Reputation: 106609
I've got a CMakeLists where I want to build some targets using the dynamic version of the C runtime, and some other targets using the static version.
Because this needs to be set per target, the default method of setting CMAKE_CXX_FLAGS_<Config>
does not work; this overrides for all targets.
To that end, I tried something like the following:
# @fn set_target_dynamic_crt
# @brief Sets the given target to use the dynamic version of the CRT (/MD or
# /MDd)
# @param ... A list of targets to which this setting should be applied.
function( set_target_dynamic_crt )
if ( MSVC )
message (WARNING ${CMAKE_BUILD_TYPE})
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set_target_properties ( ${ARGN} PROPERTIES COMPILE_FLAGS "/MDd" )
else()
set_target_properties ( ${ARGN} PROPERTIES COMPILE_FLAGS "/MD" )
endif()
endif()
endfunction()
However, this always chooses the release version (/MD
) and when I query for the build type (the message
call above) I get the empty string. (I suspect this is because I'm using the Visual Studio generator; I've seen more than one reference that says CMAKE_BUILD_TYPE
is for makefiles only...)
How can I set compile options like this per target?
Upvotes: 22
Views: 40196
Reputation: 96
Assume that I want to add -On
options to vmovq_n_u8.c and generate vmovq_O3.out and vmovq_O0.out. I had it done with target_compile_options
by following:
add_executable(vmovq_O3.out vmovq_n_u8.c)
add_executable(vmovq_O0.out vmovq_n_u8.c)
target_compile_options(vmovq_O3.out PRIVATE -O3)
target_compile_options(vmovq_O0.out PRIVATE -O0)
Upvotes: 0
Reputation: 11084
In CMake 2.8.12 I added a target_compile_options command to address this need:
http://public.kitware.com/Bug/view.php?id=6493
http://www.cmake.org/cmake/help/git-master/manual/cmake-generator-expressions.7.html
target_compile_options(tgt PRIVATE "/MD$<$<CONFIG:Debug>:d>")
See
for more relating to CMAKE_BUILD_TYPE and several reasons why the generator expression is better (eg IMPORTED target config mapping).
Upvotes: 41
Reputation: 78458
The only option I know of for this scenario is to split your project into subdirectories on a per-target basis and use add_subdirectory
.
Depending on how your project is currently set up, this could be a painful process I guess.
The result would be a top-level CMakeLists.txt that looked like e.g.
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)
add_subdirectory(libB)
add_subdirectory(libA)
add_executable(main_exe "main.cpp")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
target_link_libraries(main_exe lib_a lib_b)
then libA/CMakeLists.txt
could specify MD
and MDd
flags:
project(LibA)
add_library(lib_a a.cpp a.hpp)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
and libB/CMakeLists.txt
for MT
and MTd
flags:
project(LibB)
add_library(lib_b b.cpp b.hpp)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
You can of course add all targets needing linked to the static CRT in the one subdirectory and CMakeLists.txt and all the dynamic CRT ones in the other if you have a lot of targets.
Upvotes: 2
Reputation: 721
CMAKE_BUILD_TYPE
is only valid for single-configuration generators. The multi-configuration generators (MSVC and Xcode) can build for multiple configurations in one build-directory and as such the CMAKE_BUILD_TYPE
flag wouldn't have a meaning.
The COMPILE_FLAGS target property does not distinguish different configurations (See kitware bugtracker for more information).
A workaround would be to have two build-directories, similar to how people use the Makefile generators, and define an additional flag when building binaries for distribution. (ie, the Release configuration)
Upvotes: 0