Reputation: 477
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
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