Definir macro de preprocesador a través de CMake?

283

¿Cómo defino una variable de preprocesador a través de CMake?

El código equivalente sería #define foo.

Mythli
fuente

Respuestas:

382

Durante mucho tiempo, CMake tuvo el add_definitionscomando para este propósito. Sin embargo, recientemente el comando ha sido reemplazado por un enfoque más detallado (comandos separados para compilar definiciones, incluir directorios y opciones de compilación).

Un ejemplo usando las nuevas 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)

Lo bueno de esto es que evita el truco en mal estado que CMake tiene establecido add_definitions. CMake es un sistema tan lamentable, pero finalmente están encontrando cierta cordura.

Encuentre más explicaciones sobre qué comandos usar para los indicadores del compilador aquí: https://cmake.org/cmake/help/latest/command/add_definitions.html

Del mismo modo, puede hacer esto por objetivo como se explica en la respuesta de Jim Hunziker.

ypnos
fuente
44
Desde la página vinculada: "Nota: Este comando ha sido reemplazado por alternativas: Use add_compile_definitions () para agregar definiciones de preprocesador". Tal vez esta respuesta necesita una edición?
M.Herzkamp
9
En cmake 3.10.2, add_compile_definitionstiros CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. Tuve que usar add_compile_options(-D <your-def>)en su lugar.
code_dredd
2
@mannyglover No lo creo, pero puedes configurar los indicadores del compilador con -D, algo cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'
similar a
1
Es realmente nuevo ... de hecho está en CMake más moderno (> 3.11). Un dolor que es tan difícil saber cuando se introdujo un comando.
Sandburg
1
@Sandburg Puede abrir el enlace a la última documentación: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsy comenzar a cambiar el número de versión hacia abajo hasta que desaparezca la página. Esa sería la versión donde aún no existe. En el siguiente movimiento, puede ir a la Whats newsección para encontrar un nuevo comando o función. Entonces no es tan difícil.
Andry
245

Para hacer esto para un objetivo específico, puede hacer lo siguiente:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Debes hacer esto si tienes más de un objetivo que estás construyendo y no quieres que todos usen las mismas banderas. Consulte también la documentación oficial sobre target_compile_definitions .

Jim Hunziker
fuente
1
@JimHunziker ¿Cómo es target_compile_definitions(my_target PRIVATE FOO=1)diferente de set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
John Strood
1
@ JohnStrood La diferencia está en el nivel de alcance. target_compile_definitionsestablece el valor para TODO el ejecutable / biblioteca, donde como 'set_source_files_properties` establece el valor solo para el archivo especificado. El último comando permite que los archivos se compilen usando un idioma diferente; es decir: set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Tenga en cuenta que -x objective-caquí hay una bandera específica para GCC / Clang.
Julian Kirsch
20

La otra solución propuesta en esta página son útiles en algunas versiones de Cmake <3.3.2 . Aquí la solución para la versión que estoy usando (es decir, 3.3.2). Verifique la versión de su Cmake usando $ cmake --versiony elija la solución que se ajuste a sus necesidades. La documentación de cmake se puede encontrar en la página oficial.

Con CMake versión 3.3.2, para crear

#define foo

Necesitaba usar:

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

y, para tener una definición de macro de preprocesador como esta otra:

#define foo=5

la línea se modifica así:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
Leos313
fuente
44
Según la documentación , esta solución es en realidad el enfoque más antiguo y anticuado. Las otras respuestas ofrecen las soluciones más modernas.
squareskittles
2
Cuando escribí la respuesta, probé la otra solución, pero ninguna de ellas funcionaba.
Leos313
@squareskittles, ¿alguna idea de por qué la solución de la otra respuesta no funcionó correctamente? CMake dar errores si los pruebo
Leos313
1
Si está utilizando CMake 3.3.2, como indicó en su respuesta, debe usar add_definitions()o target_compile_definitions(). El comando más moderno add_compile_definitions()no se agregó hasta CMake 3.12. @ Leos313
squareskittles
1
@squareskittles, estoy actualizando la respuesta, reescribiendo lo que escribí hace algunos meses. Gracias por señalar esto
Leos313