Eu gostaria de usar um conjunto global de sinalizadores para compilar um projeto, o que significa que no meu arquivo CMakeLists.txt de nível superior eu especifiquei:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
No entanto, para um arquivo específico (digamos "foo.cpp") em um subdiretório, quero mudar os sinalizadores de compilação para não aplicar -Weffc ++ (biblioteca comercial incluída, não posso mudar). Para simplificar a situação de usar apenas -Wall, tentei:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, que não funcionou. Eu também tentei
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
e
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, em que nenhum funcionou.
Por fim, tentei remover esta definição:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, que também não funcionou (ou seja, recebo muitos avisos de estilo sobre a biblioteca comercial). (** Nota: Os avisos SÃO suprimidos se eu NÃO incluir novamente a diretiva -Weffc ++ após o executável ser compilado.)
Também tentei remover temporariamente os sinalizadores de compilação: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , mas isso não ajudou.
Não existe uma solução elegante para isso?
fonte
Respostas:
Suas tentativas acima estão adicionando mais sinalizadores ao seu arquivo / destino, em vez de sobrescrever como você parece esperar. Por exemplo, nos documentos de Propriedades nos arquivos de origem - COMPILE_FLAGS :
Você deve ser capaz de contra-ordenar o
-Weffc++
ordenar bandeira para foo.cpp fazendoIsso deve ter o efeito de adicionar
-Wno-effc++
após-Weffc++
no comando do compilador, e a última configuração vence. Para ver o comando completo e verificar se este é realmente o caso, você pode fazerÀ parte, um dos mantenedores da Biblioteca Padrão GNU C ++ apresenta uma opinião bastante negativa sobre
-Weffc++
em esta resposta .Outro ponto é que você está usando mal
add_definitions
usando no sentido de que está usando isso para sinalizadores de compilador em vez das definições de pré-processador pretendidas.Seria preferível usar
add_compile_options
ou para versões do CMake <3.0 para fazer algo mais como:
Em resposta a outras perguntas nos comentários abaixo, acredito que seja impossível remover de forma confiável um sinalizador em um único arquivo. O motivo é que, para qualquer arquivo de origem, ele tem o
COMPILE_OPTIONS
eCOMPILE_FLAGS
1 de seu destino aplicado, mas eles não aparecem em nenhuma das propriedades desse arquivo de origem.Você pode tentar retirar o sinalizador de problema do alvo
COMPILE_OPTIONS
, em seguida, aplicá-lo a cada uma das origens do destino individualmente, omitindo-o do arquivo de origem específico conforme necessário.No entanto, embora isso possa funcionar em muitos cenários, há alguns problemas.
Primeiro - as propriedades dos arquivos de origem não incluem
COMPILE_OPTIONS
, apenasCOMPILE_FLAGS
. Isso é um problema porque oCOMPILE_OPTIONS
de um destino pode incluir expressões geradoras , masCOMPILE_FLAGS
não as suporta. Portanto, você teria que acomodar expressões geradoras enquanto procurava por seu sinalizador e, de fato, talvez até tivesse que "analisar" expressões geradoras se seu sinalizador estivesse contido em um ou mais para ver se deveria ser reaplicado ao restante Arquivos Fonte.Segundo - desde CMake v3.0, os destinos podem especificar
INTERFACE_COMPILE_OPTIONS
. Isso significa que uma dependência do seu alvo pode adicionar ou substituir a do seu alvo porCOMPILE_OPTIONS
meio de seuINTERFACE_COMPILE_OPTIONS
. Portanto, você ainda teria que iterar recursivamente por meio de todas as dependências do seu destino (não é uma tarefa particularmente fácil, pois a lista deLINK_LIBRARIES
para o destino também pode conter expressões geradoras) para encontrar qualquer uma que esteja aplicando o sinalizador de problema e tente removê-la daquelas alvos 'INTERFACE_COMPILE_OPTIONS
também.Neste estágio de complexidade, gostaria de enviar um patch ao CMake para fornecer a funcionalidade de remover um sinalizador específico incondicionalmente de um arquivo de origem.
1: Observe que, ao contrário da
COMPILE_FLAGS
propriedade nos arquivos de origem, aCOMPILE_FLAGS
propriedade nos destinos está obsoleta.fonte
Apenas adicionando a resposta correta de @Fraser.
Caso você queira adicionar o sinalizador especial a pastas específicas, você pode fazer:
ou
Observe que não é recomendado usar GLOB conforme discutido aqui
fonte
Usando a resposta @Fraser, criei o seguinte para lidar com o Qt includes porque a variável inclui vários caminhos separados por ponto-e-vírgula. Isso significa que primeiro tive que adicionar um
foreach()
loop e criar os sinalizadores de inclusão manualmente . Mas isso me permite ter uma exceção: foo.cpp (aquele arquivo usa Qt por enquanto, mas a longo prazo eu quero remover essa dependência e quero ter certeza de que o Qt não se infiltrará em nenhum outro lugar).Observe também que eu uso o em
-isystem
vez de-I
para evitar alguns avisos que os cabeçalhos Qt geram (tenho muitos avisos ativados).fonte