Определить макрос препроцессора через CMake?

283

Как определить переменную препроцессора через CMake?

Эквивалентный код будет #define foo.

Mythli
источник

Ответы:

383

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

Пример использования нового add_compile_definitions :

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)

Или:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

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

Дополнительную информацию о том, какие команды использовать для флагов компилятора, можно найти здесь: https://cmake.org/cmake/help/latest/command/add_definitions.html.

Точно так же вы можете сделать это для каждой цели, как объяснено в ответе Джима Ханзикера.

ypnos
источник
4
На связанной странице: «Примечание. Эта команда была заменена альтернативами: используйте add_compile_definitions () для добавления определений препроцессора». Может быть, этот ответ нуждается в редактировании?
М.Херцкамп,
10
В cmake 3.10.2 add_compile_definitionsкидает CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. Пришлось использовать add_compile_options(-D <your-def>)вместо.
code_dredd
2
@mannyglover Я так не думаю, но вы можете установить флаги компилятора с -D, что-то вроде cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(не проверено)
ypnos
1
Это действительно новый ... на самом деле это более современный CMake (> 3.11). Боль, которую так трудно понять, когда была введена команда.
Сандбург
1
@Sandburg Вы можете открыть ссылку на последнюю документацию: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsи начать менять номер версии вниз, пока страница не исчезнет. Это будет версия, где она еще не существует. В следующем шаге вы можете перейти в Whats newраздел, чтобы найти новую команду или функцию. Так что это не так сложно.
Андри
245

Чтобы сделать это для конкретной цели, вы можете сделать следующее:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Это следует делать, если у вас есть более одной цели, которую вы строите, и вы не хотите, чтобы все они использовали одни и те же флаги. Также см. Официальную документацию по target_compile_definitions .

Джим Хунзикер
источник
1
@JimHunziker Чем target_compile_definitions(my_target PRIVATE FOO=1)отличается от set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
Джон Строуд
1
@JohnStrood Разница на уровне области. target_compile_definitionsзадает значение для исполняемого файла / библиотеки WHOLE, где значение 'set_source_files_properties` устанавливает значение только для указанного файла. Команда Latter позволяет файлам компилироваться на другом языке; то есть: set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Обратите внимание, что -x objective-cздесь есть флаг, специфичный для GCC / Clang.
Джулиан Кирш
20

Другое решение, предлагаемое на этой странице, полезно для некоторых версий Cmake <3.3.2 . Здесь решение для версии, которую я использую (т.е. 3.3.2). Проверьте версию своего Cmake с помощью $ cmake --versionи выберите решение, которое соответствует вашим потребностям. Документацию по cmake можно найти на официальной странице.

С CMake версии 3.3.2, чтобы создать

#define foo

Мне нужно было использовать:

add_definitions(-Dfoo)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

и, чтобы иметь определение макроса препроцессора, подобное этому:

#define foo=5

строка так изменена:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
Leos313
источник
4
Согласно документации , это решение на самом деле является более старым, более устаревшим подходом. Другие ответы предлагают более современные решения.
квадратные названия
2
Когда я написал ответ, я попробовал другое решение, но ни один из них не работал.
Leos313
@squareskittles, есть идеи, почему решение другого ответа не сработало? CMake
выдает
1
Если вы используете CMake 3.3.2, как вы указали в своем ответе, вы должны использовать add_definitions()или target_compile_definitions(). Более современная команда add_compile_definitions()не была добавлена ​​до CMake 3.12. @ Leos313
squareskittles
1
@squareskittles, я обновляю ответ, переписываю то, что написал несколько месяцев назад. Спасибо за указание на это
Leos313