2012-11-30 13 views
73

Vorrei utilizzare un insieme globale di bandiere per la compilazione di un progetto, il che significa che a mio file CMakeLists.txt di alto livello che ho specificato:Override compilare bandiere per i file singoli

ADD_DEFINITIONS (-Wall -Weffc++ -pedantic -std=c++0x) 

Tuttavia, per un file specifico (diciamo "foo.cpp") in una sottodirectory, voglio cambiare i flag di compilazione per non applicare -WeffC++ (libreria commerciale inclusa che non posso cambiare). Per semplificare la situazione da utilizzare solo -Wall, ho provato:

SET_SOURCE_FILES_PROPERTIES(foo.cpp PROPERTIES COMPILE_FLAGS -Wall) 
ADD_EXECUTABLE(foo foo.cpp) 

, che non ha funzionato. Ho anche provato

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) 

, in cui né lavorato.

Infine, ho provato a rimuovere questa defintion:

REMOVE_DEFINITIONS(-Weffc++) 
ADD_EXECUTABLE(foo foo.cpp) 
ADD_DEFINITIONS(-Weffc++) 

, che pure non ha funzionato (significato, ho un sacco di avvertimenti in stile sulla libreria commerciale). (** Nota:. Gli avvisi vengono soppressi se non lo faccio ri-direttiva include la -WeffC++ dopo l'eseguibile è stato costruito)

Ho anche provato a rimuovere temporaneamente i flag di compilazione: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , ma che non l'ha fatto Aiuto.

Non c'è una soluzione elegante a questo?

+1

Attendi, se il tuo ultimo tentativo funziona, ma solo dopo che è stato creato, questo potrebbe non essere un problema di cache? Prova a eliminare CMakeCache dopo aver apportato le modifiche. – Cameron

+0

Correlati, vedere [Come modificare un flag del compilatore per un solo eseguibile in CMake?] (Https://stackoverflow.com/q/24238937/608639) La risposta di Andre mostra quello che sembra essere un modo per sostituire le opzioni esistenti con nuove opzioni . – jww

risposta

87

I tentativi sopra riportati aggiungono ulteriori flag al file/destinazione anziché sovrascrivere come sembra. Ad esempio, dai documenti per Properties on Source Files - COMPILE_FLAGS:

Questi flag verranno aggiunti all'elenco di flag di compilazione quando questo file di origine viene generato.

si dovrebbe essere in grado di annullare la bandiera -Weffc++ per foo.cpp facendo

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++) 

Questo dovrebbe avere l'effetto di aggiungere -Wno-effc++ dopo -Weffc++ nel comando del compilatore, e le vittorie di impostazione quest'ultimo. Per vedere il comando completo e verificare che questo è davvero il caso, si può fare

make VERBOSE=1 

Per inciso, uno dei manutentori del ++ Standard Library GNU C presenta un parere piuttosto negativo sulla -Weffc++ in this answer.

Un altro punto è che si sta utilizzando in modo improprio add_definitions nel senso che si sta utilizzando questo per i flag del compilatore anziché le definizioni del preprocessore.

Sarebbe preferibile utilizzare add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x) 

o per le versioni CMake < 3.0 a fare qualcosa di più simile:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x") 

In risposta alle ulteriori domande nei commenti qui sotto, credo che sia impossibile in modo affidabile rimuovere una bandiera su un singolo file. Il motivo è che per qualsiasi dato file sorgente, è il COMPILE_OPTIONS e COMPILE_FLAGS del target applicato, ma questi non vengono visualizzati in nessuna delle proprietà per tale file sorgente.

È possibile visualizzare il flag di rimozione del problema da COMPILE_OPTIONS della destinazione, quindi applicarlo individualmente a ciascuna sorgente di destinazione, omettendolo dal file di origine specifico come richiesto.

Tuttavia, mentre questo potrebbe funzionare in molti scenari, ha un paio di problemi.

Primo - source files' properties non includere COMPILE_OPTIONS, solo COMPILE_FLAGS. Questo è un problema perché il COMPILE_OPTIONS di una destinazione può includere generator expressions, ma COMPILE_FLAGS non li supporta. Quindi dovresti accettare le espressioni del generatore durante la ricerca del tuo flag, e in effetti potresti anche dover "analizzare" le espressioni del generatore se il tuo flag era contenuto in uno o più per vedere se dovesse essere riapplicato al resto file sorgenti.

Secondo: da CMake v3.0, gli obiettivi possono specificare INTERFACE_COMPILE_OPTIONS. Ciò significa che una dipendenza del tuo target può aggiungere o ignorare il tuo target COMPILE_OPTIONS tramite il suo INTERFACE_COMPILE_OPTIONS. Quindi dovresti eseguire iterazioni ricorsive in tutte le dipendenze del tuo target (non un compito particolarmente facile dato che l'elenco di LINK_LIBRARIES per la destinazione può contenere anche espressioni del generatore) per trovare quelle che stanno applicando il flag del problema, e provare a rimuoverlo da quegli obiettivi 'INTERFACE_COMPILE_OPTIONS troppo.

In questa fase di complessità, avrei intenzione di inviare una patch a CMake per fornire la funzionalità per rimuovere un flag specifico incondizionatamente da un file sorgente.


1: Si noti che a differenza della proprietà COMPILE_FLAGS il file di origine, la proprietà COMPILE_FLAGS su obiettivi è deprecato.

+5

Ma come si impostano effettivamente i flag di compilazione per i file separatamente senza aggiungerli. Ad esempio, desidero utilizzare diversi flag di compilazione per la destinazione risultante che per i file ma, poiché vengono aggiunti, dovrei rimuoverli manualmente. Non ci sono proprietà che non aggiungono ma che in realtà le impostano solo per il file/target specificato? –

+2

Cosa possiamo fare quando -fno-flag non è disponibile (e -flag è impostato)? – gnzlbg

+0

@ Baradé Non è possibile - non per un file sorgente. – Fraser

Problemi correlati