CMakeLists.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. #
  2. # Wrapping
  3. #
  4. cmake_minimum_required (VERSION 2.6)
  5. project (CustomCommand)
  6. add_subdirectory(GeneratedHeader)
  7. #
  8. # Lib and exe path
  9. #
  10. if(NOT DEFINED bin_dir)
  11. set(bin_dir "bin")
  12. endif()
  13. set (LIBRARY_OUTPUT_PATH
  14. ${PROJECT_BINARY_DIR}/${bin_dir} CACHE INTERNAL
  15. "Single output directory for building all libraries.")
  16. set (EXECUTABLE_OUTPUT_PATH
  17. ${PROJECT_BINARY_DIR}/${bin_dir} CACHE INTERNAL
  18. "Single output directory for building all executables.")
  19. ################################################################
  20. #
  21. # First test using a compiled generator to create a .c file
  22. #
  23. ################################################################
  24. # add the executable that will generate the file
  25. add_executable(generator generator.cxx)
  26. ################################################################
  27. #
  28. # Test using a wrapper to wrap a header file
  29. #
  30. ################################################################
  31. # add the executable that will generate the file
  32. add_executable(wrapper wrapper.cxx)
  33. add_custom_command(
  34. OUTPUT ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  35. DEPENDS wrapper
  36. MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/wrapped.h
  37. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/wrapper
  38. ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  39. ${CMAKE_CFG_INTDIR} # this argument tests passing of the configuration
  40. VERBATIM # passing of configuration should work in this mode
  41. )
  42. ################################################################
  43. #
  44. # Test creating files from a custom target
  45. #
  46. ################################################################
  47. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}//doc1.dvi # test 2 slashes
  48. DEPENDS ${PROJECT_SOURCE_DIR}/doc1.tex
  49. COMMAND ${CMAKE_COMMAND}
  50. ARGS -E copy ${PROJECT_SOURCE_DIR}/doc1.tex
  51. ${PROJECT_BINARY_DIR}/doc1.dvi
  52. )
  53. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h
  54. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.dvi to doc1temp.h."
  55. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.dvi
  56. ${PROJECT_BINARY_DIR}/doc1temp.h
  57. )
  58. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h APPEND
  59. DEPENDS ${PROJECT_BINARY_DIR}/doc1.dvi
  60. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1temp.h to doc1.h."
  61. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1temp.h
  62. ${PROJECT_BINARY_DIR}/doc1.h
  63. COMMAND ${CMAKE_COMMAND} -E echo " Removing doc1temp.h."
  64. COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_BINARY_DIR}/doc1temp.h
  65. )
  66. # Add custom command to generate foo.h.
  67. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.h
  68. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  69. COMMAND ${CMAKE_COMMAND} -E echo " Copying foo.h.in to foo.h."
  70. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  71. ${PROJECT_BINARY_DIR}/foo.h
  72. )
  73. # Add the location of foo.h to the include path.
  74. include_directories(${PROJECT_BINARY_DIR})
  75. # Test generation of a file to the build tree without full path. As
  76. # of CMake 2.6 custom command outputs specified by relative path go in
  77. # the build tree.
  78. add_custom_command(
  79. OUTPUT doc1.txt
  80. COMMAND ${CMAKE_COMMAND} -E echo "Example Document Target" > doc1.txt
  81. DEPENDS doc1.tex
  82. VERBATIM
  83. )
  84. # Add a custom target to drive generation of doc1.h.
  85. add_custom_target(TDocument ALL
  86. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.h to doc2.h."
  87. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.h
  88. ${PROJECT_BINARY_DIR}/doc2.h
  89. DEPENDS doc1.txt ${PROJECT_BINARY_DIR}//doc1.h # test 2 slashes
  90. COMMENT "Running top-level TDocument commands"
  91. SOURCES doc1.tex
  92. )
  93. # Setup a pre- and post-build pair that will fail if not run in the
  94. # proper order.
  95. add_custom_command(
  96. TARGET TDocument PRE_BUILD
  97. COMMAND ${CMAKE_COMMAND} -E echo " Writing doc1pre.txt."
  98. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/doc1.tex ${PROJECT_BINARY_DIR}/doc1pre.txt
  99. COMMENT "Running TDocument pre-build commands"
  100. )
  101. add_custom_command(
  102. TARGET TDocument POST_BUILD
  103. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1pre.txt to doc2post.txt."
  104. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1pre.txt
  105. ${PROJECT_BINARY_DIR}/doc2post.txt
  106. COMMENT "Running TDocument post-build commands"
  107. )
  108. # Setup a custom target that will fail if the POST_BUILD custom command
  109. # isn't run before it.
  110. add_custom_command(
  111. OUTPUT doc3post.txt
  112. DEPENDS ${PROJECT_BINARY_DIR}/doc2post.txt
  113. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc2pre.txt to doc3post.txt."
  114. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc2post.txt
  115. ${PROJECT_BINARY_DIR}/doc3post.txt
  116. COMMENT "Running TDocument post-build dependent custom command"
  117. )
  118. add_custom_target(doc3Post ALL DEPENDS doc3post.txt)
  119. add_dependencies(doc3Post TDocument)
  120. ################################################################
  121. #
  122. # Test using a multistep generated file
  123. #
  124. ################################################################
  125. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
  126. DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
  127. TDocument # Ensure doc1.h generates before this target
  128. COMMAND ${CMAKE_COMMAND}
  129. ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
  130. ${PROJECT_BINARY_DIR}/foo.pre
  131. )
  132. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
  133. DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
  134. COMMAND ${CMAKE_COMMAND}
  135. ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
  136. ${PROJECT_BINARY_DIR}/foo.c
  137. )
  138. # Add custom command to generate not_included.h, which is a header
  139. # file that is not included by any source in this project. This will
  140. # test whether all custom command outputs explicitly listed as sources
  141. # get generated even if they are not needed by an object file.
  142. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
  143. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  144. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  145. ${PROJECT_BINARY_DIR}/not_included.h
  146. )
  147. # Tell the executable where to find not_included.h.
  148. configure_file(
  149. ${PROJECT_SOURCE_DIR}/config.h.in
  150. ${PROJECT_BINARY_DIR}/config.h
  151. @ONLY
  152. )
  153. # add the executable
  154. add_executable(CustomCommand
  155. ${PROJECT_BINARY_DIR}/foo.h
  156. ${PROJECT_BINARY_DIR}/foo.c
  157. ${PROJECT_BINARY_DIR}/wrapped.c
  158. ${PROJECT_BINARY_DIR}/wrapped_help.c
  159. ${PROJECT_BINARY_DIR}/generated.c
  160. ${PROJECT_BINARY_DIR}/not_included.h
  161. gen_redirect.c # default location for custom commands is in build tree
  162. )
  163. # Add the rule to create generated.c at build time. This is placed
  164. # here to test adding the generation rule after referencing the
  165. # generated source in a target.
  166. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
  167. DEPENDS generator
  168. COMMAND generator
  169. ARGS ${PROJECT_BINARY_DIR}/generated.c
  170. )
  171. target_link_libraries(CustomCommand GeneratedHeader)
  172. ##############################################################################
  173. # Test for using just the target name as executable in the COMMAND
  174. # section. Has to be recognized and replaced by CMake with the output
  175. # actual location of the executable.
  176. # Additionally the generator is created in an extra subdir after the
  177. # add_custom_command() is used.
  178. #
  179. # Test the same for add_custom_target()
  180. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  181. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  182. )
  183. add_executable(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
  184. add_custom_target(RunTarget
  185. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
  186. )
  187. add_custom_command(TARGET CustomCommandUsingTargetTest POST_BUILD
  188. COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
  189. add_subdirectory(GeneratorInExtraDir)
  190. ##############################################################################
  191. # Test shell operators in custom commands.
  192. add_executable(tcat tcat.cxx)
  193. add_custom_command(OUTPUT gen_redirect.c
  194. DEPENDS tcat gen_redirect_in.c
  195. COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
  196. COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
  197. VERBATIM
  198. )
  199. ##############################################################################
  200. # Test non-trivial command line arguments in custom commands.
  201. set(EXPECTED_ARGUMENTS)
  202. set(CHECK_ARGS)
  203. if(NOT MSVC71)
  204. set(CHECK_ARGS -DPATH=c:/posix/path)
  205. endif()
  206. set(CHECK_ARGS
  207. ${CHECK_ARGS}
  208. c:/posix/path
  209. c:\\windows\\path
  210. 'single-quotes'
  211. single'quote
  212. \"double-quotes\"
  213. "\\;semi-colons\\;"
  214. "semi\\;colon"
  215. `back-ticks`
  216. back`tick
  217. "(parens)"
  218. "(lparen"
  219. "rparen)"
  220. {curly}
  221. {lcurly}
  222. rcurly}
  223. <angle>
  224. <langle
  225. rangle>
  226. [square]
  227. [lsquare # these have funny behavior due to special cases for
  228. rsquare] # windows registry value names in list expansion
  229. $dollar-signs$
  230. dollar$sign
  231. &ampersands&x # Borland make does not like trailing ampersand
  232. one&ampersand
  233. @two-ats@
  234. one@at
  235. ~two-tilda~
  236. one~tilda
  237. ^two-carrots^
  238. one^carrot
  239. %two-percents%
  240. one%percent
  241. !two-exclamations!
  242. one!exclamation
  243. ?two-questions?
  244. one?question
  245. *two-stars*
  246. one*star
  247. =two+equals=
  248. one=equals
  249. _two-underscores_
  250. one_underscore
  251. ,two-commas,
  252. one,comma
  253. .two-periods.
  254. one.period
  255. |two-pipes|
  256. one|pipe
  257. |nopipe
  258. "#two-pounds#"
  259. "one#pound"
  260. "#nocomment"
  261. "c:/posix/path/with space"
  262. "c:\\windows\\path\\with space"
  263. "'single quotes with space'"
  264. "single'quote with space"
  265. "\"double-quotes with space\""
  266. "\\;semi-colons w s\\;"
  267. "semi\\;colon w s"
  268. "`back-ticks` w s"
  269. "back`tick w s"
  270. "(parens) w s"
  271. "(lparen w s"
  272. "rparen) w s"
  273. "{curly} w s"
  274. "{lcurly w s"
  275. "rcurly} w s"
  276. "<angle> w s"
  277. "<langle w s"
  278. "rangle> w s"
  279. "[square] w s"
  280. "[lsquare w s" # these have funny behavior due to special cases for
  281. "rsquare] w s" # windows registry value names in list expansion
  282. "$dollar-signs$ w s"
  283. "dollar$sign w s"
  284. "&ampersands& w s"
  285. "one&ampersand w s"
  286. "@two-ats@ w s"
  287. "one@at w s"
  288. "~two-tilda~ w s"
  289. "one~tilda w s"
  290. "^two-carrots^ w s"
  291. "one^carrot w s"
  292. "%two-percents% w s"
  293. "one%percent w s"
  294. "!two-exclamations! w s"
  295. "one!exclamation w s"
  296. "*two-stars* w s"
  297. "one*star w s"
  298. "=two+equals= w s"
  299. "one=equals w s"
  300. "_two-underscores_ w s"
  301. "one_underscore w s"
  302. "?two-questions? w s"
  303. "one?question w s"
  304. ",two-commas, w s"
  305. "one,comma w s"
  306. ".two-periods. w s"
  307. "one.period w s"
  308. "|two-pipes| w s"
  309. "one|pipe w s"
  310. "#two-pounds# w s"
  311. "one#pound w s"
  312. ~ ` ! @ \# $ % ^ & _ - + = : "\;" \" ' , . ? "(" ")" { } []
  313. )
  314. if(NOT MINGW)
  315. # * # MinGW programs on windows always expands the wildcard!
  316. # / # MSys make converts a leading slash to the mingw home directory
  317. list(APPEND CHECK_ARGS * /)
  318. endif()
  319. # The windows command shell does not support a double quote by itself:
  320. # double\"quote
  321. # without messing up quoting of arguments following it.
  322. # Make tools need help with escaping a single backslash
  323. # \
  324. # at the end of a command because they think it is a continuation
  325. # character.
  326. # We now have special cases for shell operators:
  327. # | < > << >> &> 2>&1 1>&2
  328. # to allow custom commands to perform redirection.
  329. foreach(arg ${CHECK_ARGS} "")
  330. set(ARG "${arg}")
  331. string(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
  332. string(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
  333. set(EXPECTED_ARGUMENTS
  334. "${EXPECTED_ARGUMENTS} \"${ARG}\",
  335. ")
  336. endforeach()
  337. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
  338. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
  339. @ONLY)
  340. add_executable(check_command_line
  341. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
  342. set(output_name "check_command_line")
  343. set_property(TARGET check_command_line
  344. PROPERTY OUTPUT_NAME ${output_name})
  345. # set_target_properties(check_command_line PROPERTIES
  346. # COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
  347. add_custom_command(
  348. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  349. COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  350. -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
  351. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  352. ${CHECK_ARGS} ""
  353. VERBATIM
  354. COMMENT "Checking custom command line escapes (single'quote)"
  355. )
  356. set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  357. PROPERTIES SYMBOLIC 1)
  358. add_custom_target(do_check_command_line ALL
  359. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  360. COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
  361. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  362. ${CHECK_ARGS} ""
  363. VERBATIM
  364. COMMENT "Checking custom target command line escapes ($dollar-signs$)"
  365. )
  366. add_dependencies(do_check_command_line check_command_line)
  367. add_custom_target(pre_check_command_line
  368. COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  369. )
  370. add_dependencies(do_check_command_line pre_check_command_line)
  371. # <SameNameTest>
  372. #
  373. # Add a custom target called "SameName" -- then add a custom command in a
  374. # different target whose output is a full-path file called "SameName" -- then
  375. # add a second custom target that depends on the full-path file ".../SameName"
  376. #
  377. # At first, this reproduces a bug reported by a customer. After fixing it,
  378. # having this test here makes sure it stays fixed moving forward.
  379. #
  380. add_custom_command(
  381. OUTPUT SameName1.txt
  382. COMMAND ${CMAKE_COMMAND} -E touch SameName1.txt
  383. )
  384. add_custom_target(SameName ALL
  385. DEPENDS SameName1.txt
  386. )
  387. add_custom_command(
  388. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  389. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subdir
  390. COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  391. )
  392. add_custom_target(DifferentName ALL
  393. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  394. )
  395. #
  396. # </SameNameTest>
  397. # Per-config target name and generator expressions.
  398. add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
  399. add_custom_command(
  400. OUTPUT perconfig.out
  401. COMMAND ${PerConfig_COMMAND}
  402. DEPENDS ${PerConfig_DEPENDS}
  403. VERBATIM
  404. )
  405. set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1)
  406. add_custom_target(perconfig_target ALL
  407. COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>"
  408. DEPENDS perconfig.out)
  409. # Test SOURCES in add_custom_target() with COMPILE_DEFINITIONS
  410. # which previously caused a crash in the makefile generators.
  411. add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp)
  412. set_property(SOURCE source_in_custom_target
  413. PROPERTY COMPILE_DEFINITIONS "TEST"
  414. )