Как я могу установить определенные флаги компилятора для конкретной цели в конкретной конфигурации сборки, используя 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)

Другие вопросы по тегам