1

I want to generate a Visual Studio project with two configurations using cmake. I want cmake to define different preprocessor symbols for these configurations.

I generate the project with the following command

cmake -B intermediate/cmake -G "Visual Studio 16 2019" -T v142 -DCMAKE_GENERATOR_PLATFORM=x64

In my CMakeLists.txt I define configurations:

if(CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_CONFIGURATION_TYPES Debug Release)
endif()

Now, how do I define the preprocessor definitions per configuration? The quick search advises against using if(CMAKE_BUILD_TYPE STREQUAL "Release") because it doesn't work for multiconfiguration generators.

2
  • It's not clear what you mean by "macros". Are you looking to define different configuration-time CMake macros (e.g. functions without scope)? Or are you looking to conditionally define C++ preprocessor symbols based on the CMake configuration? Can you please clarify? Commented Aug 29, 2021 at 2:49
  • @Human-Compiler I've just updated the question, thx Commented Aug 29, 2021 at 3:08

1 Answer 1

1

The conventional way to handle configuration-specific details in a multi-configuration generator is through the use of generator expressions.

Generator expressions allow you to specify symbols, values, flags, etc that will only be expanded at generation time based on the current state of the generator (such as the current build configuration).

For example, you can define custom pre-processor definitions with the -D flag with target_compile_definitions:

target_compile_definitions(MyTarget PRIVATE
  $<$<CONFIG:Debug>:DEBUG_ONLY=1>
  $<$<CONFIG:Release>:RELEASE_ONLY=2>
  FOO=3
)

(This example is for PRIVATE definitions. Replace this with PUBLIC or INTERFACE as needed.)

This adds -DDEBUG_ONLY=1 to MyTarget for Debug builds, -DRELEASE_ONLY=2 for Release builds, and -DFOO=3 for all builds.


Also see this relevant/similar question: Cmake: Specifiy config specific settings for multi-config cmake project

Sign up to request clarification or add additional context in comments.

2 Comments

This works but the syntax is different. There should be <INTERFACE|PUBLIC|PRIVATE> after target and colons instead of commas. So target_compile_definitions(MyTarget PRIVATE $<$<CONFIG:Debug>:DEBUG_ONLY=1> $<$<CONFIG:Release>:RELEASE_ONLY=2> FOO=3) works
@KirillDaybov Ah, my apologies -- I was working from memory when I wrote this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.