CMakeLists.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #
  2. # Wrapping
  3. #
  4. PROJECT (CustomCommand)
  5. ADD_SUBDIRECTORY(GeneratedHeader)
  6. #
  7. # Lib and exe path
  8. #
  9. SET (LIBRARY_OUTPUT_PATH
  10. ${PROJECT_BINARY_DIR}/bin/ CACHE INTERNAL
  11. "Single output directory for building all libraries.")
  12. SET (EXECUTABLE_OUTPUT_PATH
  13. ${PROJECT_BINARY_DIR}/bin/ CACHE INTERNAL
  14. "Single output directory for building all executables.")
  15. ################################################################
  16. #
  17. # First test using a compiled generator to create a .c file
  18. #
  19. ################################################################
  20. # add the executable that will generate the file
  21. ADD_EXECUTABLE(generator generator.cxx)
  22. GET_TARGET_PROPERTY(generator_PATH generator LOCATION)
  23. MESSAGE("Location ${generator_PATH}")
  24. ################################################################
  25. #
  26. # Test using a wrapper to wrap a header file
  27. #
  28. ################################################################
  29. # add the executable that will generate the file
  30. ADD_EXECUTABLE(wrapper wrapper.cxx)
  31. ADD_CUSTOM_COMMAND(
  32. OUTPUT ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  33. DEPENDS wrapper
  34. MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/wrapped.h
  35. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/wrapper
  36. ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  37. )
  38. ################################################################
  39. #
  40. # Test creating files from a custom target
  41. #
  42. ################################################################
  43. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/doc1.dvi
  44. DEPENDS ${PROJECT_SOURCE_DIR}/doc1.tex
  45. COMMAND ${CMAKE_COMMAND}
  46. ARGS -E copy ${PROJECT_SOURCE_DIR}/doc1.tex
  47. ${PROJECT_BINARY_DIR}/doc1.dvi
  48. )
  49. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h
  50. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.dvi to doc1temp.h."
  51. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.dvi
  52. ${PROJECT_BINARY_DIR}/doc1temp.h
  53. )
  54. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h APPEND
  55. DEPENDS ${PROJECT_BINARY_DIR}/doc1.dvi
  56. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1temp.h to doc1.h."
  57. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1temp.h
  58. ${PROJECT_BINARY_DIR}/doc1.h
  59. COMMAND ${CMAKE_COMMAND} -E echo " Removing doc1temp.h."
  60. COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_BINARY_DIR}/doc1temp.h
  61. )
  62. # Add custom command to generate foo.h.
  63. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.h
  64. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  65. COMMAND ${CMAKE_COMMAND} -E echo " Copying foo.h.in to foo.h."
  66. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  67. ${PROJECT_BINARY_DIR}/foo.h
  68. )
  69. # Add the location of foo.h to the include path.
  70. INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
  71. # Add a custom target to drive generation of doc1.h.
  72. ADD_CUSTOM_TARGET(TDocument ALL
  73. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.h to doc2.h."
  74. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.h
  75. ${PROJECT_BINARY_DIR}/doc2.h
  76. DEPENDS ${PROJECT_BINARY_DIR}/doc1.h
  77. COMMENT "Running top-level TDocument commands"
  78. )
  79. # Setup a pre- and post-build pair that will fail if not run in the
  80. # proper order.
  81. ADD_CUSTOM_COMMAND(
  82. TARGET TDocument PRE_BUILD
  83. COMMAND ${CMAKE_COMMAND} -E echo " Writing doc1pre.txt."
  84. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/doc1.tex ${PROJECT_BINARY_DIR}/doc1pre.txt
  85. )
  86. ADD_CUSTOM_COMMAND(
  87. TARGET TDocument POST_BUILD
  88. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1pre.txt to doc2post.txt."
  89. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1pre.txt
  90. ${PROJECT_BINARY_DIR}/doc2post.txt
  91. )
  92. ################################################################
  93. #
  94. # Test using a multistep generated file
  95. #
  96. ################################################################
  97. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
  98. DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
  99. COMMAND ${CMAKE_COMMAND}
  100. ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
  101. ${PROJECT_BINARY_DIR}/foo.pre
  102. )
  103. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
  104. DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
  105. COMMAND ${CMAKE_COMMAND}
  106. ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
  107. ${PROJECT_BINARY_DIR}/foo.c
  108. )
  109. # Add custom command to generate not_included.h, which is a header
  110. # file that is not included by any source in this project. This will
  111. # test whether all custom command outputs explicitly listed as sources
  112. # get generated even if they are not needed by an object file.
  113. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
  114. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  115. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  116. ${PROJECT_BINARY_DIR}/not_included.h
  117. )
  118. # Tell the executable where to find not_included.h.
  119. CONFIGURE_FILE(
  120. ${PROJECT_SOURCE_DIR}/config.h.in
  121. ${PROJECT_BINARY_DIR}/config.h
  122. @ONLY IMMEDIATE
  123. )
  124. # add the executable
  125. ADD_EXECUTABLE(CustomCommand
  126. ${PROJECT_BINARY_DIR}/foo.h
  127. ${PROJECT_BINARY_DIR}/foo.c
  128. ${PROJECT_BINARY_DIR}/wrapped.c
  129. ${PROJECT_BINARY_DIR}/wrapped_help.c
  130. ${PROJECT_BINARY_DIR}/generated.c
  131. ${PROJECT_BINARY_DIR}/not_included.h
  132. )
  133. # Add the rule to create generated.c at build time. This is placed
  134. # here to test adding the generation rule after referencing the
  135. # generated source in a target.
  136. ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
  137. DEPENDS generator
  138. COMMAND ${generator_PATH}
  139. ARGS ${PROJECT_BINARY_DIR}/generated.c
  140. )
  141. TARGET_LINK_LIBRARIES(CustomCommand GeneratedHeader)
  142. # must add a dependency on TDocument otherwise it might never build and
  143. # the CustomCommand executable really needs doc1.h
  144. ADD_DEPENDENCIES(CustomCommand TDocument)
  145. ##############################################################################
  146. # Test for using just the target name as executable in the COMMAND
  147. # section. Has to be recognized and replaced by CMake with the output
  148. # actual location of the executable.
  149. # Additionally the generator is created in an extra subdir after the
  150. # ADD_CUSTOM_COMMAND() is used.
  151. #
  152. # Test the same for ADD_CUSTOM_TARGET()
  153. ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  154. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  155. )
  156. ADD_EXECUTABLE(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
  157. ADD_CUSTOM_TARGET(RunTarget
  158. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
  159. )
  160. ADD_CUSTOM_COMMAND(TARGET CustomCommandUsingTargetTest POST_BUILD
  161. COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
  162. ADD_SUBDIRECTORY(GeneratorInExtraDir)
  163. ##############################################################################
  164. # Test non-trivial command line arguments in custom commands.
  165. SET(EXPECTED_ARGUMENTS)
  166. # TODO: Check shell operators < > << >> | 2>&1 1>&2 &> ! &
  167. SET(CHECK_ARGS
  168. c:/posix/path
  169. c:\\windows\\path
  170. 'single-quotes'
  171. single'quote
  172. \"double-quotes\"
  173. double\"quote
  174. "\\;semi-colons\\;"
  175. "semi\\;colon"
  176. `back-ticks`
  177. back`tick
  178. "(parens)"
  179. "(lparen"
  180. "rparen)"
  181. {curly}
  182. {lcurly}
  183. rcurly}
  184. #<angle> # angle-brackets are inconsistent on windows right now
  185. #<langle
  186. #rangle>
  187. [square]
  188. [lsquare # these have funny behavior due to special cases for
  189. rsquare] # windows registry value names in list expansion
  190. $dollar-signs$
  191. dollar$sign
  192. &ampersands&
  193. one&ampersand
  194. @two-ats@
  195. one@at
  196. ~two-tilda~
  197. one~tilda
  198. ^two-carrots^
  199. one^carrot
  200. %two-percents%
  201. one%percent
  202. !two-exclamations!
  203. one!exclamation
  204. ?two-questions?
  205. one?question
  206. *two-stars*
  207. one*star
  208. =two+equals=
  209. one=equals
  210. _two-underscores_
  211. one_underscore
  212. ,two-commas,
  213. one,comma
  214. .two-periods.
  215. one.period
  216. |two-pipes|
  217. one|pipe
  218. |nopipe
  219. "#two-pounds#"
  220. "one#pound"
  221. "#nocomment"
  222. "c:/posix/path/with space"
  223. "c:\\windows\\path\\with space"
  224. "'single quotes with space'"
  225. "single'quote with space"
  226. "\"double-quotes with space\""
  227. "double\"quote with space"
  228. "\\;semi-colons w s\\;"
  229. "semi\\;colon w s"
  230. "`back-ticks` w s"
  231. "back`tick w s"
  232. "(parens) w s"
  233. "(lparen w s"
  234. "rparen) w s"
  235. "{curly} w s"
  236. "{lcurly w s"
  237. "rcurly} w s"
  238. #"<angle> w s" # angle-brackets are inconsistent on windows right now
  239. #"<langle w s"
  240. #"rangle> w s"
  241. "[square] w s"
  242. "[lsquare w s" # these have funny behavior due to special cases for
  243. "rsquare] w s" # windows registry value names in list expansion
  244. "$dollar-signs$ w s"
  245. "dollar$sign w s"
  246. "&ampersands& w s"
  247. "one&ampersand w s"
  248. "@two-ats@ w s"
  249. "one@at w s"
  250. "~two-tilda~ w s"
  251. "one~tilda w s"
  252. "^two-carrots^ w s"
  253. "one^carrot w s"
  254. "%two-percents% w s"
  255. "one%percent w s"
  256. "!two-exclamations! w s"
  257. "one!exclamation w s"
  258. "*two-stars* w s"
  259. "one*star w s"
  260. "=two+equals= w s"
  261. "one=equals w s"
  262. "_two-underscores_ w s"
  263. "one_underscore w s"
  264. "?two-questions? w s"
  265. "one?question w s"
  266. ",two-commas, w s"
  267. "one,comma w s"
  268. ".two-periods. w s"
  269. "one.period w s"
  270. "|two-pipes| w s"
  271. "one|pipe w s"
  272. "#two-pounds# w s"
  273. "one#pound w s"
  274. ~ ` ! @ \# $ % ^ & _ - + = | : "\;" \" ' , . ? "(" ")" { } []
  275. # < > << >> &> 2>&1 1>&2
  276. # \\ # Need to test last to avoid ; escape in list.
  277. # # Make tools need help when this is the last argument.
  278. )
  279. IF(NOT MINGW)
  280. # * # MinGW programs on windows always expands the wildcard!
  281. # / # MSys make converts a leading slash to the mingw home directory
  282. LIST(APPEND CHECK_ARGS * /)
  283. ENDIF(NOT MINGW)
  284. FOREACH(arg ${CHECK_ARGS})
  285. SET(ARG "${arg}")
  286. STRING(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
  287. STRING(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
  288. SET(EXPECTED_ARGUMENTS
  289. "${EXPECTED_ARGUMENTS} \"${ARG}\",
  290. ")
  291. ENDFOREACH(arg)
  292. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
  293. CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
  294. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
  295. @ONLY IMMEDIATE)
  296. ADD_EXECUTABLE(check_command_line
  297. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
  298. # SET_TARGET_PROPERTIES(check_command_line PROPERTIES
  299. # COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
  300. ADD_CUSTOM_COMMAND(
  301. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  302. COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  303. -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
  304. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/check_command_line
  305. ${CHECK_ARGS}
  306. VERBATIM
  307. COMMENT "Checking custom command line escapes (single'quote)"
  308. )
  309. SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  310. PROPERTIES SYMBOLIC 1)
  311. ADD_CUSTOM_TARGET(do_check_command_line ALL
  312. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  313. COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
  314. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/check_command_line
  315. ${CHECK_ARGS}
  316. VERBATIM
  317. COMMENT "Checking custom target command line escapes ($dollar-signs$)"
  318. )
  319. ADD_DEPENDENCIES(do_check_command_line check_command_line)
  320. ADD_CUSTOM_TARGET(pre_check_command_line
  321. COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  322. )
  323. ADD_DEPENDENCIES(do_check_command_line pre_check_command_line)