[CMake] set(... CACHE ) broken for CMAKE_C_FLAGS_{DEBUG, RELEASE, ...} ?

Michael Hertling mhertling at online.de
Wed Jul 6 13:26:39 EDT 2011


On 07/06/2011 03:41 PM, Jerry Gagelman wrote:
> I'm redistributing a library for which the original authors have hand coded
> their own Makefile, but I would like to streamline everything with CMake.
> Their Makefile provides for Debug and Release flavored configurations, each
> has its own set of CFLAGS, and for consistency I would like to incorporate
> the same set of flags.
> 
> Using the following commands, the configuration can be selected in the
> cache:
> 
> if( DEFINED CMAKE_BUILD_TYPE )
> 
> set( CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Options are: Debug
> Release")
> 
> else( DEFINED CMAKE_BUILD_TYPE )
> 
> set(CMAKE_BUILD_TYPE Debug CACHE STRING "Options are: Debug Release")
> 
> endif( DEFINED CMAKE_BUILD_TYPE )
> 
> 
> That works. Next, I tried to update the C_FLAGS :
> 
> 
> set( CMAKE_C_FLAGS_DEBUG "-Wall -Wno-format -g -DDEBUG" CACHE STRING
> "Recommended debug flags." )
> 
> set( CMAKE_C_FLAGS_RELEASE "-Wall -Wno-unknown-pragmas -Wno-format -O3"
> CACHE STRING "Recommended release flags." )
> 
> However running "make edit_cache" always reflects the default
> CMAKE_C_FLAGS_{type}, not the new ones that I supplied. I have tried several
> variations on this theme, but can't make it work. Before posting a bug
> report, I thought I'd post this here in case there is anything obvious that
> I'm missing.
> 
> Incidentally, I'm running CMake version 2.8.4, built by MacPorts.
> 
> Thanks,
> Jerry

The SET(<variable> <value> CACHE <type> <doc>) command doesn't write to
the cache if there's already a cached value for the variable, and some-
times, it even does not set the variable's value in the current scope,
see [1] for more information. You might use the FORCE flag in order to
overwrite the CMAKE_C_FLAGS_<CONFIG> variables' preset values, but this
prevents your users from being able to set these values on the command
line or in the GUI. You may consider to introduce two custom build
types, say, CUSTOMDEBUG and CUSTOMRELEASE, and say:

SET(CMAKE_C_FLAGS_CUSTOMDEBUG "..." CACHE STRING "...")
SET(CMAKE_C_FLAGS_CUSTOMRELEASE "..." CACHE STRING "...")

Since these variables are not preset in the cache, the above-noted
commands probably do what you want. Of course, you should also set
the default build type accordingly. Usually, CMAKE_BUILD_TYPE is
defined *and* cached automatically, see CMakeCInformation.cmake,
so IF(DEFINED CMAKE_BUILD_TYPE) is always true for Makefiles and

SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "...")

is a no-op, AFAICS. If you want to define a default build type in your
CMakeLists.txt in a reliable manner, you should use a project-specific
one, e.g. ${PROJECT_NAME}_BUILD_TYPE which constrains the value of the
CMAKE_BUILD_TYPE variable, i.e.

SET(${PROJECT_NAME}_BUILD_TYPE Debug CACHE STRING "...")
SET(CMAKE_BUILD_TYPE ${${PROJECT_NAME}_BUILD_TYPE}
    CACHE STRING "..." FORCE)
MARK_AS_ADVANCED(CMAKE_BUILD_TYPE)

or SET(CMAKE_NOT_USING_CONFIG_FLAGS TRUE) before the PROJECT() command
and implement the machinery of build types and configuration flags by
yourself, i.e.:

SET(CMAKE_NOT_USING_CONFIG_FLAGS TRUE)
...
PROJECT(...)
...
SET(CMAKE_BUILD_TYPE Debug CACHE STRING "...")
SET(CMAKE_C_FLAGS_DEBUG "..." CACHE STRING "...")
SET(CMAKE_C_FLAGS_RELEASE "..." CACHE STRING "...")

For a project which has two predefined build types and associated sets
of configuration flags, this seems to be an appropriate solution, IMO.

'hope that helps.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg29869.html


More information about the CMake mailing list