cmake - настройка глобального флага компоновщика (для всех целей в каталоге)
Я хочу передать флаги компоновщика всем подпроектам (подкаталог CMakeList) в моем проекте.
Перед переключением на новый cmake 3.3 я использовал следующий код (cmake 3.2), который работал хорошо, добавив флаги для компиляции и компоновки:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -stdlibc++")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -stdlibc++")
С cmake 3.3 это больше не работает и устанавливает флаги только для шага компиляции. Я обновил CMakeList, чтобы использовать более "современный" синтаксис cmake:
set(MY_DEBUG_OPTIONS -g -stdlib=libstdc++ -Wfatal-errors)
set(MY_RELEASE_OPTIONS -O3 -stdlib=libstdc++ -Wfatal-errors)
add_compile_options(
"$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>"
"$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
Этот набор флагов компиляции для всех подпроектов, есть ли подобный способ сделать это для флагов компоновщика? Я знаю, что можно добавить флаги компоновщика на целевой основе с target_link_libraries
команда, но больше ничего не могу найти.
Я пытался с помощью CMAKE_SHARED_LINKER_FLAGS
(и соответствующая переменная для exe, module,..) переменная без успеха.
Обновить:
Оказывается, это не имеет ничего общего с версией cmake, все работает правильно CMAKE_CXX_FLAGS_XXX
переменные, кроме первой команды make. Если один прогон make
во второй раз (с модификацией в CmakeList) присутствуют флаги.
Я думаю, что нашел решение во время тестирования с простым CMakeList: если флаги объявлены после project
Команда это просто работает, как ожидалось. Я не знаю, является ли это требованием самого cmake или просто странным поведением.
cmake_minimum_required (VERSION 3.2)
set(PROJECT Test_Project)
# Not working (on first run)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -stdlib=libstdc++ -Wfatal-errors")
project(${PROJECT})
# Declare here instead...
add_executable(Test test.cpp)
MESSAGE( STATUS "Config flags : " ${CMAKE_CXX_FLAGS_RELEASE})
С помощью:
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
1 ответ
Ваши проблемы не связаны с конкретной версией CMake.
Это одинаково для всех переменных флагов компоновщика / компилятора в CMake. Потому что эти переменные являются кэшированными переменными и устанавливаются с project()
/ enable_language()
команда (подробности см. здесь), вы должны
- предварительно заполнить кэш
set(... CACHE ...)
передproject()
команда - обычно используют
set(... CACHE ... FORCE)
заставить / переписать - переместить
set()
послеproject()
команда, чтобы скрыть или добавить к кэшированным переменным
Вот пример для CMAKE_EXE_LINKER_FLAGS
показывая все три варианта:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# 1. prefill
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "")
project(Test_Project CXX)
# 2. force
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)
# 3. hide
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map")
# 3. or append
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=output.map")
# TODO: Remove, this is just for testing
file(WRITE "foo.cpp" "int main() {}")
add_executable(${PROJECT_NAME} foo.cpp)
Какими бы ни были значения этих переменных в конце любого CMakeLists.txt
файл будет применен ко всем соответствующим целям в том же CMakeLists.txt
файл как значения по умолчанию (см. CMAKE - установка флагов компиляции для библиотек и каков синтаксис CMake для установки и использования переменных?).
Первый вариант имеет тот недостаток, что на самом деле это только начальное значение. Второй и третий вариант, скорее всего, потребуется if (CMAKE_COMPILER_IS_GNUCXX)
вокруг, поэтому я предпочитаю второй вариант с перемещением этих настроек в собственный файл начального кэша:
MyGNUSettings.cmake
set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -Wfatal-errors" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)
Используя, например,
cmake -G "Unix Makefiles" -C MyGNUSettings.cmake -DCMAKE_BUILD_TYPE=Release .
И да - для глобальных настроек и параметров компилятора - я предпочитаю глобальные кэшированные переменные add_compile_options()
команда. Я думаю add_compile_options()
не заменил глобальные переменные, он был в основном введен, чтобы люди не помещали опции компилятора в add_definitions()
команды.