CMake conditional for Release,Debug and Etc

Viewed 1001

I am working on a CMake project that need to set specific paths for each configuration type (e.g., RELEASE, DEBUG, MINSIZEREL and RELWITHDEBINFO) for a static library in linking process. Because I have different versions of my static libraries that is used on Debug and Release versions.

So far, I have done this below in order to set the folder "release" or "debug" for my static library that I am try to link:

# Here we need to determine our build type and set the each one specific 3rd library for our binary
if( CMAKE_BUILD_TYPE STREQUAL "Debug")
    #set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install)
    #message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
    set(THIRDLIBS_BUILD_TYPE "debug")

elseif( CMAKE_BUILD_TYPE STREQUAL "Release")
    #SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
    #message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
    set(THIRDLIBS_BUILD_TYPE "release")

elseif( CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
    #SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
    #message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
    set(THIRDLIBS_BUILD_TYPE "debug")

elseif( CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
    #SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
    #message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
    set(THIRDLIBS_BUILD_TYPE "release")

else()
    MESSAGE( STATUS "CMAKE_BUILD_TYPE not set yet ${CMAKE_BUILD_TYPE}" )
endif()

if (WIN32)
    set(THIRD_LIBS
        ../external_libs/mylibalpha/win64/${THIRDLIBS_BUILD_TYPE}/libalpha
        ../external_libs/mylibbeta/win64/${THIRDLIBS_BUILD_TYPE}/libbeta
    )
endif(WIN32)

However, in my Visual Studio, I noticed that on each project build type (RELEASE, DEBUG, MINSIZEREL and RELWITHDEBINFO) the ${THIRDLIBS_BUILD_TYPE} variable is empty and not getting properly set. I am basically getting an error on linking showing that cannot find the external_libs/mylibalpha/win64//libalpha.lib and I should be getting something like this external_libs/mylibalpha/win64/release/libalpha.lib

What is wrong with my CMakeLists.txt script?

1 Answers

Variable CMAKE_BUILD_TYPE has no sense with multiconfiguration generators, and Visual Studio is one of such generators.

Canonical way for define in CMake a pre-built library which have different locations for different configuration is to create IMPORTED library target with several properties IMPORTED_LOCATION_<CONFIG> to be set:

add_library(thirdPartyLib IMPORTED UNKNOWN)
set_target_properties(thirdPartyLib PROPERTIES
  IMPORTED_LOCATION_RELEASE
    ${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/release/libalpha.a
  IMPORTED_LOCATION_DEBUG
    ${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/debug/libalpha.a
)

Then you need to create a mapping between build types of the main project and build types of the IMPORTED target.

Such mapping could be created either on per-target basis, by setting properties MAP_IMPORTED_CONFIG_<CONFIG>:

set_target_properties(thirdPartyLib PROPERTIES
  # For Debug version of the project use DEBUG-suffixed library location
  MAP_IMPORTED_CONFIG_DEBUG DEBUG
  # For Release version of the project use RELEASE-suffixed library location
  MAP_IMPORTED_CONFIG_RELEASE RELEASE
  # For ReleaseWithDebInfo version of the project use DEBUG-suffixed library location
  MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG
  # For MinSizeRel version of the project use RELEASE-suffixed library location
  MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
)

Alternatively, the mapping could be created for all IMPORTED targets by setting variables CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>. Note, that these variables should be set before creation of IMPORTED target(s).

# For Debug version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG DEBUG)
# For Release version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE RELEASE)
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG)
# For MinSizeRel version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE)

Having IMPORTED libraries and configurations mapping, using these libraries is quite straightforward:

target_link_libraries(my_exe PRIVATE thirdPartyLib)

Depending on the build type of the project, CMake will automatically select proper library for linking.

Related