Каков современный метод установки общих флагов компиляции в CMake?

Существует несколько механизмов, предлагаемых CMake для получения флагов компилятору:

Есть ли один метод, который предпочтительнее другого в современном использовании? Если да, то почему? Кроме того, как этот метод можно использовать с несколькими конфигурационными системами, такими как MSVC?

Ответ 1

Для современного CMake (версии 2.8.12 и выше) вы должны использовать target_compile_options, который использует целевые свойства внутри.

CMAKE_<LANG>_FLAGS - глобальная переменная и наиболее подверженная ошибкам в использовании. Он также не поддерживает генераторные выражения, которые могут пригодиться.

add_compile_options основан на свойствах каталогов, что хорошо в некоторых ситуациях, но обычно это не самый естественный способ указать параметры.

target_compile_options работает на основе каждой цели (путем установки COMPILE_OPTIONS и INTERFACE_COMPILE_OPTIONS целевые свойства), что обычно приводит к чистому CMake-коду, поскольку параметры компиляции для исходного файла определяются тем, к какому проекту принадлежит файл (а не к каталогу, в котором он размещен на жестком диске). Это имеет дополнительное преимущество в том, что автоматически позаботится о передаче опций для зависимых целей по запросу.

Несмотря на то, что они немного более подробные, команды на целевую группу допускают достаточно тонкий контроль над различными вариантами построения и (в моем личном опыте) наименее вероятны, чтобы вызвать головные боли в долгосрочной перспективе.

В теории вы также можете напрямую установить соответствующие свойства с помощью set_target_properties, но target_compile_options обычно более читабельна.

Например, чтобы задать параметры компиляции целевого foo на основе конфигурации с использованием выражений генератора, вы можете написать:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")