CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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 $<1:generator> $<0:does_not_exist>
  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. # Test that list expansion from a generator expression works.
  194. set_property(TARGET tcat PROPERTY DEPSLIST tcat gen_redirect_in.c)
  195. add_custom_command(OUTPUT gen_redirect.c
  196. DEPENDS $<TARGET_PROPERTY:tcat,DEPSLIST>
  197. COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
  198. COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
  199. VERBATIM
  200. )
  201. ##############################################################################
  202. # Test non-trivial command line arguments in custom commands.
  203. set(EXPECTED_ARGUMENTS)
  204. set(CHECK_ARGS)
  205. if(NOT MSVC71)
  206. set(CHECK_ARGS -DPATH=c:/posix/path)
  207. endif()
  208. set(CHECK_ARGS
  209. ${CHECK_ARGS}
  210. c:/posix/path
  211. c:\\windows\\path
  212. 'single-quotes'
  213. single'quote
  214. \"double-quotes\"
  215. "\\;semi-colons\\;"
  216. "semi\\;colon"
  217. `back-ticks`
  218. back`tick
  219. "(parens)"
  220. "(lparen"
  221. "rparen)"
  222. {curly}
  223. {lcurly}
  224. rcurly}
  225. <angle>
  226. <langle
  227. rangle>
  228. [square]
  229. [lsquare # these have funny behavior due to special cases for
  230. rsquare] # windows registry value names in list expansion
  231. $dollar-signs$
  232. dollar$sign
  233. &ampersands&x # Borland make does not like trailing ampersand
  234. one&ampersand
  235. @two-ats@
  236. one@at
  237. ~two-tilda~
  238. one~tilda
  239. ^two-carrots^
  240. one^carrot
  241. %two-percents%
  242. one%percent
  243. !two-exclamations!
  244. one!exclamation
  245. ?two-questions?
  246. one?question
  247. *two-stars*
  248. one*star
  249. =two+equals=
  250. one=equals
  251. _two-underscores_
  252. one_underscore
  253. ,two-commas,
  254. one,comma
  255. .two-periods.
  256. one.period
  257. |two-pipes|
  258. one|pipe
  259. |nopipe
  260. "#two-pounds#"
  261. "one#pound"
  262. "#nocomment"
  263. "c:/posix/path/with space"
  264. "c:\\windows\\path\\with space"
  265. "'single quotes with space'"
  266. "single'quote with space"
  267. "\"double-quotes with space\""
  268. "\\;semi-colons w s\\;"
  269. "semi\\;colon w s"
  270. "`back-ticks` w s"
  271. "back`tick w s"
  272. "(parens) w s"
  273. "(lparen w s"
  274. "rparen) w s"
  275. "{curly} w s"
  276. "{lcurly w s"
  277. "rcurly} w s"
  278. "<angle> w s"
  279. "<langle w s"
  280. "rangle> w s"
  281. "[square] w s"
  282. "[lsquare w s" # these have funny behavior due to special cases for
  283. "rsquare] w s" # windows registry value names in list expansion
  284. "$dollar-signs$ w s"
  285. "dollar$sign w s"
  286. "&ampersands& w s"
  287. "one&ampersand w s"
  288. "@two-ats@ w s"
  289. "one@at w s"
  290. "~two-tilda~ w s"
  291. "one~tilda w s"
  292. "^two-carrots^ w s"
  293. "one^carrot w s"
  294. "%two-percents% w s"
  295. "one%percent w s"
  296. "!two-exclamations! w s"
  297. "one!exclamation w s"
  298. "*two-stars* w s"
  299. "one*star w s"
  300. "=two+equals= w s"
  301. "one=equals w s"
  302. "_two-underscores_ w s"
  303. "one_underscore w s"
  304. "?two-questions? w s"
  305. "one?question w s"
  306. ",two-commas, w s"
  307. "one,comma w s"
  308. ".two-periods. w s"
  309. "one.period w s"
  310. "|two-pipes| w s"
  311. "one|pipe w s"
  312. "#two-pounds# w s"
  313. "one#pound w s"
  314. ~ ` ! @ \# $ % ^ & _ - + = : "\;" \" ' , . ? "(" ")" { } []
  315. )
  316. if(NOT MINGW)
  317. # * # MinGW programs on windows always expands the wildcard!
  318. # / # MSys make converts a leading slash to the mingw home directory
  319. list(APPEND CHECK_ARGS * /)
  320. endif()
  321. # The windows command shell does not support a double quote by itself:
  322. # double\"quote
  323. # without messing up quoting of arguments following it.
  324. # Make tools need help with escaping a single backslash
  325. # \
  326. # at the end of a command because they think it is a continuation
  327. # character.
  328. # We now have special cases for shell operators:
  329. # | < > << >> &> 2>&1 1>&2
  330. # to allow custom commands to perform redirection.
  331. foreach(arg ${CHECK_ARGS} "")
  332. set(ARG "${arg}")
  333. string(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
  334. string(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
  335. set(EXPECTED_ARGUMENTS
  336. "${EXPECTED_ARGUMENTS} \"${ARG}\",
  337. ")
  338. endforeach()
  339. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
  340. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
  341. @ONLY)
  342. add_executable(check_command_line
  343. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
  344. set(output_name "check_command_line")
  345. set_property(TARGET check_command_line
  346. PROPERTY OUTPUT_NAME ${output_name})
  347. # set_target_properties(check_command_line PROPERTIES
  348. # COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
  349. add_custom_command(
  350. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  351. COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  352. -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
  353. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  354. ${CHECK_ARGS} ""
  355. VERBATIM
  356. COMMENT "Checking custom command line escapes (single'quote)"
  357. )
  358. set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  359. PROPERTIES SYMBOLIC 1)
  360. add_custom_target(do_check_command_line ALL
  361. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  362. COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
  363. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  364. ${CHECK_ARGS} ""
  365. VERBATIM
  366. COMMENT "Checking custom target command line escapes ($dollar-signs$)"
  367. )
  368. add_dependencies(do_check_command_line check_command_line)
  369. add_custom_target(pre_check_command_line
  370. COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  371. )
  372. add_dependencies(do_check_command_line pre_check_command_line)
  373. # <SameNameTest>
  374. #
  375. # Add a custom target called "SameName" -- then add a custom command in a
  376. # different target whose output is a full-path file called "SameName" -- then
  377. # add a second custom target that depends on the full-path file ".../SameName"
  378. #
  379. # At first, this reproduces a bug reported by a customer. After fixing it,
  380. # having this test here makes sure it stays fixed moving forward.
  381. #
  382. add_custom_command(
  383. OUTPUT SameName1.txt
  384. COMMAND ${CMAKE_COMMAND} -E touch SameName1.txt
  385. )
  386. add_custom_target(SameName ALL
  387. DEPENDS SameName1.txt
  388. )
  389. add_custom_command(
  390. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  391. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subdir
  392. COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  393. )
  394. add_custom_target(DifferentName ALL
  395. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  396. )
  397. #
  398. # </SameNameTest>
  399. # Per-config target name and generator expressions.
  400. add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
  401. add_custom_command(
  402. OUTPUT perconfig.out
  403. COMMAND ${PerConfig_COMMAND}
  404. DEPENDS ${PerConfig_DEPENDS}
  405. VERBATIM
  406. )
  407. set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1)
  408. add_custom_target(perconfig_target ALL
  409. COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>"
  410. DEPENDS perconfig.out)
  411. # Test SOURCES in add_custom_target() with COMPILE_DEFINITIONS
  412. # which previously caused a crash in the makefile generators.
  413. add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp)
  414. set_property(SOURCE source_in_custom_target
  415. PROPERTY COMPILE_DEFINITIONS "TEST"
  416. )