Визначити макрос препроцесора через CMake?


283

Як визначити змінну препроцесора через CMake?

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

Відповіді:


382

Довгий час 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

Так само ви можете робити це за ціль, як пояснено у відповіді Джима Ханзікера.


4
На пов'язаній сторінці: "Примітка. Ця команда була замінена альтернативами: Використовуйте add_compile_definitions () для додавання визначень препроцесора." Можливо, ця відповідь потребує редагування?
М.Герцкамп

9
У 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(....)

4
Відповідно до документації , це рішення насправді є старішим, більш старовинним підходом. Інші відповіді пропонують більш сучасні рішення.
squareskittles

2
Коли я написав відповідь, я спробував інше рішення, але жодне з них не працювало.
Леос313

@squareskittles, будь-яка ідея, чому рішення іншої відповіді не працює належним чином? CMake видає помилки, якщо я спробую їх
Leos313

1
Якщо ви використовуєте CMake 3.3.2, як ви вказали у своїй відповіді, ви повинні використовувати add_definitions()або target_compile_definitions(). Більш сучасна команда, add_compile_definitions()не була додана до CMake 3.12. @ Leos313
squareskittles

1
@squareskittles, я оновлюю відповідь, переписуючи те, що я написав кілька вершин тому. Дякую, що вказали на це
Leos313
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.