2014-08-27 23 views
8

vorrei aggiungere -std=c++11 al mioCMake generatore di espressione, differenziare C/C++ di codice

add_compile_options("-std=c++11") 

Tuttavia, questo li aggiunge anche alla compilazione di C file, non solo C++. So che posso aggiungere flag di compilazione condizionali a seconda della configurazione utilizzata:

add_compile_options("$<$<CONFIG:DEBUG>:-addMeInDebugOnly>") 

Come posso aggiungere la mia bandiera solo per C++ file? Sto cercando qualcosa come:

add_compile_options("$<$<??:??>:-std=c++11>") 

Ma cosa devo compilare con i punti interrogativi?

+0

stai usando g ++/gcc? –

+0

O g ++/gcc o clang, a seconda della piattaforma. –

+1

Potresti dare un'occhiata al comando sperimentale ['target_compile_features'] (http://www.steveire.com/cmake-future/manual/cmake-compile-features.7.html) che ci permetterebbe di ottenere sbarazzarsi di flag di compilazione non portatili per questo caso d'uso del tutto. A partire da ora (CMake 3.0.1) questa funzione non viene fornita con CMake, ma dovremmo farlo con una delle prossime versioni. – ComicSansMS

risposta

2

È possibile utilizzare LINKER_LANGUAGE proprietà target per aggiungere bandiera solo per C++ target *:

add_compile_options(
    "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-std=c++11>" 
) 

* Nota che questo non funzionerà per obiettivi con sorgenti miste C/C++

CMAKE_CXX_FLAGS dovrebbe funzionare bene anche:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

Probabilmente è necessario aggiungere loro di memorizzare nella cache se impostato prima project di comando (per esempio in toolchain):

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE STRING "" FORCE) 
+0

Impressionante, "target_property: linker_language" era esattamente quello che stavo cercando :) –

+0

Hmm ... in realtà non sembra funzionare dopo tutto se il codice C e C++ sono mescolati nello stesso target :( –

+0

@ruslo: Ma fa 'CMAKE_CXX_FLAGS' funziona per tutti i tipi di build (' CMAKE_BUILD_TYPE_DEBUG', 'CMAKE_BUILD_TYPE_RELWITHDEBINFO', ...), o devo farlo alla vecchia maniera, http://binglongx.wordpress.com/tag/cmake_build_type/? – telephone

3

preferirei farlo in questo modo:

set_source_files_properties(
    ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp 
    PROPERTIES COMPILE_FLAGS "-std=c++11") 

in cui la documentazione per set_source_files_properties è a http://www.cmake.org/cmake/help/v3.0/command/set_source_files_properties.html

+0

Il problema con questo è che mi piacerebbe utilizzare il codice in un file CMakeLists.txt di livello superiore e farlo applicare a tutti i file cmake in tutte le sottodirectory. Quindi dovrei aggiungere la tua linea a dozzine di file CMakeLists.txt diversi, il che non è molto bello ... –

+0

@ JanRüegg hai provato a impostare 'CMAKE_CXX_FLAGS 'come' SET (CMAKE_CXX_FLAGS "-std = C++ 11" CACHE STRING "compile flags" FORCE) '(http://stackoverflow.com/questions/15100351/changing-cmake-cxx-flags-in-project) – fritzone

+0

Questo è quello che sto facendo attualmente, tuttavia mi sarebbe piaciuto liberarmi di questo, dal momento che pensavo che fosse il "vecchio brutto" modo di farlo, mentre add_compile_options è più moderno. –

12

Dopo aver mescolato le fonti C e C++, la proprietà LINKER_LANGUAGE potrebbe applicare le bandiere sbagliate per la compilazione delle singole fonti. La soluzione è utilizzare l'espressione del generatore COMPILE_LANGUAGE (introdotta con CMake 3.3). L'esempio più semplice per la tua bandiera originale C++ 1x è:

add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++11>) 

Quando si dispone di una serie di opzioni di compilazione (ad esempio, per l'utilizzo con la proprietà COMPILE_FLAGS target), è necessario dividere le bandiere

set(WARNCFLAGS "-Wall -Wextra -Wfuzzle -Wbar") 
# ... 
string(REPLACE " " ";" c_flags "${WARNCFLAGS}") 
string(REPLACE " " ";" cxx_flags "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}") 
add_compile_options(
    "$<$<COMPILE_LANGUAGE:C>:${c_flags}>" 
    "$<$<COMPILE_LANGUAGE:CXX>:${cxx_flags}>" 
) 
# Two alternative variants for single targets that take strings: 
target_compile_options(some-target PRIVATE "${WARNCFLAGS}") 
set_target_properties(some-target PROPERTIES 
    COMPILE_FLAGS "${WARNCFLAGS}") 

L'utilizzo di stringhe è tuttavia deprecato a favore delle liste. Quando gli elenchi sono in uso, è possibile utilizzare:

set(c_flags -Wall -Wextra -Wfuzzle -Wbar) 
# ... 
add_compile_options(
    "$<$<COMPILE_LANGUAGE:C>:${c_flags}>" 
    "$<$<COMPILE_LANGUAGE:CXX>:${cxx_flags}>" 
) 
# Two alternative variants for single targets given a list: 
target_compile_options(some-target PRIVATE ${f_flags}) 
set_target_properties(some-target PROPERTIES 
    COMPILE_OPTIONS "${c_flags}") 

Prestare attenzione al preventivo. Se un elenco non è un preventivo, viene esteso ai suoi elementi (e non è più un elenco). Per passare una lista tra i comandi, citala.

Problemi correlati