[CMake] VS2005: CMAKE_CXX_FLAGS not used when project() is placed after definition

Michael Hertling mhertling at online.de
Thu Sep 22 11:28:12 EDT 2011


On 09/21/2011 09:26 AM, Jens Auer wrote:
>> The PROJECT() command has significant side effects, e.g. for 
>> C++ projects, it loads Modules/CMakeCXXInformation.cmake containing:
>>
>> SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT}" CACHE STRING
>>      "Flags used by the compiler during all build types.")
>>
>> If CMAKE_CXX_FLAGS has no value in the cache before, this 
>> command will write to the cache *and* to the current scope, 
>> see [1]. Thus, it will overwrite the value provided in the 
>> CMakeLists.txt in the first case.
>> In the second case, the CMakeLists.txt file provides the 
>> definitive value in the current scope which will be in effect 
>> afterwards.
>>
>> IMO, it's best to have PROJECT() as one of the very first 
>> commands in CMakeLists.txt files, and to only put other 
>> commands before it if one really knows about the consequences.
> This behvaior seems to be a little inconsistent. When I remember correctly, the optimization switch gets set correctly in both cases, but the /EHa is lost. [...]

The /EH and /O flags stem from different origins: The former from
CMAKE_CXX_FLAGS and the latter from CMAKE_CXX_FLAGS_DEBUG, e.g., cf.
Modules/Platform/Windows-cl.cmake. Therefore, if you build the debug
configuration with CMAKE_CXX_FLAGS set before PROJECT(), you will end
up with /EHsc - overwritten in CMAKE_CXX_FLAGS by PROJECT() - and /O2
normally from CMAKE_CXX_FLAGS_DEBUG, so it *seems* as if the /O2 flag
is preserved. In this regard, CMake's behavior is consistent, IMO.

> [...] I also think that overwriting the variable in the current scope is unobivious and should at least be documented in the manual, but I would prefer to not touch the variable or even use the current value.

The CMAKE_<LANG>_FLAGS[_<CONFIG>] variables serve as a means for the
user to specify basic and configuration-related compilation flags on
the CMake command line or the GUI, and for this reason, they're all
cached with reasonable default values. Thus, it's actually you who
provides for an unobivious behavior when you overwrite them in the
CMakeLists.txt files with SET(CMAKE_CXX_FLAGS "..."). Suppose your
user configures the project with "cmake -DCMAKE_CXX_FLAGS=..."; of
course it's expected that these flags hold, but the user will see
the possibly different flags established by the CMakeLists.txt.

If you have special requirements w.r.t. compilation flags for your
project, I think it's best to provide your own default values, e.g.

SET(CMAKE_CXX_FLAGS "..." CACHE TYPE STRING "Default C++ flags")
...
PROJECT(...)

or via the -C or -D command line options, or even define a customized
configuration with suitable default values for the project, refer to
FAQ 4.16,17 for more information. In any case, respect your user's
choice as far as possible, and keep in mind that such compilation
flags are compiler-specific.

> Best regards,
>   Jens

Regards,

Michael


More information about the CMake mailing list