¿Cuál es el método moderno para configurar indicadores de compilación generales en CMake?


84

Hay varios mecanismos ofrecidos por CMake para enviar banderas al compilador:

¿Existe un método que se prefiera sobre el otro en el uso moderno? Si es así, ¿por qué? Además, ¿cómo se puede utilizar este método con múltiples sistemas de configuración como MSVC?


Respuestas:


94

Para CMake moderno (versiones 2.8.12 y posteriores) debe usar target_compile_options, que usa propiedades de destino internamente.

CMAKE_<LANG>_FLAGSes una variable global y la más propensa a errores de uso. Tampoco admite expresiones generadoras , lo que puede resultar muy útil.

add_compile_options se basa en las propiedades del directorio, lo que está bien en algunas situaciones, pero normalmente no es la forma más natural de especificar opciones.

target_compile_optionsfunciona según el objetivo (mediante la configuración de las propiedades COMPILE_OPTIONSy el INTERFACE_COMPILE_OPTIONSobjetivo), lo que generalmente da como resultado el código CMake más limpio, ya que las opciones de compilación para un archivo fuente están determinadas por el proyecto al que pertenece el archivo (en lugar de por el directorio en el que está ubicado en el disco duro). Esto tiene la ventaja adicional de que se encarga automáticamente de pasar las opciones a los objetivos dependientes si se solicita.

A pesar de que son un poco más detallados, los comandos por objetivo permiten un control razonablemente detallado sobre las diferentes opciones de compilación y (en mi experiencia personal) son los menos propensos a causar dolores de cabeza a largo plazo.

En teoría, también podría establecer las propiedades respectivas directamente usando set_target_properties, pero target_compile_optionsgeneralmente es más legible.

Por ejemplo, para establecer las opciones de compilación de un destino en foofunción de la configuración utilizando expresiones generadoras, puede escribir:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")

12
Tenga en cuenta que target_compile_options agregue opciones, para que pueda modificar la última línea como esta para que sea más legible)

2
@ComicSansMS Excelente respuesta y la mejor (y más actualizada) que pude encontrar en Internet. ¡Gracias!
Ela782

Si quiero tener el mismo conjunto estricto de indicadores de compilación a nivel mundial, ¿cuál es la mejor forma moderna de hacerlo? Especificación de las mismas banderas y otra vez para diferentes objetivos con target_compile_options parece una mala idea
user3667089

1
@ user3667089 Las propiedades específicas del destino generalmente se inicializan mediante una variable o propiedad de directorio. La página de manual de la propiedad respectiva le dice exactamente cuál. En el caso de las opciones de compilación, la COMPILE_OPTIONSpropiedad del directorio hace esto. Puede usar el add_compile_optionscomando para configurar esto. Las opciones para las que este es un buen enfoque suelen ser pocas y dispersas.
ComicSansMS

6
@ComicSansMS ¿Cuál es el uso de PUBLICin target_compile_options?
Ramana Reddy
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.