MantisBT - CMake
View Issue Details
0011660CMakeCMakepublic2011-01-05 18:372011-01-31 15:58
sly5 
Brad King 
normalmajoralways
closedsuspended 
Windows
CMake 2.8.3 
CMake 2.8.4CMake 2.8.4 
0011660: Semicolons escaped badly
A macro definition that contains semicolons is escaped badly on Visual Studio. In particular,

set_source_files_properties( main.cpp PROPERTIES COMPILE_DEFINITIONS "MSG=\"hello\;world\"" )

Turns into the following switch:

 /D "MSG=\"hello"" /D "world\\"

It works fine on a Linux platform by correctly escaping as

-DMSG="\"hello;world\""
Create a CMakeLists.txt with the content:

______________________________________________
project( Hello CXX )
cmake_minimum_required(VERSION 2.8)
add_executable( hello hello.cpp )
set_source_files_properties( hello.cpp
   PROPERTIES COMPILE_DEFINITIONS
   "MSG=\"hello\;world\""
)
==============================================

And a hello.cpp file
______________________________________________
#include <iostream>
int main() {
   std::cout<< MSG <<std::endl;
   return 0;
}
==============================================


Build and compile on Windows using Visual Studio.
No tags attached.
related to 0011712closed Brad King add_definitions/COMPILE_DEFINITIONS do not support defines with semicolon 
Issue History
2011-01-05 18:37sly5New Issue
2011-01-06 07:35Brad KingNote Added: 0024449
2011-01-06 07:35Brad KingStatusnew => closed
2011-01-06 07:35Brad KingAssigned To => Brad King
2011-01-06 07:35Brad KingResolutionopen => not fixable
2011-01-06 16:00sly5Note Added: 0024480
2011-01-06 16:00sly5Statusclosed => feedback
2011-01-06 16:00sly5Resolutionnot fixable => reopened
2011-01-06 16:23Brad KingNote Added: 0024482
2011-01-06 16:25Brad KingNote Added: 0024483
2011-01-17 07:45Brad KingRelationship addedrelated to 0011712
2011-01-17 08:31Brad KingNote Added: 0024741
2011-01-17 08:33Brad KingNote Added: 0024742
2011-01-17 08:33Brad KingStatusfeedback => closed
2011-01-17 08:33Brad KingResolutionreopened => suspended
2011-01-31 15:58David ColeFixed in Version => CMake 2.8.4
2011-01-31 15:58David ColeTarget Version => CMake 2.8.4

Notes
(0024449)
Brad King   
2011-01-06 07:35   
See disclaimer in the documentation:

http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_sf:COMPILE_DEFINITIONS [^]

"Disclaimer: Most native build tools have poor support for escaping certain values. CMake has work-arounds for many cases but some values may just not be possible to pass correctly"
(0024480)
sly5   
2011-01-06 16:00   
I see the disclaimer, but I suspect this is actually more subtle than "poor support of build tools for escapes". It seems to be Visual Studio version oversight in CMake code itself.

In 2.8.3 release version, Source\cmVisualStudioGeneratorOptions.cxx line 192:

    // Escape the definition for the compiler.
    std::string define;
    if(this->Version != 10)
      {
      define =
        this->LocalGenerator->EscapeForShell(di->c_str(), true);
      }

which seems to execute some function in Source\kwsys\System.c Line 516

    else if(*c == ';')
      {
      if(flags & kwsysSystem_Shell_Flag_VSIDE)
        {
        /* In a VS IDE a semicolon is written ";". If this is written
           in an un-quoted argument it starts a quoted segment,
           inserts the ; and ends the segment. If it is written in a
           quoted argument it ends quoting, inserts the ; and restarts
           quoting. Either way the ; is isolated. */
        *out++ = '"';
        *out++ = ';';
        *out++ = '"';

That the semicolon requires quotes doesn't seem to apply to VS 9, and quoting it actually doesn't work.

So it seems the issue Escape issue manifests in VS Versions <10 (and >10 for that matter!) (I'll check with 10 to be sure, I have VS 10 installed somewhere).

Now, are you sure this is "not fixable" ?
(0024482)
Brad King   
2011-01-06 16:23   
Patch welcome. The Tests/Preprocess/CMakeLists.txt file has a bunch of comments about support for ';' on different systems:

  http://cmake.org/gitweb?p=cmake.git;a=blob;f=Tests/Preprocess/CMakeLists.txt;h=b4ec17c6;hb=63d21c1f [^]

We generally use configure_file to create header files that #define whatever string we need. No escaping needed.
(0024483)
Brad King   
2011-01-06 16:25   
FYI, the "System.c" code you quoted was written for escaping arguments to custom commands (see add_custom_command's VERBATIM option). It wasn't meant to apply to compile definition properties, so the "define=EscapeForShell()" code path is the right place to fix this.
(0024741)
Brad King   
2011-01-17 08:31   
Documentation updated to mention known limitations:

  http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c64d1385 [^]
(0024742)
Brad King   
2011-01-17 08:33   
The documentation now mentions that ";" does not work everywhere. In a real project the recommended approach in the documentation is to configure a header file.

I consider this issue closed. If someone has a way to improve the support in VS2010 please re-open with a proposed patch.