[CMake] How to set a preprocessor define for all build configurations except one ?
Michael Hertling
mhertling at online.de
Sun Jun 12 21:53:08 EDT 2011
On 06/07/2011 07:05 PM, Glenn Coombs wrote:
> I want to have a preprocessor symbol (GEN_OUTFILES) defined for all build
> configurations except one (ReleaseNoOutfiles). Before I added the
> ReleaseNoOutfiles configuration I just had this line in my top level
> CMakeLists.txt:
>
> add_definitions(-DGEN_OUTFILES)
>
> but now I have to have this complicated mess instead:
>
> # Add preprocessor definition for GEN_OUTFILES to all project configurations
> except ReleaseNoOutfiles
> if (CMAKE_CONFIGURATION_TYPES)
> string(TOUPPER "${CMAKE_CONFIGURATION_TYPES}"
> CMAKE_CONFIGURATION_TYPES_UPPER)
> else()
> string(TOUPPER "${CMAKE_BUILD_TYPE}"
> CMAKE_CONFIGURATION_TYPES_UPPER)
> endif()
>
> foreach(config ${CMAKE_CONFIGURATION_TYPES_UPPER})
> if (NOT (${config} MATCHES "RELEASENOOUTFILES"))
> set_property(DIRECTORY APPEND PROPERTY
> COMPILE_DEFINITIONS_${config} GEN_OUTFILES)
> endif()
> endforeach()
>
> Is there a more elegant solution that I am missing ? Ideally something
> like:
>
> add_definitions(CONFIG=Debug;Release;RelWithDebInfo;MinSizeRel
> -DGEN_OUTFILES)
>
> which I know doesn't exist but I really wish it did :-)
AFAIK, there's no other approach to take account of single- and multi-
config generators at the same time for this purpose, but perhaps, you
could design the loop a bit smarter:
FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES ITEMS ${CMAKE_BUILD_TYPE})
STRING(TOUPPER ${i} j)
IF(NOT j MATCHES "RELEASENOOUTFILES")
SET_PROPERTY(...)
ENDIF()
ENDFOREACH()
Since CMAKE_CONFIGURATION_TYPES and CMAKE_BUILD_TYPE are mutually
exclusive and an empty list/item doesn't cause an iteration, this
should work as expected.
Alternatively, you might use
SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS GEN_OUTFILES)
SET(CMAKE_C_FLAGS_RELEASENOOUTFILES -UGEN_OUTFILES)
and rely on the assumption that
(1) the FLAGS are mentioned after the COMPILE_DEFINITIONS, and
(2) the last -D/-U argument in the command line will take effect.
At least, GCC guarantees that (2) holds, but I have not found any
explicit assertion in the documentation that CMake guarantees (1),
though it seems to work in this way.
BTW, is an "inverted" logic an option, i.e. a preprocessor definition
NO_GEN_OUTFILES enabled for the RELEASENOOUTFILES configuration only?
This would be much easier and fit that configuration's intent better.
Regards,
Michael
> Initially I didn't have the if (CMAKE_CONFIGURATION_TYPES) check and it
> didn't work on linux. Why is CMAKE_CONFIGURATION_TYPES empty for linux
> targets ? I know that multiple build configs are not supported in the same
> tree like they are under Visual Studio but you can configure multiple build
> directories with CMAKE_BUILD_TYPE set to each value in
> CMAKE_CONFIGURATION_TYPES. The code in CMakeLists.txt files would be more
> platform agnostic and easier to read if one could iterate over
> CMAKE_CONFIGURATION_TYPES on linux to set configuration specific variables
> like COMPILE_DEFINITIONS_XXX.
>
> --
> Glenn
More information about the CMake
mailing list