yrHeTateJlb
yrHeTateJlb

Reputation: 477

CMake. How to generate Visual Studo solution with different libary types?

There is CMake script for C++ project with following content:

#...

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug_static")
    add_library(${PROJECT_NAME} STATIC ${SRC_FILES} ${HEADERS_FILES})
endif()

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    add_library(${PROJECT_NAME} SHARED ${SRC_FILES} ${HEADERS_FILES})
endif()

if(${CMAKE_BUILD_TYPE} STREQUAL "Release_static")
    add_library(${PROJECT_NAME} STATIC ${SRC_FILES} ${HEADERS_FILES})
endif()

if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
    add_library(${PROJECT_NAME} SHARED ${SRC_FILES} ${HEADERS_FILES})
endif()

#...

Library type depends on build type. When I build project with CMake everything is ok, but i can't generate equivalent VS solution.

cmake -G "Visual Studio 15 2017 Win64"

I run CMake without CMAKE_BUILD_TYPE => all if-s is FALSE => no target - no soution.

When I set CMAKE_BUILD_TYPE

cmake -DCMAKE_BUILD_TYPE=Debug_static -G "Visual Studio 15 2017 Win64"

all 4 configurations will be like Debug_static. I think for this case generator-expressions was invented, but add_library doesn't support them for library type.

So, my question is: How to change my CMake script to make VS generator able to generate equivalent solution? 4 configurations: 2 shared and 2 static.

Upvotes: 1

Views: 845

Answers (1)

ptrlukas
ptrlukas

Reputation: 346

According to CMAKE_BUILD_TYPE documentation :

This variable is only meaningful to single-configuration generators...

To add customize configurations for multi-configuration generator you have to set CMAKE_CONFIGURATION_TYPES.

set(CMAKE_CONFIGURATION_TYPES Release Debug Release_static Debug_static)

Then for each new configuration type (Release_static and Debug_static) set the compiler and linker variables needed for your project.

set(CMAKE_CXX_FLAGS_RELEASE_STATIC ${CMAKE_CXX_FLAGS_RELEASE})
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE_STATIC ${CMAKE_SHARED_LINKER_FLAGS_RELEASE})
...
set(CMAKE_CXX_FLAGS_DEBUG_STATIC ${CMAKE_CXX_FLAGS_DEBUG})
...

As far as I know it is not possible to add single-configuration target for multi-configuration generator output. So just add separate targets for shared and static libraries.

To avoid building both libraries for any configuration set EXCLUDE_FROM_DEFAULT_BUILD_CONFIG properties.

add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES
    EXCLUDE_FROM_DEFAULT_BUILD_RELEASE_STATIC TRUE
    EXCLUDE_FROM_DEFAULT_BUILD_DEBUG_STATIC TRUE)

add_library(${PROJECT_NAME}_static STATIC ${SRC_FILES})
set_target_properties(${PROJECT_NAME}_static PROPERTIES
    EXCLUDE_FROM_DEFAULT_BUILD_RELEASE TRUE
    EXCLUDE_FROM_DEFAULT_BUILD_DEBUG TRUE)

Building solution will compile only library matching active configuration.

Use OUTPUT_NAME to make ${PROJECT_NAME}_static target produce ${PROJECT_NAME}.lib at output.

I hope it's close enough to your scenario.

Upvotes: 1

Related Questions