CMakeLists.txt 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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. BYPRODUCTS ${PROJECT_BINARY_DIR}/doc2post.txt
  107. COMMENT "Running TDocument post-build commands"
  108. )
  109. # Setup a custom target that will fail if the POST_BUILD custom command
  110. # isn't run before it.
  111. add_custom_command(
  112. OUTPUT doc3post.txt
  113. DEPENDS ${PROJECT_BINARY_DIR}/doc2post.txt
  114. COMMAND ${CMAKE_COMMAND} -E echo " Copying doc2pre.txt to doc3post.txt."
  115. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc2post.txt
  116. ${PROJECT_BINARY_DIR}/doc3post.txt
  117. COMMENT "Running TDocument post-build dependent custom command"
  118. )
  119. add_custom_target(doc3Post ALL DEPENDS doc3post.txt)
  120. add_dependencies(doc3Post TDocument)
  121. ################################################################
  122. #
  123. # Test using a multistep generated file
  124. #
  125. ################################################################
  126. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
  127. DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
  128. TDocument # Ensure doc1.h generates before this target
  129. COMMAND ${CMAKE_COMMAND}
  130. ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
  131. ${PROJECT_BINARY_DIR}/foo.pre
  132. )
  133. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
  134. DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
  135. COMMAND ${CMAKE_COMMAND}
  136. ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
  137. ${PROJECT_BINARY_DIR}/foo.c
  138. )
  139. # Test using OBJECT_DEPENDS to bring in a custom command.
  140. # Use a path that can be simplified to make sure paths
  141. # are consistently normalized.
  142. add_custom_command(
  143. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/../subdir/subdir.h
  144. COMMAND ${CMAKE_COMMAND} -E copy
  145. ${CMAKE_CURRENT_SOURCE_DIR}/subdir.h.in
  146. ${CMAKE_CURRENT_BINARY_DIR}/subdir/subdir.h
  147. DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/subdir.h.in
  148. )
  149. set_property(SOURCE ${PROJECT_BINARY_DIR}/foo.c PROPERTY
  150. OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/../subdir/subdir.h)
  151. # Add custom command to generate not_included.h, which is a header
  152. # file that is not included by any source in this project. This will
  153. # test whether all custom command outputs explicitly listed as sources
  154. # get generated even if they are not needed by an object file.
  155. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
  156. DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
  157. COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
  158. ${PROJECT_BINARY_DIR}/not_included.h
  159. )
  160. # add the executable
  161. add_executable(CustomCommand
  162. ${PROJECT_BINARY_DIR}/foo.h
  163. ${PROJECT_BINARY_DIR}/foo.c
  164. ${PROJECT_BINARY_DIR}/wrapped.c
  165. ${PROJECT_BINARY_DIR}/wrapped_help.c
  166. ${PROJECT_BINARY_DIR}/generated.c
  167. ${PROJECT_BINARY_DIR}/not_included.h
  168. gen_redirect.c # default location for custom commands is in build tree
  169. )
  170. # Add the rule to create generated.c at build time. This is placed
  171. # here to test adding the generation rule after referencing the
  172. # generated source in a target.
  173. add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
  174. DEPENDS $<1:generator> $<0:does_not_exist>
  175. COMMAND generator
  176. ARGS ${PROJECT_BINARY_DIR}/generated.c
  177. )
  178. target_link_libraries(CustomCommand GeneratedHeader)
  179. ##############################################################################
  180. # Test for using just the target name as executable in the COMMAND
  181. # section. Has to be recognized and replaced by CMake with the output
  182. # actual location of the executable.
  183. # Additionally the generator is created in an extra subdir after the
  184. # add_custom_command() is used.
  185. #
  186. # Test the same for add_custom_target()
  187. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  188. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
  189. )
  190. add_executable(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
  191. add_custom_target(RunTarget
  192. COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
  193. )
  194. add_custom_command(TARGET CustomCommandUsingTargetTest POST_BUILD
  195. COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
  196. add_subdirectory(GeneratorInExtraDir)
  197. ##############################################################################
  198. # Test shell operators in custom commands.
  199. add_executable(tcat tcat.cxx)
  200. # Test that list expansion from a generator expression works.
  201. set_property(TARGET tcat PROPERTY DEPSLIST tcat gen_redirect_in.c)
  202. add_custom_command(OUTPUT gen_redirect.c
  203. DEPENDS $<TARGET_PROPERTY:tcat,DEPSLIST>
  204. COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
  205. COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
  206. VERBATIM
  207. )
  208. ##############################################################################
  209. # Test non-trivial command line arguments in custom commands.
  210. set(EXPECTED_ARGUMENTS)
  211. set(CHECK_ARGS)
  212. if(NOT MSVC71)
  213. set(CHECK_ARGS -DPATH=c:/posix/path)
  214. endif()
  215. set(CHECK_ARGS
  216. ${CHECK_ARGS}
  217. c:/posix/path
  218. c:\\windows\\path
  219. 'single-quotes'
  220. single'quote
  221. \"double-quotes\"
  222. "\\;semi-colons\\;"
  223. "semi\\;colon"
  224. `back-ticks`
  225. back`tick
  226. "(parens)"
  227. "(lparen"
  228. "rparen)"
  229. {curly}
  230. {lcurly}
  231. rcurly}
  232. <angle>
  233. <langle
  234. rangle>
  235. [square]
  236. [lsquare # these have funny behavior due to special cases for
  237. rsquare] # windows registry value names in list expansion
  238. $dollar-signs$
  239. dollar$sign
  240. &ampersands&x # Borland make does not like trailing ampersand
  241. one&ampersand
  242. @two-ats@
  243. one@at
  244. ~two-tilda~
  245. one~tilda
  246. ^two-carrots^
  247. one^carrot
  248. %two-percents%
  249. one%percent
  250. !two-exclamations!
  251. one!exclamation
  252. ?two-questions?
  253. one?question
  254. *two-stars*
  255. one*star
  256. =two+equals=
  257. one=equals
  258. _two-underscores_
  259. one_underscore
  260. ,two-commas,
  261. one,comma
  262. .two-periods.
  263. one.period
  264. |two-pipes|
  265. one|pipe
  266. |nopipe
  267. "#two-pounds#"
  268. "one#pound"
  269. "#nocomment"
  270. "c:/posix/path/with space"
  271. "c:\\windows\\path\\with space"
  272. "'single quotes with space'"
  273. "single'quote with space"
  274. "\"double-quotes with space\""
  275. "\\;semi-colons w s\\;"
  276. "semi\\;colon w s"
  277. "`back-ticks` w s"
  278. "back`tick w s"
  279. "(parens) w s"
  280. "(lparen w s"
  281. "rparen) w s"
  282. "{curly} w s"
  283. "{lcurly w s"
  284. "rcurly} w s"
  285. "<angle> w s"
  286. "<langle w s"
  287. "rangle> w s"
  288. "[square] w s"
  289. "[lsquare w s" # these have funny behavior due to special cases for
  290. "rsquare] w s" # windows registry value names in list expansion
  291. "$dollar-signs$ w s"
  292. "dollar$sign w s"
  293. "&ampersands& w s"
  294. "one&ampersand w s"
  295. "@two-ats@ w s"
  296. "one@at w s"
  297. "~two-tilda~ w s"
  298. "one~tilda w s"
  299. "^two-carrots^ w s"
  300. "one^carrot w s"
  301. "%two-percents% w s"
  302. "one%percent w s"
  303. "!two-exclamations! w s"
  304. "one!exclamation w s"
  305. "*two-stars* w s"
  306. "one*star w s"
  307. "=two+equals= w s"
  308. "one=equals w s"
  309. "_two-underscores_ w s"
  310. "one_underscore w s"
  311. "?two-questions? w s"
  312. "one?question w s"
  313. ",two-commas, w s"
  314. "one,comma w s"
  315. ".two-periods. w s"
  316. "one.period w s"
  317. "|two-pipes| w s"
  318. "one|pipe w s"
  319. "#two-pounds# w s"
  320. "one#pound w s"
  321. ~ ` ! @ \# $ % ^ & _ - + = : "\;" \" ' , . ? "(" ")" { } []
  322. )
  323. if(NOT MINGW)
  324. # * # MinGW programs on windows always expands the wildcard!
  325. # / # MSys make converts a leading slash to the mingw home directory
  326. list(APPEND CHECK_ARGS * /)
  327. endif()
  328. # The windows command shell does not support a double quote by itself:
  329. # double\"quote
  330. # without messing up quoting of arguments following it.
  331. # Make tools need help with escaping a single backslash
  332. # \
  333. # at the end of a command because they think it is a continuation
  334. # character.
  335. # We now have special cases for shell operators:
  336. # | < > << >> &> 2>&1 1>&2
  337. # to allow custom commands to perform redirection.
  338. foreach(arg ${CHECK_ARGS} "")
  339. set(ARG "${arg}")
  340. string(REPLACE "\\" "\\\\" ARG "${ARG}")
  341. string(REPLACE "\"" "\\\"" ARG "${ARG}")
  342. string(APPEND EXPECTED_ARGUMENTS
  343. " \"${ARG}\",
  344. ")
  345. endforeach()
  346. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
  347. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
  348. @ONLY)
  349. add_executable(check_command_line
  350. ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
  351. set(output_name "check_command_line")
  352. set_property(TARGET check_command_line
  353. PROPERTY OUTPUT_NAME ${output_name})
  354. # set_target_properties(check_command_line PROPERTIES
  355. # COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
  356. add_custom_command(
  357. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  358. COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  359. -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
  360. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  361. ${CHECK_ARGS} ""
  362. VERBATIM
  363. COMMENT "Checking custom command line escapes (single'quote)"
  364. )
  365. set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  366. PROPERTIES SYMBOLIC 1)
  367. add_custom_target(do_check_command_line ALL
  368. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
  369. COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
  370. COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
  371. ${CHECK_ARGS} ""
  372. VERBATIM
  373. COMMENT "Checking custom target command line escapes ($dollar-signs$)"
  374. )
  375. add_dependencies(do_check_command_line check_command_line)
  376. add_custom_target(pre_check_command_line
  377. COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
  378. )
  379. add_dependencies(do_check_command_line pre_check_command_line)
  380. # <SameNameTest>
  381. #
  382. # Add a custom target called "SameName" -- then add a custom command in a
  383. # different target whose output is a full-path file called "SameName" -- then
  384. # add a second custom target that depends on the full-path file ".../SameName"
  385. #
  386. # At first, this reproduces a bug reported by a customer. After fixing it,
  387. # having this test here makes sure it stays fixed moving forward.
  388. #
  389. add_custom_command(
  390. OUTPUT SameName1.txt
  391. COMMAND ${CMAKE_COMMAND} -E touch SameName1.txt
  392. )
  393. add_custom_target(SameName ALL
  394. DEPENDS SameName1.txt
  395. )
  396. add_custom_command(
  397. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  398. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subdir
  399. COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  400. )
  401. add_custom_target(DifferentName ALL
  402. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
  403. )
  404. #
  405. # </SameNameTest>
  406. # Per-config target name and generator expressions.
  407. add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
  408. add_custom_command(
  409. OUTPUT perconfig.out
  410. COMMAND ${PerConfig_COMMAND}
  411. DEPENDS ${PerConfig_DEPENDS}
  412. VERBATIM
  413. )
  414. set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1)
  415. add_custom_target(perconfig_target ALL
  416. COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>"
  417. DEPENDS perconfig.out)
  418. # Test SOURCES in add_custom_target() with COMPILE_DEFINITIONS
  419. # which previously caused a crash in the makefile generators.
  420. add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp)
  421. set_property(SOURCE source_in_custom_target
  422. PROPERTY COMPILE_DEFINITIONS "TEST"
  423. )
  424. set(gen_path "${CMAKE_CURRENT_BINARY_DIR}//./foo")
  425. set(gen_file "${gen_path}/foo.cxx")
  426. add_custom_command(
  427. OUTPUT "${gen_file}"
  428. # Make sure the output directory exists before trying to write to it.
  429. COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}"
  430. COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}"
  431. )
  432. add_library(NormOutput "${gen_file}")
  433. string(APPEND gen_path "/bar")
  434. set(gen_file "${gen_path}/bar.cxx")
  435. add_custom_command(
  436. OUTPUT "${gen_path}"
  437. COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}"
  438. )
  439. add_custom_command(
  440. OUTPUT "${gen_file}"
  441. DEPENDS "${gen_path}"
  442. COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}")
  443. add_library(NormDepends "${gen_file}")
  444. # Test that USES_TERMINAL is parsed correctly.
  445. # It seems much more difficult to test that USES_TERMINAL actually gives
  446. # the subprocess console access, as test output is piped through CTest,
  447. # and CTest itself might not be connected to the console.
  448. set(gen_file "${gen_path}/bar2.cxx")
  449. add_custom_command(
  450. OUTPUT "${gen_file}"
  451. DEPENDS "${gen_path}"
  452. COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}"
  453. VERBATIM
  454. USES_TERMINAL
  455. )
  456. add_library(UseConsole "${gen_file}")
  457. add_custom_target(UseConsoleTarget ALL
  458. COMMAND ${CMAKE_COMMAND} -E echo "Custom console target."
  459. VERBATIM
  460. USES_TERMINAL
  461. )
  462. # Test COMMAND_EXPAND_LISTS
  463. set(cmp_args "1ARG=COMMAND_EXPAND_LISTS" "2ARG=test" "3ARG=outfile"
  464. "4ARG=content")
  465. set(AARGS "")
  466. foreach(arg IN LISTS cmp_args)
  467. list(APPEND AARGS "-DA${arg}")
  468. endforeach()
  469. set(gen_file "expand_custom_command.phony")
  470. add_custom_command(
  471. OUTPUT "${gen_file}"
  472. COMMAND ${CMAKE_COMMAND} ${AARGS}
  473. "-DB$<JOIN:$<TARGET_PROPERTY:command_expand_lists,CMPARGS>,;-DB>"
  474. "-P" "${CMAKE_CURRENT_SOURCE_DIR}/compare_options.cmake"
  475. COMMAND_EXPAND_LISTS
  476. VERBATIM
  477. )
  478. set_property(SOURCE "${gen_file}" PROPERTY SYMBOLIC ON)
  479. add_custom_target(command_expand_lists ALL DEPENDS "${gen_file}")
  480. set_property(TARGET command_expand_lists PROPERTY CMPARGS "${cmp_args}")