Summary: emitting a CMakeLists.txt is never parallel with standard coding practices in the toplevel CMakeLists.txt. At a minimum, this causes programmers to do everything 2 different ways. In the likely case, the emission fails because it is fragile as quotes are consumed. These kinds of problems can easily chew up a programmer's entire day, as I did today.

I need to test whether Darcs source control commands actually work in build environments. It's dicey under Windows because there's no Cygwin version of Darcs, just a Windows native version. That would seem good for Windows people, but the Windows Command Prompt, Cygwin shell, MSYS shell, and the Visual Studio shell are all distinct build environments. They don't share the same search paths, and they don't understand each other's path conventions. So, aiming the right path at the right shell and tool is highly problematical.

I have working code for this problem, targeted at CMake 2.4.3. In that version, I simply ducked all the problems. I used WORKING_DIRECTORY as much as possible so that I wouldn't have to use the Darcs --repodir=E:\devel\src\chicken command option. I resorted to such workarounds after 3 days of head scratching. The head scratching did have a productive outcome, however: Brad implemented the VERBATIM feature in reaction to my problem. Unfortunately, then I went into survival mode and was unable to allocate time to trying out VERBATIM while CMake 2.4.4 was still in beta.

Come CMake 2.4.4, I thought I would give VERBATIM a whirl. Oddly, I was unable to get it to do anything constructive. I started having success when I abandoned it, at least at the level of my topmost CMakeLists.txt. Code like the following works fine:

     # NATIVE_PATH reverses slashes and adds quotes for Windows
     NATIVE_PATH(Chicken_SOURCE_DIR NATIVE_CHICKEN_SOURCE_DIR)
     NATIVE_PATH(CHANGELOG_FILE NATIVE_CHANGELOG_FILE)

     ADD_CUSTOM_TARGET(darcs-changelog ALL
       COMMENT "Generating ${NATIVE_CHANGELOG_FILE} from Darcs repository."
COMMAND ${DARCS_EXE} changes --repodir=${NATIVE_CHICKEN_SOURCE_DIR} > ${NATIVE_CHANGELOG_FILE}
     )

But I cannot, for the life of me, emit similar code via a FILE(WRITE ...).
   SOME_HAIRY_PATH(Chicken_SOURCE_DIR REPO)
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/try-darcs/CMakeLists.txt "
     PROJECT(try-darcs)
     ADD_CUSTOM_TARGET(try
       COMMAND ${DARCS_EXE} changes --repodir=${REPO} --last=0
     )
   ")

It doesn't matter what function I write for SOME_HAIRY_PATH. Doesn't matter whether I add quotes, a level of escapes, more backslashes, less backslashes, anything, everything, nothing. The problem is, the act of emitting a file in and of itself consumes quotes. I should have strings like --repodir=\"E:\devel\src\chicken\" in the above example. But that doesn't work because the single \ are interpreted as escapes for letters, giving CMake parse errors. --repodir=\"E:\\devel\\src\\chicken\" writes out to the file and doesn't generate parse errors, but the \\ aren't transformed into \, they stay as \\. So Darcs barfs on them.

VERBATIM didn't seem to solve this. Did I miss how it was supposed to be used? Or was FILE(WRITE ...) consumption not considered?


Cheers,
Brandon Van Every

_______________________________________________
CMake mailing list
CMake@cmake.org
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to