Для современного CMake (версии 2.8.12 и выше) вы должны использовать target_compile_options, который внутренне использует целевые свойства.
CMAKE_<LANG>_FLAGS- это глобальная переменная, которая наиболее подвержена ошибкам в использовании. Он также не поддерживает выражения генератора , что может очень пригодиться.
add_compile_options основан на свойствах каталога, что в некоторых случаях нормально, но обычно не самый естественный способ указания параметров.
target_compile_optionsработает для каждой цели (путем установки свойств COMPILE_OPTIONSи INTERFACE_COMPILE_OPTIONStarget), что обычно приводит к наиболее чистому коду 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}>")
В PUBLIC, PRIVATEи INTERFACEключевые слова определяют сферу вариантов . Например, если мы ссылаемся fooна barс target_link_libraries(bar foo):
PRIVATEпараметры будут применяться только к самой цели ( foo), а не к другим библиотекам (потребителям), связывающимся с ней.
INTERFACE параметры будут применяться только к целевой цели bar
PUBLICпараметры будут применены как к исходной цели, так fooи к целевой целиbar