Общая тенденция в современном CMake - перейти от глобальных настроек к настройкам, ориентированным на цель. Исходя только из этого правила, target_compile_definitions()
- самый современный подход. Это также позволяет контролировать, используются ли настройки только в цели (PRIVATE
), в других целях, использующих эту цель (INTERFACE
), или в обеих (PUBLIC
). Внутренне это работает, изменяя свойства цели COMPILE_DEFINITIONS
и INTERFACE_COMPILE_DEFINITIONS
.
Следующим по уровню современности является add_compile_definitions()
. Он добавляет определения макросов ко всем целям, определенным в текущем каталоге и подкаталогах; в этом отношении его объем аналогичен include_directories()
. Внутренне это работает путем изменения свойства COMPILE_DEFINITIONS
текущего каталога. Итак: он по-прежнему использует правильные «современные» механизмы, но ориентирован на каталог, а не на целевой.
В нижней части списка у нас есть очень старая функция add_definitions()
. Это действительно лучше избегать в современном CMake. Хотя он предназначен для указания определений препроцессора (отсюда и его имя), он на самом деле позволяет передавать произвольные параметры компилятора (именно поэтому вам необходимо указать -DFOO
вместо просто FOO
в качестве аргумента). Он пытается выяснить, являются ли передаваемые вещи на самом деле определениями макросов препроцессора, и в этом случае они перемещаются в свойство каталога COMPILE_DEFINTIIONS
. Если они не определены как таковые (что может произойти для макросов со сложными замещающими строками), они остаются в списке флагов.