MantisBT - CMake
View Issue Details
0015001CMakeCMakepublic2014-07-01 17:112016-06-10 14:31
George Sakhnovsky 
Kitware Robot 
lowfeaturealways
closedmoved 
x64Windows7
CMake 2.8.12.2 
 
0015001: add_custom_command: allow quoting of VS $(VAR) placeholders
I have an add_custom_command COMMAND line where I want to wrap several of the strings in double quotes.

cmake src snippet:

        add_custom_command(
            TARGET ${target_name}
            PRE_BUILD
            COMMAND "\"$(DevEnvDir)tf\"" history "\"$(SolutionDir)\"" /stopafter:1 /recursive > changeset.dat

The generated vcxproj file looks as follows. Note that the escaped double quotes made it through quite literally:

\"$(DevEnvDir)tf\" history "$(SolutionDir)" /stopafter:1 /recursive > changeset.dat

The desired behavior is to have $(DevEnvDir)tf wrapped in double quotes like so:

"$(DevEnvDir)tf" history "$(SolutionDir)" /stopafter:1 /recursive > changeset.dat

Why does escaping double quotes work for the second string in the line but not the first? Should this be accomplished differently for the first string because it's the actual command? If this is not a bug, what's the workaround?
No tags attached.
related to 0014787closed Kitware Robot Unable to include a directory named after a Visual Studio macro. 
Issue History
2014-07-01 17:11George SakhnovskyNew Issue
2014-07-02 09:38Brad KingNote Added: 0036304
2014-07-02 10:20George SakhnovskyNote Added: 0036305
2014-07-02 10:34Brad KingNote Added: 0036307
2014-07-02 11:01George SakhnovskyNote Added: 0036308
2014-07-02 11:15Brad KingSeverityminor => feature
2014-07-02 11:15Brad KingStatusnew => backlog
2014-07-02 11:15Brad KingSummaryadd_custom_command: inconsistent treatment of escaped quotes => add_custom_command: allow quoting of VS $(VAR) placeholders
2014-07-02 11:15Brad KingDescription Updatedbug_revision_view_page.php?rev_id=1508#r1508
2014-07-02 11:15Brad KingRelationship addedrelated to 0014787
2014-07-02 11:16Brad KingNote Added: 0036309
2016-06-10 14:29Kitware RobotNote Added: 0042576
2016-06-10 14:29Kitware RobotStatusbacklog => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0036304)
Brad King   
2014-07-02 09:38   
Try using the VERBATIM option to add_custom_command. It activates more correct escaping behavior to pass things through to the command line correctly. Without that option the default has some historical behavior.
(0036305)
George Sakhnovsky   
2014-07-02 10:20   
Adding VERBATIM changes the behavior but does not resolve the issue.

COMMAND "$(DevEnvDir)tf" history "(SolutionDir)" /stopafter:1 /recursive > changeset.dat

becomes

$(DevEnvDir)tf history (SolutionDir) /stopafter:1 /recursive > changeset.dat

while

COMMAND "\"$(DevEnvDir)tf\"" history "\"(SolutionDir)\"" /stopafter:1 /recursive > changeset.dat

becomes

\"$(DevEnvDir)tf\" history \"(SolutionDir)\" /stopafter:1 /recursive > changeset.dat

Unless I should be doing something different to get the plain double quotes I'm after?
(0036307)
Brad King   
2014-07-02 10:34   
Re 0015001:0036305: CMake is not really designed with VS placeholders in mind. They are not cross-platform.

Why do you need $(SolutionDir) instead of using "${PROJECT_BINARY_DIR}"?
You could also use find_program to get the real location of "tf" and pass that.

With VERBATIM and the escaped quotes CMake thinks you want the literal double quotes to be part of the command arguments so it escapes them for the cmd shell, and without the escaped quotes CMake does not see any characters that need quoting and so leaves out the quotes. It is not aware of how the build system will replace the values with something that needs quoting.

I think the Windows command shell will pick up $(DevEnvDir)tf without quotes even if it has spaces after replacement. You could try using this without VERBATIM:

 "$(DevEnvDir)tf" history "\"$(SolutionDir)\""

to get

 $(DevEnvDir)tf history "$(SolutionDir)"
(0036308)
George Sakhnovsky   
2014-07-02 11:01   
$(DevEnvDir)tf without quotes will not be executed correctly if it contains spaces after replacement.

I implemented your suggestion to use find_program instead, and that works nicely.
(0036309)
Brad King   
2014-07-02 11:16   
Re 0015001:0036308: Okay, then we have a workaround. I've changed this to a feature request for passing placeholders with quoting and added a link to a similar issue.
(0042576)
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.