Definire la macro del preprocessore tramite CMake?


283

Come definisco una variabile del preprocessore tramite CMake?

Il codice equivalente sarebbe #define foo.

Risposte:


383

Per molto tempo, CMake ha avuto il add_definitionscomando per questo scopo. Tuttavia, recentemente il comando è stato sostituito da un approccio più fine (comandi separati per le definizioni di compilazione, include le directory e le opzioni del compilatore).

Un esempio che utilizza le nuove add_compile_definitions :

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

O:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

La parte buona di questo è che elude il trucco malandato per cui CMake è in atto add_definitions. CMake è un sistema così malandato, ma stanno finalmente trovando un po 'di buonsenso.

Trova ulteriori spiegazioni su quali comandi utilizzare per i flag del compilatore qui: https://cmake.org/cmake/help/latest/command/add_definitions.html

Allo stesso modo, puoi fare questo per bersaglio come spiegato nella risposta di Jim Hunziker.


4
Dalla pagina collegata: "Nota Questo comando è stato sostituito da alternative: Utilizzare add_compile_definitions () per aggiungere definizioni del preprocessore." Forse questa risposta ha bisogno di una modifica?
M.Herzkamp,

10
In cmake 3.10.2, add_compile_definitionsgenera CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. Dovevo usare add_compile_options(-D <your-def>)invece.
code_dredd,

2
@mannyglover Non credo, ma puoi impostare i flag del compilatore con -D, qualcosa del genere cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(non testato)
ypnos,

1
È davvero nuovo ... in realtà è in More Modern CMake (> 3.11). Un dolore che è così difficile sapere quando è stato introdotto un comando.
Sandburg

1
@Sandburg È possibile aprire il collegamento all'ultima documentazione: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionse iniziare a modificare il numero di versione verso il basso fino alla scomparsa della pagina. Questa sarebbe la versione in cui non esiste ancora. Nella prossima mossa puoi andare alla Whats newsezione per trovare un nuovo comando o funzione. Quindi non è così difficile.
Andry,

245

Per fare ciò per un obiettivo specifico, puoi fare quanto segue:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Dovresti farlo se hai più di un obiettivo che stai costruendo e non vuoi che tutti usino le stesse bandiere. Vedi anche la documentazione ufficiale su target_compile_definitions .


1
@JimHunziker In cosa target_compile_definitions(my_target PRIVATE FOO=1)differisce da set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
John Strood,

1
@JohnStrood La differenza è a livello di ambito. target_compile_definitionsimposta il valore per l'intero eseguibile / libreria, dove come 'set_source_files_properties` imposta il valore solo per il file specificato. Il comando Latter consente di compilare i file utilizzando una lingua diversa; Per esempio: set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Nota che -x objective-cqui c'è un flag specifico per GCC / Clang.
Julian Kirsch,

20

L'altra soluzione proposta in questa pagina sono utili alcune versioni di Cmake <3.3.2 . Qui la soluzione per la versione che sto usando (cioè, 3.3.2). Controlla la versione di Cmake utilizzando $ cmake --versione scegli la soluzione adatta alle tue esigenze. La documentazione di cmake è disponibile sulla pagina ufficiale.

Con CMake versione 3.3.2, per creare

#define foo

Avevo bisogno di usare:

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

e, per avere una definizione di macro del preprocessore come questa:

#define foo=5

la linea è così modificata:

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

4
Secondo la documentazione , questa soluzione è in realtà l'approccio più vecchio e più antiquato. Le altre risposte offrono le soluzioni più moderne.
squareskittles,

2
Quando ho scritto la risposta, ho provato l'altra soluzione ma nessuno di loro funzionava.
Leos313,

@squareskittles, hai idea del perché la soluzione dell'altra risposta non ha funzionato correttamente? CMake dà errori se li provo
Leos313

1
Se si utilizza CMake 3.3.2, come indicato nella risposta, è necessario utilizzare add_definitions()o target_compile_definitions(). Il comando più moderno, add_compile_definitions()non è stato aggiunto fino a CMake 3.12. @ Leos313
squareskittles

1
@squareskittles, sto aggiornando la risposta, riscrivendo quello che ho scritto alcuni mesi fa. Grazie per averlo sottolineato
Leos313,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.