Me gustaría usar un conjunto global de indicadores para compilar un proyecto, lo que significa que en mi archivo CMakeLists.txt de nivel superior he especificado:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Sin embargo, para un archivo específico (digamos "foo.cpp") en un subdirectorio, quiero cambiar las marcas de compilación para que no se apliquen -Weffc ++ (biblioteca comercial incluida que no puedo cambiar). Para simplificar la situación para usar solo -Wall, intenté:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, que no funcionó. También lo intenté
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
y
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, en el que ninguno funcionó.
Finalmente, intenté eliminar esta definición:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, que tampoco funcionó (es decir, recibo muchas advertencias de estilo sobre la biblioteca comercial). (** Nota: Las advertencias se suprimen si NO vuelvo a incluir la directiva -Weffc ++ después de que se compile el ejecutable).
También intenté eliminar temporalmente las marcas de compilación: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , pero eso no ayudó.
¿No hay una solución elegante para esto?
fuente
Respuestas:
Sus intentos anteriores están agregando más banderas a su archivo / destino en lugar de sobrescribir como parece esperar. Por ejemplo, de los documentos de Propiedades en archivos de origen - COMPILE_FLAGS :
Debería poder
-Weffc++
anular la bandera de foo.cpp haciendoEsto debería tener el efecto de agregar
-Wno-effc++
after-Weffc++
en el comando del compilador, y la última configuración gana. Para ver el comando completo y comprobar que este es realmente el caso, puede hacerComo acotación al margen, uno de los mantenedores de la biblioteca estándar de GNU C ++ presenta una opinión bastante negativa
-Weffc++
en esta respuesta .Otro punto es que está haciendo un mal uso
add_definitions
en el sentido de que lo está usando para los indicadores del compilador en lugar de las definiciones del preprocesador previstas.Seria preferible usar
add_compile_options
o para las versiones de CMake <3.0 para hacer algo más como:
En respuesta a más preguntas en los comentarios a continuación, creo que es imposible eliminar de manera confiable una marca en un solo archivo. La razón es que para cualquier archivo fuente dado, tiene el
COMPILE_OPTIONS
y 1 de su destino aplicado, pero estos no aparecen en ninguna de las propiedades de ese archivo fuente.COMPILE_FLAGS
Podría buscar quitar el indicador de problema del objetivo
COMPILE_OPTIONS
y luego aplicarlo a cada una de las fuentes del objetivo individualmente, omitiéndolo del archivo fuente específico según sea necesario.Sin embargo, aunque esto podría funcionar en muchos escenarios, tiene un par de problemas.
Primero, las propiedades de los archivos de origen no incluyen
COMPILE_OPTIONS
, soloCOMPILE_FLAGS
. Esto es un problema porque elCOMPILE_OPTIONS
de un destino puede incluir expresiones generadoras , peroCOMPILE_FLAGS
no las admite. Por lo tanto, tendría que acomodar las expresiones del generador mientras busca su bandera y, de hecho, tal vez incluso tenga que "analizar" las expresiones del generador si su bandera está contenida en una o más para ver si debe volver a aplicarse al resto archivos fuente.En segundo lugar, desde CMake v3.0, los destinos pueden especificar
INTERFACE_COMPILE_OPTIONS
. Esto significa que una dependencia de su objetivo puede agregar o anular su objetivo aCOMPILE_OPTIONS
través de suINTERFACE_COMPILE_OPTIONS
. Entonces, además, tendría que iterar recursivamente a través de todas las dependencias de su objetivo (no es una tarea particularmente fácil ya que la lista deLINK_LIBRARIES
para el objetivo también puede contener expresiones generadoras) para encontrar cualquiera que esté aplicando el indicador de problema, e intentar eliminarlo de esos objetivos 'INTERFACE_COMPILE_OPTIONS
también.En esta etapa de complejidad, estaría buscando enviar un parche a CMake para proporcionar la funcionalidad para eliminar una marca específica incondicionalmente de un archivo fuente.
1: tenga en cuenta que, a diferencia de la
COMPILE_FLAGS
propiedad de los archivos de origen, laCOMPILE_FLAGS
propiedad de los destinos está obsoleta.fuente
Solo agregando a la respuesta correcta de @ Fraser.
En caso de que desee agregar la bandera especial a carpetas específicas, puede hacer:
o
Tenga en cuenta que no se recomienda utilizar GLOB como se describe aquí
fuente
Usando la respuesta de @Fraser, creé lo siguiente para manejar las inclusiones de Qt porque la variable incluye múltiples rutas separadas por punto y coma. Esto significa que primero tuve que agregar un
foreach()
bucle y crear las banderas de inclusión a mano . Pero eso me permite tener una excepción: foo.cpp (ese archivo usa Qt por ahora, pero a largo plazo quiero eliminar esa dependencia y quiero asegurarme de que Qt no se cuele en ningún otro lugar).Tenga en cuenta también que uso el en
-isystem
lugar de-I
para evitar algunas advertencias que los encabezados de Qt generan (tengo un montón de advertencias activadas).fuente