web-dev-qa-db-ja.com

CMakeでC++ 11をアクティベートするにはどうすればいいですか?

プログラムをコンパイルするためにCMakeが生成したmakefileを実行しようとすると、

forループベースの範囲は、C++ 98モードではサポートされていません。

私は私のCMakeLists.txtadd_definitions(-std=c++0x)を追加しようとしました、しかしそれは助けになりませんでした。私もこれを試しました:

if(CMAKE_COMPILER_IS_GNUCXX)
    add_definitions(-std=gnu++0x)
endif()

g++ --versionを実行すると、次のようになります。

g ++(Ubuntu/Linaro 4.6.1-9ubuntu3)4.6.1

私はSET(CMAKE_CXX_FLAGS "-std=c++0x")も試しましたが、これもうまくいきません。

CMakeを使ってC++ 11の機能を有効にする方法がわかりません。

329

結局のところ、SET(CMAKE_CXX_FLAGS "-std=c++0x")は多くのC++ 11機能を有効にします。うまくいかなかったのは、この文が次のようになっていたからです。

set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")

このアプローチに従って、どういうわけか-std=c++0xフラグが上書きされてそれが機能しませんでした。フラグを1つずつ設定するか、リストメソッドを使用して作業してください。

list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
40

CMake 3.1は CMAKE_CXX_STANDARD 変数を導入しました。 CMake 3.1をいつでも利用できるということを知っているなら、あなたはこれをあなたのトップレベルCMakeLists.txtファイルに書くか、あるいは新しいターゲットが定義される直前にそれを置くことができます:

set (CMAKE_CXX_STANDARD 11)

あなたがCMakeの古いバージョンをサポートする必要があるならば、ここに私が思い付くことができるというマクロがあります:

macro(use_cxx11)
  if (CMAKE_VERSION VERSION_LESS "3.1")
    if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
    endif ()
  else ()
    set (CMAKE_CXX_STANDARD 11)
  endif ()
endmacro(use_cxx11)

このマクロは現在GCCしかサポートしていませんが、他のコンパイラに拡張するのは簡単です。

その後、C++ 11を使用するターゲットを定義するCMakeLists.txtファイルの先頭にuse_cxx11()を書くことができます。

MacOSをターゲットにしているクランユーザーのための問題#15943

もしあなたがCMakeとclangを使ってmacOSをターゲットにしているのであれば、 bug があり、それはCMAKE_CXX_STANDARD機能を単純に機能させないかもしれません(コンパイラフラグを追加しません)。以下のいずれかを必ず実行してください。

  • CMake 3.0以降が必要な場合は cmake_minimum_required を使用します。
  • projectコマンドの前に、CMakeLists.txtファイルの先頭にある次のコードを使用して、ポリシーCMP0025をNEWに設定します。

    # Fix behavior of CMAKE_CXX_STANDARD when targeting macOS.
    if (POLICY CMP0025)
      cmake_policy(SET CMP0025 NEW)
    endif ()
    
343
David Grayson

CMakeコマンド target_compile_features() を使用して、必要なC++機能cxx_range_forを指定します。 CMakeはC++標準の使用を勧めるでしょう。

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
target_compile_features(foobar PRIVATE cxx_range_for)

CMakeはC++コンパイラが適切なコマンドラインフラグを使って呼び出されるようにするので、add_definitions(-std=c++11)を使用したりCMake変数CMAKE_CXX_FLAGSを変更する必要はありません。

あなたのC++プログラムがcxx_range_for以外のC++機能を使っているかもしれません。 CMakeグローバルプロパティ CMAKE_CXX_KNOWN_FEATURES には、選択可能なC++機能がリストされています。

target_compile_features()を使用する代わりに、CMakeターゲットにCMakeプロパティ CXX_STANDARD および CXX_STANDARD_REQUIRED を設定することで、C++標準を明示的に指定することもできます。

私のより詳細な回答 も参照してください。

181
Erik Sjölund

使ってます

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

あなたがC++11で遊びたいのであれば、g++ 4.6.1はかなり古いです。新しいg++バージョンを入手するようにしてください。

91
KoKuToru

Cxx標準を設定する最も簡単な方法は次のとおりです。

 set_property(TARGET tgt PROPERTY CXX_STANDARD 11)

詳しくは CMakeのドキュメント をご覧ください。

54
Luckyrand

最も簡単な方法:

add_compile_options(-std=c++11)

23
alvarez

これは、C++ 11サポートを有効にするもう1つの方法です。

ADD_DEFINITIONS(
    -std=c++11 # Or -std=c++0x
    # Other flags
)

私はこの方法だけが機能し、他の方法が失敗する例に遭遇しました。たぶんそれはCMakeの最新版と関係があります。

16
Hindol

CMake 3.8以降では使用できます

target_compile_features(target PUBLIC cxx_std_11)
8
eyelash

現代のCMake(> = 3.1)でグローバルな要求を設定するための最良の方法は次のとおりです。

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

「すべてのターゲットにC++ 11が欲しいのですが、これはオプションではありません。私はGNUやMSの拡張を使いたくありません。」 c ++ 17以降、これはまだ私見の最善の方法です。

ソース: https://crascit.com/2015/03/28/enabling-cxx11-in-cmake/

8
MateuszL

私のために働くのはあなたのCMakeLists.txtに次の行を設定することです:

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

このコマンドを設定すると、コンパイラのC++ 11機能が有効になります。cmake ..コマンドを実行すると、コード内でrange based for loopsを使用してエラーなしでコンパイルできるようになります。

6
Kevin Katzke

この2行だけで十分だと思います。

set(CMAKE_CXX_STANDARD 11)

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

常に最新のC++標準を有効にしたい場合は、CMAKE_CXX_STANDARDに最近の(CMake 3.8、CMake 3.11)に17と20の値が追加されたことを考慮して、 David Grayson's answer を拡張します。

IF (CMAKE_VERSION VERSION_LESS "3.8")
    SET(CMAKE_CXX_STANDARD 14)
ELSEIF (CMAKE_VERSION VERSION_LESS "3.11")
    SET(CMAKE_CXX_STANDARD 17)
ELSE() # CMake 3.11 or higher:
    SET(CMAKE_CXX_STANDARD 20)
ENDIF()
# Typically, you'll also want to turn off compiler-specific extensions:
SET(CMAKE_CXX_EXTENSIONS OFF)

(リンクされたanwswerのset (CMAKE_CXX_STANDARD 11)の代わりにそのコードを使ってください)。

1
codeling