[CMake] emitting CMakeLists.txt for TRY_COMPILE considered harmful
Brandon J. Van Every
bvanevery at gmail.com
Wed Nov 22 03:37:19 EST 2006
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
More information about the CMake
mailing list