Визначити макрос препроцесора через 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.