Как я могу установить определенные флаги компилятора для конкретной цели в конкретной конфигурации сборки, используя CMake?
У меня есть CMakeLists, где я хочу построить некоторые цели, используя динамическую версию среды выполнения C, а некоторые другие цели, используя статическую версию.
Поскольку это должно быть установлено для цели, метод установки по умолчанию CMAKE_CXX_FLAGS_<Config>
не работает; это переопределяет для всех целей.
Для этого я попробовал что-то вроде следующего:
# @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()
Тем не менее, это всегда выбирает версию выпуска (/MD
) и когда я запрашиваю тип сборки (message
позвони выше) получаю пустую строку. (Я подозреваю, что это потому, что я использую генератор Visual Studio; я видел более одной ссылки, которая говорит CMAKE_BUILD_TYPE
только для make-файлов...)
Как я могу установить такие параметры компиляции для каждой цели?
3 ответа
В CMake 2.8.12 я добавил команду target_compile_options для решения этой задачи:
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>")
Увидеть
http://www.cmake.org/cmake/help/git-next/manual/cmake-buildsystem.7.html
для получения дополнительной информации о CMAKE_BUILD_TYPE и нескольких причинах, почему выражение генератора лучше (например, IMPORTED сопоставление конфигурации цели).
Единственная известная мне опция для этого сценария - разделить ваш проект на подкаталоги для каждой цели и использовать add_subdirectory
,
В зависимости от того, как ваш проект настроен в настоящий момент, я думаю, это может быть болезненным процессом.
Результатом будет CMakeLists.txt верхнего уровня, который выглядит, например, как
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)
затем libA/CMakeLists.txt
мог бы указать MD
а также MDd
флаги:
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")
а также libB/CMakeLists.txt
за MT
а также MTd
флаги:
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")
Конечно, вы можете добавить все цели, связанные со статическим CRT, в одном подкаталоге и CMakeLists.txt и все динамические CRT в другом, если у вас много целей.
CMAKE_BUILD_TYPE
действительно только для генераторов с одной конфигурацией. Многоконфигурационные генераторы (MSVC и Xcode) могут создавать несколько конфигураций в одном каталоге сборки и, таким образом, CMAKE_BUILD_TYPE
флаг не будет иметь смысла.
Свойство target COMPILE_FLAGS не различает различные конфигурации (для получения дополнительной информации см. Bugtracker kitware).
Обходной путь должен состоять в том, чтобы иметь две директории сборки, аналогично тому, как люди используют генераторы Makefile, и определять дополнительный флаг при сборке двоичных файлов для распространения. (т. е. конфигурация выпуска)
Предположим, я хочу добавить -On
параметры для vmovq_n_u8.c и сгенерировать vmovq_O3.out и vmovq_O0.out. Я сделал это сtarget_compile_options
следующим образом:
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)