Qual è il metodo moderno per impostare i flag di compilazione generali in CMake?


86

Esistono più meccanismi offerti da CMake per ottenere i flag al compilatore:

C'è un metodo che è preferito rispetto all'altro nell'uso moderno? Se è così perché? Inoltre, come può essere utilizzato questo metodo con più sistemi di configurazione come MSVC?


Risposte:


97

Per CMake moderno (versioni 2.8.12 e successive) dovresti usare target_compile_options, che utilizza internamente le proprietà di destinazione.

CMAKE_<LANG>_FLAGSè una variabile globale e la più soggetta a errori da utilizzare. Inoltre non supporta le espressioni del generatore , che possono tornare molto utili.

add_compile_options si basa sulle proprietà della directory, il che va bene in alcune situazioni, ma di solito non è il modo più naturale per specificare le opzioni.

target_compile_optionsfunziona in base alla destinazione (tramite l'impostazione delle proprietà COMPILE_OPTIONSe della INTERFACE_COMPILE_OPTIONSdestinazione), che di solito produce il codice CMake più pulito, poiché le opzioni di compilazione per un file di origine sono determinate dal progetto a cui appartiene il file (piuttosto che dalla directory in cui è posizionato sul disco rigido). Ciò ha l'ulteriore vantaggio che si occupa automaticamente di passare le opzioni alle destinazioni dipendenti, se richiesto.

Anche se sono un po 'più verbosi, i comandi per target consentono un controllo ragionevolmente fine sulle diverse opzioni di build e (nella mia esperienza personale) hanno meno probabilità di causare mal di testa a lungo termine.

In teoria, potresti anche impostare le rispettive proprietà direttamente usando set_target_properties, ma di target_compile_optionssolito è più leggibile.

Ad esempio, per impostare le opzioni di compilazione di un target in foobase alla configurazione utilizzando espressioni del generatore è possibile scrivere:

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

I PUBLIC, PRIVATEe INTERFACEle parole chiave definiscono la portata delle opzioni . Ad esempio, se ci colleghiamo fooin barcon target_link_libraries(bar foo):

  • PRIVATEle opzioni verranno applicate solo alla destinazione stessa ( foo) e non ad altre librerie (consumatori) che si collegano ad essa.
  • INTERFACE le opzioni verranno applicate solo all'obiettivo di consumo bar
  • PUBLICle opzioni verranno applicate sia al target originale fooche al target di consumobar

12
Nota che target_compile_options aggiungi opzioni, così puoi modificare l'ultima riga in questo modo per renderla più leggibile)

2
@ComicSansMS Ottima risposta e la migliore (e più aggiornata) che ho potuto trovare su Internet. Grazie!
Ela782

1
@ user3667089 Le proprietà specifiche della destinazione di solito vengono inizializzate da una variabile o una proprietà di directory. La pagina di manuale per la rispettiva proprietà ti dice esattamente quale. Nel caso delle opzioni di compilazione, la COMPILE_OPTIONSproprietà directory lo fa. Puoi usare il add_compile_optionscomando per impostarlo. Le opzioni per le quali questo è un buon approccio sono generalmente poche e distanti tra loro.
ComicSansMS

6
@ComicSansMS A cosa serve PUBLICin target_compile_options?
Ramana Reddy

1
@RamanaReddy ho aggiunto un'ulteriore spiegazione della PUBLICparola chiave alla risposta.
Stefan Profanter

0

I tre modi servono a scopi diversi, quindi nessuno è generalmente preferito agli altri. Il CMAKE_<LANG>_FLAGSè la variabile che un utente può definire a passare le bandiere quando si chiama CMake per un progetto. Gli altri due vengono utilizzati all'interno del progetto. Uno per impostare i flag per un target specifico, l'altro per un'intera directory o un'espressione del generatore.

Domanda correlata: differenza tra add_compile_options e SET (CMAKE_CXX_FLAGS ...)


1
La domanda collegata non spiega la target_compile_optionsstrada. IMHO target_compile_optionsdovrebbe essere preferito in quanto consente un controllo dettagliato delle opzioni e consente di utilizzare espressioni del generatore. add_compile_optionsimposta i flag in tutta la directory. Puoi elaborare un po 'di più la tua risposta su questo fatto? Inoltre ci sono vari siti in cui si dice che target_compile_optionsdovrebbe essere preferito.
Stefan Profanter
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.