CMAKE - установка флагов компиляции для библиотек

У меня есть сценарий CMakeLists.txt для компиляции моих библиотек. Проблема в том, что я не могу установить флаги компиляции для библиотек.

я пробовал

SET(CMAKE_CXX_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_CXX_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_C_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_C_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_EXE_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_MODULE_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_SHARED_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_STATIC_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_STATIC_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")

Ни один из них не имеет эффекта...

Единственный способ изменить флаги для библиотеки - это так.

SET_TARGET_PROPERTIES(MyLib PROPERTIES COMPILE_FLAGS "/W3 /nologo /EHsc")

и это изменит флаги для Debug и Release

Как в мире я могу установить флаги Release и Debug отдельно для библиотеки, использующей CMake?

1 ответ

Решение

Это глобально кэшированные переменные, которые вы пытаетесь перезаписать при первом подходе.

Для локального изменения этих параметров компилятора / компоновщика вам нужны специфичные для конфигурации свойства цели или выражения генератора. Итак, ваш второй подход и Как я могу установить конкретные флаги компилятора для конкретной цели в конкретной конфигурации сборки с использованием CMake? Я бы получил:

target_compile_options(
    MyLib PRIVATE 
    "/W3 /nologo /EHsc"
    "$<$<CONFIG:Debug>:/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG>"
    "$<$<CONFIG:Release>:/MT /O2 /Ob2 /DNDEBUG>"
)

или для версий CMake <= 2.8.12 (см. также политику CMP0043):

set_target_properties(
    MyLib PROPERTIES 
        COMPILE_FLAGS 
            "/W4 /nologo /EHsc"
        COMPILE_FLAGS_DEBUG
            "/MTd /Od /Ob0 /Zi /RTC1"
        COMPILE_FLAGS_RELEASE
            "/MT /O2 /Ob2"
        COMPILE_DEFINITIONS_DEBUG
            "DEBUG;_DEBUG"
        COMPILE_DEFINITIONS_RELEASE
            "NDEBUG"
)

Мне лично нравится "старый" способ сделать это лучше, потому что он заменяет параметры по умолчанию в свойствах проекта Visual Studio. Что бы ни проходило через target_compile_options() в конечном итоге в Configuration Properties / C/C++ / Command Line / Additional Options,

Некоторая справочная информация, почему ваш первый подход не сработал:

Генератор CMake принимает все, что установлено для CMAKE_<LANG>_FLAGS в конце любого CMakeLists.txt файл и применяет его ко всем библиотекам и исполняемым целям в том же CMakeLists.txt файл в качестве параметров компилятора по умолчанию при создании среды сборки.

Если вы установите переменные компоновщика для вас основной CMakeLists.txt цели в подкаталогах CMakeLists.txt это не поможет (неправильный объем). Если я возьму ваш код в основной CMakeLists.txt это работает, и я получаю следующие предупреждения (потому что вы использовали параметры компилятора для компоновщика):

1>LINK : warning LNK4044: unrecognized option '/W3'; ignored
1>LINK : warning LNK4044: unrecognized option '/EHsc'; ignored
1>LINK : warning LNK4044: unrecognized option '/MTd'; ignored
1>LINK : warning LNK4044: unrecognized option '/Od'; ignored
1>LINK : warning LNK4044: unrecognized option '/Ob0'; ignored
1>LINK : warning LNK4044: unrecognized option '/Zi'; ignored
1>LINK : warning LNK4044: unrecognized option '/RTC1'; ignored
1>LINK : warning LNK4044: unrecognized option '/DDEBUG'; ignored
1>LINK : warning LNK4044: unrecognized option '/D_DEBUG'; ignored

Сейчас я скрываю кэшированные переменные с тем же именем, которые были установлены CMake во время обнаружения компилятора. Для более подробной информации смотрите:

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