CMakeLists.txt 11 KB

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