Präprozessor-Makro über CMake definieren?

283

Wie definiere ich eine Präprozessorvariable über CMake?

Der entsprechende Code wäre #define foo.

Mythli
quelle

Antworten:

382

CMake hatte lange Zeit den add_definitionsBefehl zu diesem Zweck. In letzter Zeit wurde der Befehl jedoch durch einen differenzierteren Ansatz ersetzt (separate Befehle zum Kompilieren von Definitionen, Include-Verzeichnisse und Compiler-Optionen).

Ein Beispiel mit den neuen add_compile_definitions :

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

Oder:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

Das Gute daran ist, dass es die schäbigen Tricks umgeht, für die CMake eingesetzt hat add_definitions. CMake ist so ein schäbiges System, aber sie finden endlich etwas Vernunft.

Weitere Erläuterungen zu den für Compiler-Flags zu verwendenden Befehlen finden Sie hier: https://cmake.org/cmake/help/latest/command/add_definitions.html

Ebenso können Sie dies pro Ziel tun, wie in der Antwort von Jim Hunziker erläutert.

ypnos
quelle
4
Auf der verlinkten Seite: "Hinweis Dieser Befehl wurde durch Alternativen ersetzt: Verwenden Sie add_compile_definitions (), um Präprozessordefinitionen hinzuzufügen." Vielleicht muss diese Antwort bearbeitet werden?
M.Herzkamp
9
In cmake 3.10.2 add_compile_definitionswirft CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. Musste add_compile_options(-D <your-def>)stattdessen verwenden.
code_dredd
2
@mannyglover Ich glaube nicht, aber Sie können die Compiler-Flags mit -D setzen, etwas in der Art von cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(nicht getestet)
ypnos
1
Es ist wirklich neu ... tatsächlich ist es in More Modern CMake (> 3.11). Ein Schmerz, den man nur schwer erkennen kann, wenn ein Befehl eingeführt wurde.
Sandburg
1
@ Sandburg Sie können den Link zur letzten Dokumentation öffnen: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsund die Versionsnummer nach unten ändern, bis die Seite verschwindet. Das wäre die Version, in der es noch nicht existiert. Im nächsten Schritt können Sie zum Whats newAbschnitt gehen, um einen neuen Befehl oder eine neue Funktion zu finden. Es ist also nicht so schwer.
Andry
245

Um dies für ein bestimmtes Ziel zu tun, können Sie Folgendes tun:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Sie sollten dies tun, wenn Sie mehr als ein Ziel haben, das Sie erstellen, und nicht möchten, dass alle dieselben Flags verwenden. Siehe auch die offizielle Dokumentation zu target_compile_definitions .

Jim Hunziker
quelle
1
@ JimHunziker Wie target_compile_definitions(my_target PRIVATE FOO=1)unterscheidet sich von set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
John Strood
1
@ JohnStrood Der Unterschied liegt auf Umfangsebene. target_compile_definitionsLegt den Wert für die GANZE ausführbare Datei / Bibliothek fest, wobei 'set_source_files_properties' den Wert nur für die angegebene Datei festlegt. Mit dem letzten Befehl können Dateien in einer anderen Sprache kompiliert werden. dh : set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Beachten Sie, dass -x objective-chier ein für GCC / Clang spezifisches Flag angegeben ist.
Julian Kirsch
20

Die andere auf dieser Seite vorgeschlagene Lösung ist für einige Versionen von Cmake <3.3.2 nützlich . Hier die Lösung für die Version, die ich verwende (dh 3.3.2). Überprüfen Sie die Version Ihres Cmake, indem Sie $ cmake --versiondie Lösung verwenden und auswählen, die Ihren Anforderungen entspricht. Die cmake-Dokumentation finden Sie auf der offiziellen Seite.

Mit CMake Version 3.3.2, um zu erstellen

#define foo

Ich musste verwenden:

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

und um eine Präprozessor-Makrodefinition wie diese andere zu haben:

#define foo=5

Die Linie ist so modifiziert:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
Leos313
quelle
4
Laut Dokumentation handelt es sich bei dieser Lösung tatsächlich um den älteren, veralteten Ansatz. Die anderen Antworten bieten die moderneren Lösungen.
Squareskittles
2
Als ich die Antwort schrieb, habe ich die andere Lösung ausprobiert, aber keine davon hat funktioniert.
Leos313
@squareskittles, eine Idee, warum die Lösung der anderen Antwort nicht richtig funktioniert hat? CMake geben Fehler, wenn ich sie versuche
Leos313
1
Wenn Sie CMake 3.3.2 verwenden, wie Sie in Ihrer Antwort angegeben haben, müssen Sie add_definitions()oder verwenden target_compile_definitions(). Der modernere Befehl add_compile_definitions()wurde erst mit CMake 3.12 hinzugefügt. @ Leos313
squareskittles
1
@squareskittles, ich aktualisiere die Antwort und schreibe neu, was ich vor einigen Monaten geschrieben habe. Vielen Dank für den Hinweis
Leos313