[CMake] How to set a preprocessor define for all build configurations except one ?

Michael Hertling mhertling at online.de
Thu Jun 16 10:45:52 EDT 2011


On 06/16/2011 03:18 PM, Glenn Coombs wrote:
> On 13 June 2011 02:53, Michael Hertling <mhertling at online.de> wrote:
> 
>>
>> 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()
>>
> 
> I wasn't aware of that syntax of the foreach command - that does tidy it up
> a bit.
> 
> 
>> 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.
>>
> 
> I'm not overly keen on that solution.
> 
> 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.
>>
> 
> The default is to generate outfiles and the code is littered with blocks
> like this:
> 
> #ifdef GEN_OUTFILES
> ...
> #endif
> 
> Changing them to #ifndef NO_GEN_OUTFILES would work but the double negative
> makes the code less readable.  I'll stick with what I already have for the
> moment, but add your modification to the foreach loop.

IMO, the default should not need to be explicitly enabled but the
exception, and readability - though important - is subordinate to
functionality, but probably, this is a matter of personal taste.

However, if you stick with the GEN_OUTFILES definition, be aware of
the single-config generator with an empty build type. In that case,
only the COMPILE_DEFINITIONS property is in effect, so you must add
the GEN_OUTFILES definition to it, but with a non-empty build type,
this config-less property is in effect, too, so you must *not* add
GEN_OUTFILE to it. Thus, you need to differentiate these cases:

IF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
    FOREACH(... IN LISTS ... ITEMS ...)
        # Set COMPILE_DEFINITIONS_<CONFIG>.
    ENDFOREACH()
ELSE()
    # Set COMPILE_DEFINITIONS.
ENDIF()

Clearly, this cuts down the elegance of the FOREACH loop, while the
inverted approach with NO_GEN_OUTFILES would be unalteredly smooth.

Regards,

Michael


More information about the CMake mailing list