[CMake] Variable scope

Brad King brad.king at kitware.com
Mon Mar 21 16:00:36 EST 2005


Jorge Rodriguez wrote:
> I'm experiencing some strange behavior with variable scope in cmake 2.0.5.
> 
> To explain the situation, say I have this directory structure:
> 
> CMakeLists.txt
> include.cmake
> src/CMakeLists.txt
> 
> include.cmake has this:
> 
> # Figure out what version of the C++ compiler we're using so we
> # can tag dlls with it later.
> SET(VS_COMPILER "60")
> 
> IF(WIN32)
>  EXEC_PROGRAM(cl OUTPUT_VARIABLE COMPILER_VERSION)
>  IF(COMPILER_VERSION MATCHES ".*13\\.10.*")
>    SET(VS_COMPILER "71")
>  ENDIF(COMPILER_VERSION MATCHES ".*13\\.10.*")
> ENDIF(WIN32)
> 
> in CMakeLists.txt (top-level) you have this:
> 
> PROJET(PROJ)
> SET(VS_COMPILER "60")
> INCLUDE(${PROJ_SOURCE_DIR}/include.cmake)
> MESSAGE("Compiler 1: ${VS_COMPILER}")
> SUBDIRS(src)
> 
> and in srcs/CMakeLists.txt:
> 
> MESSAGE("Compiler 2: ${VS_COMPILER}")
> 
> The output of this when cmake is run is:
> 
> Compiler 1: 71
> Compiler 2: 60
> 
> So, it seems that the value of VS_COMPILER set in include.cmake is reset 
> in the srcs subdirectory to what it was originally set to. Am I 
> hallucinating?

This is because you are using EXEC_PROGRAM to set the value.  An 
unfortunate holdover from ancient CMake versions is that certain 
commands are "inherited" into subdirectories and others are not. 
EXEC_PROGRAM is not inherited.  What this means is that when the 
listfile code executes in the subdirectory the EXEC_PROGRAM command is 
left out.  Therefore the code executes differently.  This problem will 
be fixed in CMake 2.2, but for now you will have to cache the result:

EXEC_PROGRAM(cl OUTPUT_VARIABLE COMPILER_VERSION)
SET(COMPILER_VERSION "${COMPILER_VERSION}" CACHE INTERNAL "")

The other option is to use TRY_RUN to get the compiler version.  This 
will be more robust anyway.  Just create a small program that uses the 
preprocessor to determine the compiler version and print it out.  Then 
use the TRY_RUN command to compile and run this program at CMake 
configuration time.

-Brad


More information about the CMake mailing list