Come posso aggiungere un linker o compilare un flag in un file CMake?

Sto usando il compilatore arm-linux-androidabi-g++ . Quando provo a compilare un semplice “Hello, World!” programma che compila bene. Quando lo collaudo aggiungendo una semplice gestione delle eccezioni in quel codice funziona anche (dopo aver aggiunto -fexceptions .. Suppongo che sia disabilitato di default).

Questo è per un dispositivo Android, e voglio solo usare CMake, non ndk-build .

Ad esempio: first.cpp

 #include  using namespace std; int main() { try{ } catch(...) { } return 0; } 

./arm-linux-androidadi-g++ -o first-test first.cpp -fexceptions

Funziona senza problemi …

Il problema … Sto cercando di compilare il file con un file CMake.

Voglio aggiungere le -fexceptions come bandiera. Ci ho provato

 set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" ) 

e

 set ( CMAKE_C_FLAGS "fexceptions") 

Visualizza ancora un errore.

Supponiamo di voler aggiungere quei flag (meglio dichiararli in una costante):

 SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage") SET(GCC_COVERAGE_LINK_FLAGS "-lgcov") 

Ci sono diversi modi per aggiungerli:

  1. Il più semplice (non pulito, ma facile e conveniente, e funziona solo con flag di compilazione, C & C ++ in una volta):

     add_definitions(${GCC_COVERAGE_COMPILE_FLAGS}) 
  2. Aggiunta alle variabili CMake corrispondenti:

     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}") 
  3. Usando le proprietà target, cf. doc CMake compila la proprietà target del flag e deve conoscere il nome del target.

     get_target_property(TEMP ${THE_TARGET} COMPILE_FLAGS) if(TEMP STREQUAL "TEMP-NOTFOUND") SET(TEMP "") # Set to empty string else() SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content endif() # Append our values SET(TEMP "${TEMP}${GCC_COVERAGE_COMPILE_FLAGS}" ) set_target_properties(${THE_TARGET} PROPERTIES COMPILE_FLAGS ${TEMP} ) 

In questo momento io uso il metodo 2.

Nelle versioni più recenti di CMake puoi anche impostare flag di compilatore e linker per un singolo target utilizzando target_compile_options e target_link_libraries rispettivamente (sì, quest’ultimo imposta anche le opzioni del linker):

 target_compile_options(first-test PRIVATE -fexceptions) 

Il vantaggio di questo metodo è che puoi controllare la propagazione delle opzioni ad altri target che dipendono da questo tramite PUBLIC e PRIVATE .

Prova a impostare la variabile CMAKE_CXX_FLAGS anziché CMAKE_C_FLAGS :

 set (CMAKE_CXX_FLAGS "-fexceptions") 

La variabile CMAKE_C_FLAGS riguarda solo il compilatore C, ma stai compilando il codice C ++.

L’aggiunta del flag a CMAKE_EXE_LINKER_FLAGS è ridondante.

Puoi anche aggiungere flag linker a un target specifico utilizzando la proprietà LINK_FLAGS :

 set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}") 

Se si desidera propagare questa modifica ad altri target, è ansible creare una destinazione fittizia a cui collegarsi.

Esegui il check di ucm_add_flags e ucm_add_linker_flags macro di ucm (il mio set di macro utili di CMake) – si occupano di accodare i flag di compilatore / linker.