On 08/13/2010 09:49 PM, Ris Misner wrote:
> Hi,
> 
> I am new to using cmake, and trying to get a custom build command to embed 
> quotes for a project that I'm compiling in MS visual studio on a windows 
> machine.
> 
> I have this in my cmake file:
> 
> COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> "${PERL_EXECUTABLE}" ${MAKE_TOKENIZER} > ${DERIVED_SOURCES_DIR}/tokenizer.cpp
> 
> I need to achieve this custom build step in my generated vcproj file:
> 
> C:\cygwin\bin\flex.exe -t 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\tokenizer.flex | 
> "C:\cygwin\bin\perl.exe" 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\maketokenizer > 
> E:\Wolverine\git-Jason\git-WebKit\WebKitBuild\DerivedSources\tokenizer.cpp
> 
> Please note the wrapping quotes around "C:\cygwin\bin\perl.exe".  That's 
> critical, or the DOS shell complains that 'C:' is not a valid command.
> 
> Cmake is removing the quotes and giving me this:
> 
> C:\cygwin\bin\flex.exe -t 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\tokenizer.flex | 
> C:\cygwin\bin\perl.exe 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\maketokenizer > 
> E:\Wolverine\git-Jason\git-WebKit\WebKitBuild\DerivedSources\tokenizer.cpp
> 
> Which fails like I said.  DOS complains that 'C:' is not a valid command, and 
> doesn't parse it correctly without the quotes around the path to perl.exe.
> 
> When I try to escape the quotes, like this:
> 
> COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> \"${PERL_EXECUTABLE}\" ${MAKE_TOKENIZER} > 
> ${DERIVED_SOURCES_DIR}/tokenizer.cpp
> 
> Cmake preserves the backslashes, and generates this:
> 
> C:\cygwin\bin\flex.exe -t 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\tokenizer.flex | 
> \"C:\cygwin\bin\perl.exe\" 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\maketokenizer > 
> E:\Wolverine\git-Jason\git-WebKit\WebKitBuild\DerivedSources\tokenizer.cpp
> 
> 
> I have also tried to work around it by performing a double macro expansion 
> like this:
> 
> SET(cmd "${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> \"${PERL_EXECUTABLE}\" ${MAKE_TOKENIZER} > 
> ${DERIVED_SOURCES_DIR}/tokenizer.cpp")
> COMMAND ${cmd}
> 
> It doesn't help... I get this:
> 
> "C:\cygwin\bin\flex.exe -t 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\tokenizer.flex | 
> \"C:\cygwin\bin\perl.exe\" 
> E:\Wolverine\git-Jason\git-WebKit\WebCore\css\maketokenizer > 
> E:\Wolverine\git-Jason\git-WebKit\WebKitBuild\DerivedSources\tokenizer.cpp"
> 
> The backslashes to escape the quotes were preserved (breaking it) and the 
> wrapping quotes around the outside of the whole command string were also 
> preserved, which makes the DOS shell think this is one long file name.
> 
> Whatever I try, the quotes are either completely removed, or the backslashes 
> to escape them are preserved as \" instead of becoming a simple "
> 
> I also tried putting the quotes in their own escaped substrings like this: 
> "\""${PERL_EXECUTABLE}"\""
> 
> COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> "\""${PERL_EXECUTABLE}"\"" ${MAKE_TOKENIZER} > 
> ${DERIVED_SOURCES_DIR}/tokenizer.cpp
> 
> And I was surprised to see this output:
> 
> 
> C:\cygwin\bin\flex.exe -t 
> E:/Wolverine/git-Jason/git-WebKit/WebCore/css/tokenizer.flex | \" 
> C:/cygwin/bin/perl.exe\"\"\" 
> E:/Wolverine/git-Jason/git-WebKit/WebCore/css/maketokenizer > 
> E:/Wolverine/git-Jason/git-WebKit/WebKitBuild/DerivedSources/tokenizer.cpp
> 
> 
> So then I tried to put just the " into its own expansion like this:
> 
> SET(QUOTE \")
> COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> ${QUOTE}${PERL_EXECUTABLE}${QUOTE} ${MAKE_TOKENIZER} > 
> ${DERIVED_SOURCES_DIR}/tokenizer.cpp
> 
> But the backslash to escape the quote is still preserved that way too, and I 
> get this:
> 
> 
> C:\cygwin\bin\flex.exe -t 
> E:/Wolverine/git-Jason/git-WebKit/WebCore/css/tokenizer.flex | 
> \"C:/cygwin/bin/perl.exe\" 
> E:/Wolverine/git-Jason/git-WebKit/WebCore/css/maketokenizer > 
> E:/Wolverine/git-Jason/git-WebKit/WebKitBuild/DerivedSources/tokenizer.cpp
> 
> 
> 
> Is there any way to make this generate the output that I need?  Is this a bug 
> in the version of cmake that I'm using (2.6 for windows ce) or is there a 
> trick to the cmake syntax?
> 
> 
> For reference details, the complete context of my custom command comes from 
> this macro:
> 
> SET(MAKE_TOKENIZER ${WEBCORE_DIR}/css/maketokenizer)
> # - Create ${DERIVED_SOURCES_DIR}/tokenizer.cpp
> # GENERATE_TOKENIZER()
> MACRO(GENERATE_TOKENIZER)
>   # do a little dance to embed quotes around perl.exe, or cmake messes them up
>   ADD_CUSTOM_COMMAND(
>     OUTPUT ${DERIVED_SOURCES_DIR}/tokenizer.cpp
>     DEPENDS ${WEBCORE_DIR}/css/tokenizer.flex ${MAKE_TOKENIZER}
>     COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex | 
> "${PERL_EXECUTABLE}" ${MAKE_TOKENIZER} > ${DERIVED_SOURCES_DIR}/tokenizer.cpp
>     VERBATIM)
> ENDMACRO()
> GENERATE_TOKENIZER() # this is called out in a separate file
> 
> I am using cmake 2.6 for Windows CE because that's the version that was 
> branched to support builds for Windows CE (so unfortunately if this is a bug 
> that has been fixed, I can't update to cmake 2.8 - was there a work-around in 
> cmake 2.6?)

FYI: On *nix with CMake 2.8.2, I also didn't manage to force a quoted
command, say "perl", into the Makefiles instead of the usually unquoted
one unless the command contains blanks. Apparently, ADD_CUSTOM_COMMAND()
has its own ideas for handling quotes.

If your problem still persists, the following workaround could possibly
help: Create a file tokenizer.cmake, e.g. by FILE(WRITE ...) or from a
template via CONFIGURE_FILE() or hardcoded in the source directory:

FILE(WRITE ${CMAKE_BINARY_DIR}/tokenizer.cmake "EXECUTE_PROCESS(
COMMAND ${FLEX_EXECUTABLE} -t ${WEBCORE_DIR}/css/tokenizer.flex
COMMAND \"${PERL_EXECUTABLE}\" ${MAKE_TOKENIZER}
OUTPUT_FILE ${DERIVED_SOURCES_DIR}/tokenizer.cpp\n")

Note the escaped quotes around ${PERL_EXECUTABLE}.

Now, change the custom command to:

ADD_CUSTOM_COMMAND(
    OUTPUT ${DERIVED_SOURCES_DIR}/tokenizer.cpp
    DEPENDS ${WEBCORE_DIR}/css/tokenizer.flex ${MAKE_TOKENIZER}
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/tokenizer.cmake
    VERBATIM)

Perhaps, EXECUTE_PROCESS()'s COMMAND option treats the quotes or
whatever is your issue's reason better than ADD_CUSTOM_COMMAND()'s
w.r.t. to your shell, but I can't test - currently, no access to any
windowed machine... ;-)

Hope that helps.

Regards,

Michael
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to