MantisBT - CMake
View Issue Details
0014353CMakeCCMakepublic2013-08-13 04:122016-06-10 14:31
chrislu 
Kitware Robot 
normalfeaturealways
closedmoved 
Windows
CMake 2.8.11.2 
 
0014353: list expansion from generator expression in custom command
the below example breaks when spaces are in the argument lists.

for the release configuration everything works as expected as the argument list contains just a single entry. but for the debug configuration $<1:something something dark side> is inserted into the argument list.

this is very urgend as CMake does offer no other way to set different arguments to the custom commands depending on the configuration!

set(SCM_ARGS_A something)
set(SCM_ARGS_B something something dark side)

add_custom_command(OUTPUT ${CUDA_NVCC_OUTPUT_FILE}
                               COMMAND ${SCM_CUDA_NVCC_COMMAND}
                                   ARGS $<$<CONFIG:Release>:${SCM_ARGS_A}>
                                        $<$<CONFIG:Debug>:${SCM_ARGS_B }>
                                        ${SCM_CUDA_NVCC_OPTIONS}
                                        ${SCM_CUDA_NVCC_INC_DIR_STRING}
                                        ${SCM_CUDA_NVCC_DEF_STRING}
                                        -o \"${CUDA_NVCC_OUTPUT_FILE}\"
                                        \"${input_file}\"
                               MAIN_DEPENDENCY ${input_file}
                               DEPENDS ${input_file}
                               COMMENT "NVCC compiling (${input_file_name}):")
No tags attached.
related to 0014352closed Stephen Kelly CMake crashing with white space in generator expression 
related to 0015586closed  Add support for lists inside generator expressions 
? expand_command.cmake (1,643) 2015-04-20 12:32
https://public.kitware.com/Bug/file/5436/expand_command.cmake
Issue History
2013-08-13 04:12chrisluNew Issue
2013-08-13 04:33chrisluNote Added: 0033700
2013-08-13 08:07Stephen KellyNote Added: 0033702
2013-08-13 09:13Brad KingRelationship addedrelated to 0014352
2013-08-14 03:16chrisluNote Added: 0033710
2013-08-14 03:20Stephen KellyStatusnew => resolved
2013-08-14 03:20Stephen KellyResolutionopen => no change required
2013-08-14 03:20Stephen KellyAssigned To => Stephen Kelly
2013-08-14 04:15chrisluNote Added: 0033711
2013-08-14 04:15chrisluStatusresolved => feedback
2013-08-14 04:15chrisluResolutionno change required => reopened
2013-08-14 04:16chrisluNote Deleted: 0033710
2013-08-14 04:27Stephen KellyNote Added: 0033712
2013-08-14 04:29Stephen KellyAssigned ToStephen Kelly =>
2013-08-14 04:29Stephen KellyPriorityurgent => normal
2013-08-14 04:29Stephen KellySeverityblock => feature
2013-08-14 04:29Stephen KellyStatusfeedback => backlog
2013-08-14 04:29Stephen KellyOSWindows 7 =>
2013-08-14 04:29Stephen KellyOS Versionx64 =>
2013-08-14 04:29Stephen KellySummarygenerator expression $<1:...> and $<0:...> fail with white space in provided strings. => list expansion from generator expression in custom command
2013-08-14 04:37Stephen KellyNote Added: 0033713
2013-08-14 07:59chrisluNote Added: 0033714
2013-08-14 08:09Stephen KellyNote Added: 0033715
2013-08-15 06:14chrisluNote Added: 0033717
2013-08-15 06:18Stephen KellyNote Added: 0033718
2015-04-20 12:32arlbranchFile Added: expand_command.cmake
2015-04-20 12:39arlbranchNote Added: 0038558
2015-05-26 10:55Nils GladitzRelationship addedrelated to 0015586
2016-06-10 14:29Kitware RobotNote Added: 0042348
2016-06-10 14:29Kitware RobotStatusbacklog => resolved
2016-06-10 14:29Kitware RobotResolutionreopened => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0033700)
chrislu   
2013-08-13 04:33   
more basic:

$<0:something> -> OK
$<0:something dark> -> $<0:something dark> added to command arguments.
(0033702)
Stephen Kelly   
2013-08-13 08:07   
Generally, things are easier if you provide sscce code with bugs: http://sscce.org/ [^]

If you provide only a snippet which depends on CUDA, I have to create my own sscce and that's not necessarily showing the same problem as you have.

Here is my testcase, which seems to work fine:

 cmake_minimum_required(VERSION 2.8)

 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.out
                    COMMAND dd
                        ARGS if=${CMAKE_CURRENT_SOURCE_DIR}/main.cpp of=${CMAKE_CURRENT_BINARY_DIR}/main.out
                        "$<$<CONFIG:Debug>:some thing>"
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)

 add_library(foo SHARED main.cpp
   ${CMAKE_CURRENT_BINARY_DIR}/main.out
 )
(0033711)
chrislu   
2013-08-14 04:15   
repro:

cmake_minimum_required(VERSION 2.8)

set (SCM_CUDA_NVCC_OPTIONS --cl-version 2010 CACHE STRING "schism cuda internal" FORCE)

set(SCM_CUDA_NVCC_OPTIONS_DEBUG -Xcompiler A,B,C,D CACHE STRING "schism cuda internal" FORCE)
set(SCM_CUDA_NVCC_OPTIONS_RELEASE --optimize 3 -Xcompiler E,F,G,H CACHE STRING "schism cuda internal" FORCE)

set(input_file foobar.cu)
set(CUDA_NVCC_OUTPUT_FILE foobar.cu.obj)

add_custom_command(OUTPUT ${CUDA_NVCC_OUTPUT_FILE}
                   COMMAND nvcc.exe
                       ARGS $<$<CONFIG:Release>:${SCM_CUDA_NVCC_OPTIONS_RELEASE}>
                            $<$<CONFIG:Debug>:${SCM_CUDA_NVCC_OPTIONS_DEBUG}>
                            ${SCM_CUDA_NVCC_OPTIONS}
                            -o \"${CUDA_NVCC_OUTPUT_FILE}\"
                            \"${input_file}\"
                   MAIN_DEPENDENCY ${input_file}
                   DEPENDS ${input_file}
                   COMMENT "NVCC compiling (${input_file_name}):")


set_source_files_properties(${CUDA_NVCC_OUTPUT_FILE} PROPERTIES GENERATED TRUE)

add_executable(foo main.cpp ${CUDA_NVCC_OUTPUT_FILE})



the problem here is the same as described originally. generate a visual studio project and look for the nvcc line:

nvcc.exe $<0:--optimize 3 -Xcompiler E,F,G,H> $<1:-Xcompiler A,B,C,D> --cl-version 2010 -o "foobar.cu.obj" "foobar.cu"


now with your example:
                       ARGS "$<$<CONFIG:Release>:${SCM_CUDA_NVCC_OPTIONS_RELEASE}>"
                            "$<$<CONFIG:Debug>:${SCM_CUDA_NVCC_OPTIONS_DEBUG}>"

the nvcc line reads:

nvcc.exe --optimize;3;-Xcompiler;E,F,G,H --cl-version 2010 -o "foobar.cu.obj" "foobar.cu"

UNUSABLE! the added ; break the command line. i also tried add the "" to the SCM_CUDA_NVCC_OPTIONS_DEBUG variables which are then transported to the command line, which is also UNUSABLE.

please advise.
(0033712)
Stephen Kelly   
2013-08-14 04:27   
Here's a simpler example:

set(things raindrops windows kittens mittens)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.out
                    COMMAND dd
                        ARGS if=${CMAKE_CURRENT_SOURCE_DIR}/main.cpp of=${CMAKE_CURRENT_BINARY_DIR}/main.out
                        "$<JOIN:$<$<CONFIG:Debug>:${things}>, >"
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)

add_library(foo SHARED main.cpp
${CMAKE_CURRENT_BINARY_DIR}/main.out
)


The

 "$<JOIN:$<$<CONFIG:Debug>:${things}>, >"

can also be simplified to

"$<JOIN:${things}, >"

This results in dd if=/home/stephen/dev/src/playground/cmake/main.cpp of=/home/stephen/dev/src/playground/cmake/build/main.out raindrops\ windows\ kittens\ mittens on the command line, which is not what you want.

The problem is known, but there's no one working on a fix:

 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/7063/focus=7068 [^]
(0033713)
Stephen Kelly   
2013-08-14 04:37   
The workarounds available are either:

1) Use file(GENERATE) to generate a script and execute the script instead.
2) Use file(GENERATE) to a response file, if the tool supports it, as was done here: http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9ce60ff50 [^]

file(GENERATE) is new in CMake 2.8.12.
(0033714)
chrislu   
2013-08-14 07:59   
ok, but how is this a feature request?

and how can something so simple be made so awesomely difficult? how many years now are devs asking to set arguments etc. depending on the build configuration?

madness...
(0033715)
Stephen Kelly   
2013-08-14 08:09   
Of course, another workaround is to put the config-genex on each element in the list.


set(things $<$<CONFIG:Debug>:raindrops> $<$<CONFIG:Debug>:windows> $<$<CONFIG:Release>:kittens> $<$<CONFIG:Release>:mittens>)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.out
                    COMMAND dd
                        ARGS if=${CMAKE_CURRENT_SOURCE_DIR}/main.cpp of=${CMAKE_CURRENT_BINARY_DIR}/main.out
                        ${things}
# "$<JOIN:$<$<CONFIG:Debug>:${things}>, >"
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)



That might be something that works for your CUDA case, I don't know.
(0033717)
chrislu   
2013-08-15 06:14   
what is the real problem here?

are the genex not evaluated correctly or is there something wrong much deeper. if its a simple fix point me to the location and maybe i can hack my local version to do what it is supposed to do.
(0033718)
Stephen Kelly   
2013-08-15 06:18   
See the thread linked in 0014353:0033712.
(0038558)
arlbranch   
2015-04-20 12:39   
Since this pops up on the mailing list periodically, I've attached a (hopefully) generic workaround to get generator expression generated lists expanded in the COMMAND of add_custom_target() and add_custom_command().

==== Example use: =====

include("${CMAKE_SOURCE_DIR}/CMake/expand_command.cmake")

expandable_command(echocmd echo gcc
    -I$<JOIN:$<TARGET_PROPERTY:echo,CUSTOM_INCLUDE_DIRECTORIES>,$<SEMICOLON>-I>
    -o someprog main.cc)
add_custom_target(echo ALL
    COMMAND ${echocmd}
    COMMENT "Building target echo"
    VERBATIM
)
set_property(TARGET echo PROPERTY CUSTOM_INCLUDE_DIRECTORIES
    "/path/a" "/path/b" "/path/c")

====== End Example =======

Note that echo doesn't care whether the arguments are passed as separate arguments or a single string, so you have to check the verbose output (make VERBOSE=1 or ninja -v) to see that this does the right thing.
(0042348)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.