CMakeLists.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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. ################################################################
  111. #
  112. # Test using a multistep generated file
  113. #
  114. ################################################################
  115. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
  116. DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
  117. TDocument # Ensure doc1.h generates before this target
  118. COMMAND ${CMAKE_COMMAND}
  119. ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
  120. ${PROJECT_BINARY_DIR}/foo.pre
  121. )
  122. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
  123. DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
  124. COMMAND ${CMAKE_COMMAND}
  125. ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
  126. ${PROJECT_BINARY_DIR}/foo.c
  127. )
  128. # Add custom command to generate not_included.h, which is a header
  129. # file that is not included by any source in this project. This will
  130. # test whether all custom command outputs explicitly listed as sources
  131. # get generated even if they are not needed by an object file.
  132. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
  133. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  134. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  135. ${PROJECT_BINARY_DIR}/not_included.h
  136. )
  137. # Tell the executable where to find not_included.h.
  138. configure_file(
  139. ${PROJECT_SOURCE_DIR}/config.h.in
  140. ${PROJECT_BINARY_DIR}/config.h
  141. @ONLY IMMEDIATE
  142. )
  143. # add the executable
  144. add_executable(CustomCommand
  145. ${PROJECT_BINARY_DIR}/foo.h
  146. ${PROJECT_BINARY_DIR}/foo.c
  147. ${PROJECT_BINARY_DIR}/wrapped.c
  148. ${PROJECT_BINARY_DIR}/wrapped_help.c
  149. ${PROJECT_BINARY_DIR}/generated.c
  150. ${PROJECT_BINARY_DIR}/not_included.h
  151. gen_redirect.c # default location for custom commands is in build tree
  152. )
  153. # Add the rule to create generated.c at build time. This is placed
  154. # here to test adding the generation rule after referencing the
  155. # generated source in a target.
  156. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
  157. DEPENDS generator
  158. COMMAND ${generator_PATH}
  159. ARGS ${PROJECT_BINARY_DIR}/generated.c
  160. )
  161. target_link_libraries(CustomCommand GeneratedHeader)
  162. ##############################################################################
  163. # Test for using just the target name as executable in the COMMAND
  164. # section. Has to be recognized and replaced by CMake with the output
  165. # actual location of the executable.
  166. # Additionally the generator is created in an extra subdir after the
  167. # add_custom_command() is used.
  168. #
  169. # Test the same for add_custom_target()
  170. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  171. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  172. )
  173. add_executable(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
  174. add_custom_target(RunTarget
  175. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
  176. )
  177. add_custom_command(TARGET CustomCommandUsingTargetTest POST_BUILD
  178. COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
  179. add_subdirectory(GeneratorInExtraDir)
  180. ##############################################################################
  181. # Test shell operators in custom commands.
  182. add_executable(tcat tcat.cxx)
  183. add_custom_command(OUTPUT gen_redirect.c
  184. DEPENDS tcat gen_redirect_in.c
  185. COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
  186. COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
  187. VERBATIM
  188. )
  189. ##############################################################################
  190. # Test non-trivial command line arguments in custom commands.
  191. set(EXPECTED_ARGUMENTS)
  192. set(CHECK_ARGS)
  193. if(NOT MSVC71)
  194. set(CHECK_ARGS -DPATH=c:/posix/path)
  195. endif()
  196. set(CHECK_ARGS
  197. ${CHECK_ARGS}
  198. c:/posix/path
  199. c:\\windows\\path
  200. 'single-quotes'
  201. single'quote
  202. \"double-quotes\"
  203. "\\;semi-colons\\;"
  204. "semi\\;colon"
  205. `back-ticks`
  206. back`tick
  207. "(parens)"
  208. "(lparen"
  209. "rparen)"
  210. {curly}
  211. {lcurly}
  212. rcurly}
  213. <angle>
  214. <langle
  215. rangle>
  216. [square]
  217. [lsquare # these have funny behavior due to special cases for
  218. rsquare] # windows registry value names in list expansion
  219. $dollar-signs$
  220. dollar$sign
  221. &ampersands&x # Borland make does not like trailing ampersand
  222. one&ampersand
  223. @two-ats@
  224. one@at
  225. ~two-tilda~
  226. one~tilda
  227. ^two-carrots^
  228. one^carrot
  229. %two-percents%
  230. one%percent
  231. !two-exclamations!
  232. one!exclamation
  233. ?two-questions?
  234. one?question
  235. *two-stars*
  236. one*star
  237. =two+equals=
  238. one=equals
  239. _two-underscores_
  240. one_underscore
  241. ,two-commas,
  242. one,comma
  243. .two-periods.
  244. one.period
  245. |two-pipes|
  246. one|pipe
  247. |nopipe
  248. "#two-pounds#"
  249. "one#pound"
  250. "#nocomment"
  251. "c:/posix/path/with space"
  252. "c:\\windows\\path\\with space"
  253. "'single quotes with space'"
  254. "single'quote with space"
  255. "\"double-quotes with space\""
  256. "\\;semi-colons w s\\;"
  257. "semi\\;colon w s"
  258. "`back-ticks` w s"
  259. "back`tick w s"
  260. "(parens) w s"
  261. "(lparen w s"
  262. "rparen) w s"
  263. "{curly} w s"
  264. "{lcurly w s"
  265. "rcurly} w s"
  266. "<angle> w s"
  267. "<langle w s"
  268. "rangle> w s"
  269. "[square] w s"
  270. "[lsquare w s" # these have funny behavior due to special cases for
  271. "rsquare] w s" # windows registry value names in list expansion
  272. "$dollar-signs$ w s"
  273. "dollar$sign w s"
  274. "&ampersands& w s"
  275. "one&ampersand w s"
  276. "@two-ats@ w s"
  277. "one@at w s"
  278. "~two-tilda~ w s"
  279. "one~tilda w s"
  280. "^two-carrots^ w s"
  281. "one^carrot w s"
  282. "%two-percents% w s"
  283. "one%percent w s"
  284. "!two-exclamations! w s"
  285. "one!exclamation w s"
  286. "*two-stars* w s"
  287. "one*star w s"
  288. "=two+equals= w s"
  289. "one=equals w s"
  290. "_two-underscores_ w s"
  291. "one_underscore w s"
  292. "?two-questions? w s"
  293. "one?question w s"
  294. ",two-commas, w s"
  295. "one,comma w s"
  296. ".two-periods. w s"
  297. "one.period w s"
  298. "|two-pipes| w s"
  299. "one|pipe w s"
  300. "#two-pounds# w s"
  301. "one#pound w s"
  302. ~ ` ! @ \# $ % ^ & _ - + = : "\;" \" ' , . ? "(" ")" { } []
  303. )
  304. if(NOT MINGW)
  305. # * # MinGW programs on windows always expands the wildcard!
  306. # / # MSys make converts a leading slash to the mingw home directory
  307. list(APPEND CHECK_ARGS * /)
  308. endif()
  309. # The windows command shell does not support a double quote by itself:
  310. # double\"quote
  311. # without messing up quoting of arguments following it.
  312. # Make tools need help with escaping a single backslash
  313. # \
  314. # at the end of a command because they think it is a continuation
  315. # character.
  316. # We now have special cases for shell operators:
  317. # | < > << >> &> 2>&1 1>&2
  318. # to allow custom commands to perform redirection.
  319. foreach(arg ${CHECK_ARGS} "")
  320. set(ARG "${arg}")
  321. string(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
  322. string(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
  323. set(EXPECTED_ARGUMENTS
  324. "${EXPECTED_ARGUMENTS} \"${ARG}\",
  325. ")
  326. endforeach()
  327. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
  328. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
  329. @ONLY IMMEDIATE)
  330. add_executable(check_command_line
  331. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
  332. set(output_name "check_command_line")
  333. set_property(TARGET check_command_line
  334. PROPERTY OUTPUT_NAME ${output_name})
  335. # set_target_properties(check_command_line PROPERTIES
  336. # COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
  337. add_custom_command(
  338. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  339. COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  340. -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
  341. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  342. ${CHECK_ARGS} ""
  343. VERBATIM
  344. COMMENT "Checking custom command line escapes (single'quote)"
  345. )
  346. set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  347. PROPERTIES SYMBOLIC 1)
  348. add_custom_target(do_check_command_line ALL
  349. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  350. COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
  351. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  352. ${CHECK_ARGS} ""
  353. VERBATIM
  354. COMMENT "Checking custom target command line escapes ($dollar-signs$)"
  355. )
  356. add_dependencies(do_check_command_line check_command_line)
  357. add_custom_target(pre_check_command_line
  358. COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  359. )
  360. add_dependencies(do_check_command_line pre_check_command_line)
  361. # <SameNameTest>
  362. #
  363. # Add a custom target called "SameName" -- then add a custom command in a
  364. # different target whose output is a full-path file called "SameName" -- then
  365. # add a second custom target that depends on the full-path file ".../SameName"
  366. #
  367. # At first, this reproduces a bug reported by a customer. After fixing it,
  368. # having this test here makes sure it stays fixed moving forward.
  369. #
  370. add_custom_command(
  371. OUTPUT SameName1.txt
  372. COMMAND ${CMAKE_COMMAND} -E touch SameName1.txt
  373. )
  374. add_custom_target(SameName ALL
  375. DEPENDS SameName1.txt
  376. )
  377. add_custom_command(
  378. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  379. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subdir
  380. COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  381. )
  382. add_custom_target(DifferentName ALL
  383. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  384. )
  385. #
  386. # </SameNameTest>
  387. # Per-config target name and generator expressions.
  388. add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
  389. add_custom_command(
  390. OUTPUT perconfig.out
  391. COMMAND ${PerConfig_COMMAND}
  392. DEPENDS ${PerConfig_DEPENDS}
  393. VERBATIM
  394. )
  395. set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1)
  396. add_custom_target(perconfig_target ALL
  397. COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>"
  398. DEPENDS perconfig.out)