CMakeLists.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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. get_target_property(generator_PATH generator LOCATION)
  27. message("Location ${generator_PATH}")
  28. ################################################################
  29. #
  30. # Test using a wrapper to wrap a header file
  31. #
  32. ################################################################
  33. # add the executable that will generate the file
  34. add_executable(wrapper wrapper.cxx)
  35. add_custom_command(
  36. OUTPUT ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  37. DEPENDS wrapper
  38. MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/wrapped.h
  39. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/wrapper
  40. ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
  41. ${CMAKE_CFG_INTDIR} # this argument tests passing of the configuration
  42. VERBATIM # passing of configuration should work in this mode
  43. )
  44. ################################################################
  45. #
  46. # Test creating files from a custom target
  47. #
  48. ################################################################
  49. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}//doc1.dvi # test 2 slashes
  50. DEPENDS ${PROJECT_SOURCE_DIR}/doc1.tex
  51. COMMAND ${CMAKE_COMMAND}
  52. ARGS -E copy ${PROJECT_SOURCE_DIR}/doc1.tex
  53. ${PROJECT_BINARY_DIR}/doc1.dvi
  54. )
  55. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h
  56. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.dvi to doc1temp.h."
  57. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.dvi
  58. ${PROJECT_BINARY_DIR}/doc1temp.h
  59. )
  60. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h APPEND
  61. DEPENDS ${PROJECT_BINARY_DIR}/doc1.dvi
  62. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1temp.h to doc1.h."
  63. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1temp.h
  64. ${PROJECT_BINARY_DIR}/doc1.h
  65. COMMAND ${CMAKE_COMMAND} -E echo " Removing doc1temp.h."
  66. COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_BINARY_DIR}/doc1temp.h
  67. )
  68. # Add custom command to generate foo.h.
  69. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.h
  70. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  71. COMMAND ${CMAKE_COMMAND} -E echo " Copying foo.h.in to foo.h."
  72. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  73. ${PROJECT_BINARY_DIR}/foo.h
  74. )
  75. # Add the location of foo.h to the include path.
  76. include_directories(${PROJECT_BINARY_DIR})
  77. # Test generation of a file to the build tree without full path. As
  78. # of CMake 2.6 custom command outputs specified by relative path go in
  79. # the build tree.
  80. add_custom_command(
  81. OUTPUT doc1.txt
  82. COMMAND ${CMAKE_COMMAND} -E echo "Example Document Target" > doc1.txt
  83. DEPENDS doc1.tex
  84. VERBATIM
  85. )
  86. # Add a custom target to drive generation of doc1.h.
  87. add_custom_target(TDocument ALL
  88. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.h to doc2.h."
  89. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.h
  90. ${PROJECT_BINARY_DIR}/doc2.h
  91. DEPENDS doc1.txt ${PROJECT_BINARY_DIR}//doc1.h # test 2 slashes
  92. COMMENT "Running top-level TDocument commands"
  93. SOURCES doc1.tex
  94. )
  95. # Setup a pre- and post-build pair that will fail if not run in the
  96. # proper order.
  97. add_custom_command(
  98. TARGET TDocument PRE_BUILD
  99. COMMAND ${CMAKE_COMMAND} -E echo " Writing doc1pre.txt."
  100. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/doc1.tex ${PROJECT_BINARY_DIR}/doc1pre.txt
  101. COMMENT "Running TDocument pre-build commands"
  102. )
  103. add_custom_command(
  104. TARGET TDocument POST_BUILD
  105. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1pre.txt to doc2post.txt."
  106. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1pre.txt
  107. ${PROJECT_BINARY_DIR}/doc2post.txt
  108. COMMENT "Running TDocument post-build commands"
  109. )
  110. # Setup a custom target that will fail if the POST_BUILD custom command
  111. # isn't run before it.
  112. add_custom_command(
  113. OUTPUT doc3post.txt
  114. DEPENDS ${PROJECT_BINARY_DIR}/doc2post.txt
  115. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc2pre.txt to doc3post.txt."
  116. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc2post.txt
  117. ${PROJECT_BINARY_DIR}/doc3post.txt
  118. COMMENT "Running TDocument post-build dependent custom command"
  119. )
  120. add_custom_target(doc3Post ALL DEPENDS doc3post.txt)
  121. add_dependencies(doc3Post TDocument)
  122. ################################################################
  123. #
  124. # Test using a multistep generated file
  125. #
  126. ################################################################
  127. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
  128. DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
  129. TDocument # Ensure doc1.h generates before this target
  130. COMMAND ${CMAKE_COMMAND}
  131. ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
  132. ${PROJECT_BINARY_DIR}/foo.pre
  133. )
  134. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
  135. DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
  136. COMMAND ${CMAKE_COMMAND}
  137. ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
  138. ${PROJECT_BINARY_DIR}/foo.c
  139. )
  140. # Add custom command to generate not_included.h, which is a header
  141. # file that is not included by any source in this project. This will
  142. # test whether all custom command outputs explicitly listed as sources
  143. # get generated even if they are not needed by an object file.
  144. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
  145. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  146. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  147. ${PROJECT_BINARY_DIR}/not_included.h
  148. )
  149. # Tell the executable where to find not_included.h.
  150. configure_file(
  151. ${PROJECT_SOURCE_DIR}/config.h.in
  152. ${PROJECT_BINARY_DIR}/config.h
  153. @ONLY IMMEDIATE
  154. )
  155. # add the executable
  156. add_executable(CustomCommand
  157. ${PROJECT_BINARY_DIR}/foo.h
  158. ${PROJECT_BINARY_DIR}/foo.c
  159. ${PROJECT_BINARY_DIR}/wrapped.c
  160. ${PROJECT_BINARY_DIR}/wrapped_help.c
  161. ${PROJECT_BINARY_DIR}/generated.c
  162. ${PROJECT_BINARY_DIR}/not_included.h
  163. gen_redirect.c # default location for custom commands is in build tree
  164. )
  165. # Add the rule to create generated.c at build time. This is placed
  166. # here to test adding the generation rule after referencing the
  167. # generated source in a target.
  168. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
  169. DEPENDS generator
  170. COMMAND ${generator_PATH}
  171. ARGS ${PROJECT_BINARY_DIR}/generated.c
  172. )
  173. target_link_libraries(CustomCommand GeneratedHeader)
  174. ##############################################################################
  175. # Test for using just the target name as executable in the COMMAND
  176. # section. Has to be recognized and replaced by CMake with the output
  177. # actual location of the executable.
  178. # Additionally the generator is created in an extra subdir after the
  179. # add_custom_command() is used.
  180. #
  181. # Test the same for add_custom_target()
  182. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  183. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  184. )
  185. add_executable(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
  186. add_custom_target(RunTarget
  187. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
  188. )
  189. add_custom_command(TARGET CustomCommandUsingTargetTest POST_BUILD
  190. COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
  191. add_subdirectory(GeneratorInExtraDir)
  192. ##############################################################################
  193. # Test shell operators in custom commands.
  194. add_executable(tcat tcat.cxx)
  195. add_custom_command(OUTPUT gen_redirect.c
  196. DEPENDS tcat gen_redirect_in.c
  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 IMMEDIATE)
  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)