2015-04-16 3 views
8

Ho un solo intestazione C++ 11 biblioteca, quindi voglio configurarlo, usando CMake> 3.1, compilare caratteristiche sembra ragionevole modo per farlo:Come definire transitiva CXX_STANDARD C++ 11 in cmake

target_compile_features(my_header_lib INTERFACE cxx_range_for) 

Ma preferirei non dover indicare le singole funzionalità, ma solo C++ 11 o C++ 14. Poi ho potuto provare a utilizzare il seguente:

set_property(TARGET my_target PROPERTY CXX_STANDARD 11) 

Il problema è che my_target non può essere INTERFACCIA qui, non è supportato, e non riesco a definirlo PUBBLICO, quindi i consumatori (tanti Exes) del mio colpo di testa solo la volontà biblioteca ha automaticamente la configurazione di C++ 11 propagata dalla lib.

C'è un modo per definire uno standard 11/14 di alto livello, ma anche configurarlo per una sola libreria di intestazione (INTERFACE)? Preferirei non ricorrere al vecchio manuale -std = C++ 11.

+1

In effetti, si tratta di una scelta deliberata di progettazione non sostenere una proprietà target 'INTERFACE_CXX_STANDARD'. Vedi anche la variabile 'CMAKE_CXX_STANDARD'. – steveire

risposta

2

CMake 3.8 (pubblicato nell'aprile 2017) ha introdotto meta-funzioni (ad esempio cxx_std_11, cxx_std_14, cxx_std_17). Ora è possibile ad esempio scrivere:

target_compile_features(my_header_lib INTERFACE cxx_std_11) 
4

La soluzione più semplice per il momento è quella di mantenere manualmente gli elenchi di funzioni C++ 11 e C++ 14 in una variabile globale e alimentare tale elenco a target_compile_features.

set(CXX11_FEATURES 
    cxx_auto_type 
    cxx_constexpr 
    [...] 
) 

set(CXX14_FEATURES 
    cxx_generic_lambdas 
    [...] 
) 

target_compile_features(my_header_lib INTERFACE ${CXX11_FEATURES} ${CXX14_FEATURES}) 

Probabilmente, sarebbe bello se CMake avesse già fornito quelle liste per voi, ma attualmente non lo è.

Si noti che questo è coerente con il modo in cui il meccanismo delle caratteristiche di compilazione funziona attualmente in CMake. La proprietà CXX_STANDARD determina quale flag viene assegnato al compilatore sulla riga di comando. Solo perché richiedi una certa versione standard, tuttavia, non garantisce che compili correttamente una determinata funzione. L'unico modo per assicurarsi che una determinata funzionalità sia presente (e fallire con un errore significativo se non lo è) è verificarla tramite target_compile_features.

La complicazione qui non dipende da come CMake gestisce le cose, ma dal fatto che diversi compilatori implementano diversi sottoinsiemi dello standard.

+0

Sì, questo è un buon approccio, penso. E sì, penso che sarebbe una buona idea che CMake definisca le liste per noi. C'è ancora un piccolo problema, sembra che le caratteristiche di target_compile non siano completamente implementate dai dati per i compilatori come MinGW, e sto ricevendo alcuni errori, nonostante sembri risolto in https://public.kitware.com/Bug/view.php ? id = 15443. Proverà questo e posta un'altra domanda se necessario. – drodri

+1

@drodri Sì, 'target_compile_features' non è molto affidabile al momento. IIRC funziona solo con le versioni recenti gcc e clang al momento. Spero che questo sarà risolto presto, perché in generale è una caratteristica molto interessante di CMake. – ComicSansMS

+1

L'elenco delle funzionalità note al compilatore si trova in http://www.cmake.org/cmake/help/v3.2/variable/CMAKE_CXX_COMPILE_FEATURES.html#variable:CMAKE_CXX_COMPILE_FEATURES. GCC 4.4 è la versione GCC più vecchia supportata, la versione Clang fornita con Xcode 4.0 e MSVC 2010. Quelle sono vecchie. Non è vero che solo i compilatori recenti sono supportati. – steveire