Подтвердить что ты не робот

Включает ли set_target_properties в CMake переопределение CMAKE_CXX_FLAGS?

В начале моего проекта CMake я устанавливаю общие флаги компиляции в переменной CMAKE_CXX_FLAGS, например

set(CMAKE_CXX_FLAGS "-W -Wall ${CMAKE_CXX_FLAGS}")

Впоследствии мне нужно добавить дополнительные флаговые компиляции для конфигурации (хранящиеся в BUILD_FLAGS). Могу ли я использовать для этого следующую команду:

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})

или мне нужно добавить CMAKE_CXX_FLAGS вручную:

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BUILD_FLAGS}")

чтобы предотвратить перезапуск CMAKE_CXX_FLAGS с помощью BUILD_FLAGS?

4b9b3361

Ответ 1

Использовать первую:

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})

Флаги, хранящиеся в BUILD_FLAGS, добавляются после CMAKE_CXX_FLAGS при компиляции источников TARGET. Документация подсказывает это, но я просто попробовал это сделать.

COMPILE_FLAGS

   Additional flags to use when compiling this target sources. 

   The COMPILE_FLAGS property sets additional compiler flags used to
   build sources within the target.  Use COMPILE_DEFINITIONS to
   pass additional preprocessor definitions.

Полная командная строка будет эквивалентна:

${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS} -o foo.o -c foo.cc

И как сказал Рамон, вы всегда можете проверить с помощью make VERBOSE=1.

Ответ 2

Принятый ответ все еще работает, но устарел с 2013 года.
Этот ответ основан и на новых функциях из CMake v2.8.12, v3.3 и v3.13.

Начиная с CMake-2.8.12 (2013)

Две новые команды для установки CMAKE_CXX_FLAGS:

Документация последней версии не сильно изменилась со времени cmake-2.8.12:

В вашем случае вы можете использовать:

target_compile_options(${TARGET} PRIVATE ${BUILD_FLAGS})

Или просто, если у вас есть одна цель:

add_compile_options(${BUILD_FLAGS})

Больше примеров

target_compile_options(mylib PRIVATE   -O2) # only internal
target_compile_options(mylib INTERFACE -gl) # only external
target_compile_options(mylib PUBLIC    -g)  # same as PRIVATE + INTERFACE

# multiple targets and flags
target_compile_options(mylib1 mylib2 PRIVATE -Wall -Wextra)

target_compile_options(    mylib PUBLIC -DUSEXX)  # Bad
target_compile_definitions(mylib PUBLIC -DUSEXX)  # OK

add_compile_options(-Wall -Wextra) # for all targets in current directory
add_compile_options(-DUSEXX)       # Bad
add_definitions(-DUSEXX)           # OK

Устаревшие COMPILE_FLAGS

Документация по cmake-3.0 помечает COMPILE_FLAGS как устаревшую:

COMPILE_FLAGS

Дополнительные флаги, которые нужно использовать при компиляции этих источников.

Свойство COMPILE_FLAGS устанавливает дополнительные флаги компилятора, используемые для создания источников внутри цели. Используйте COMPILE_DEFINITIONS чтобы передать дополнительные определения препроцессора.

Это свойство устарело. COMPILE_OPTIONS свойство COMPILE_OPTIONS или команду target_compile_options.

Если вы все еще хотите использовать set_target_properties() вы можете использовать COMPILE_OPTIONS вместо COMPILE_FLAGS:

set_target_properties(${TARGET} PROPERTIES COMPILE_OPTIONS ${BUILD_FLAGS})

Начиная с CMake-3.3 (2015)

Антон Петров предлагает использовать генераторные выражения, представленные в ответе ar31.

Выражения генератора CMake применяют ваш ${BUILD_FLAGS} к:

  • C++ язык с использованием $<COMPILE_LANGUAGE:CXX> (также может быть C, CUDA...)
  • Clang-компилятор с использованием $<CXX_COMPILER_ID:Clang>
    (также может быть GNU для gcc или MSVC для Visual C++... см. полный список)
    (вместо этого используйте $<C_COMPILER_ID:Clang> если язык - C)
  • и многое другое как поддерживаемая функция C++ или версия компилятора... (см. документацию)

В вашем случае вы можете использовать:

target_compile_options(${TARGET} PRIVATE
          $<$<COMPILE_LANGUAGE:CXX>:${BUILD_FLAGS_FOR_CXX}>
          $<$<COMPILE_LANGUAGE:C>:${BUILD_FLAGS_FOR_C}>)

или о компиляторах:

target_compile_options(${TARGET} PRIVATE
          $<$<CXX_COMPILER_ID:Clang>:${BUILD_FLAGS_FOR_CLANG}>
          $<$<CXX_COMPILER_ID:GNU>:${BUILD_FLAGS_FOR_GCC}>
          $<$<CXX_COMPILER_ID:MSVC>:${BUILD_FLAGS_FOR_VISUAL}>)

Начиная с CMake-3.13 (2018)

Новая функция target_link_options() позволяет передавать параметры компоновщику, как упомянул Крейг Скотт.

Различные параметры для файлов C и C++

Лучший способ - различать файлы C и C++, используя две разные цели.