Search code examples
c++visual-studio-2015cmakemulti-configuration

Cmake: Specifiy config specific settings for multi-config cmake project


Cmake novice here, I am currently trying to convert a cmake project that was developed with only single configuration in mind to a multi-config project which can generate visual studio files.

My problem that I can not solve is that in the cmake project there exist logic depending on the variable CMAKE_BUILD_TYPE such as:

set(ENABLE_DEBUG TRUE)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
  set(ENABLE_DEBUG FALSE)
)

Since for multi-config cmake the CMAKE_BUILD_TYPE is empty this way of doing it does not work. The variable ENABLE_DEBUG is then in the cmake project used for stuff such as:

Case 1: Adding libraries to only debug config

if(ENABLE_DEBUG)
  list(APPEND LIB_SRC src/lib_debug.cpp)
endif()
add_library(LIB OBJECT LIB_SRC)

Case 2: Adding preprocessor flags to only debug config

if(ENABLE_DEBUG)
  add_definitions(...)
endif()

So what I wonder is if anyone has a workaround for one or both of the cases above that would work for multi-config cmake projects, i.e so that I can specify library additions and preprocessor flags without depending on the CMAKE_BUILD_TYPE variable. Or even better if there a config specific way of setting the ENABLE_DEBUG without depending on the CMAKE_BUILD_TYPE variable?


Solution

  • In CMake common way for config-specific settings for multi-config build tools is using generator expressions.

    Command add_library allows to use generator expressions for source files. E.g. this:

    add_library(mylib common.c $<$<CONFIG:DEBUG>:debug.c>)
    

    creates a library consisted from common.c in all configuration plus additional debug.c in Debug configuration.

    Documentation for add_definitions doesn't note usage of generator expressions, but documentation for target_compile_definitions does:

    target_compile_definitions(mylib PUBLIC $<$<CONFIG:DEBUG>:-DDEBUG_VAR>)