web-dev-qa-db-ja.com

cmakeはC ++ 11標準にコンパイルされません

私はC++を初めて使用し、コンパイル/作成/リンク/構築/その他に苦労していますが、誰かが私を助けてくれるかどうかを確認しましょう。私はいくつかの検索を行い、同様の問題を抱えている他の人を見つけましたが、運が悪かったので解決策を試しました。

均一な初期化、スレッド、_to_string_などのC++ 11機能を使用する単純なc ++プログラムは、スコープで宣言されなかった "xxx"というエラーを生成します。具体的には、今すぐ_to_string_を使用したいのですが、std名前空間で使用するか、具体的には_std::to_string_を使用するとエラー "to_string"が作成されますSTDのメンバーではありません。したがって、明らかにC++ 11でコンパイルされていません。

だからここに私のメイクファイルがあります:

_#####################################
cmake_minimum_required (VERSION 2.8)
project (raspicam_test)
find_package(raspicam REQUIRED)
find_package(OpenCV)

IF  ( OpenCV_FOUND AND raspicam_CV_FOUND)
        MESSAGE(STATUS "COMPILING OPENCV TESTS")
        add_executable (main main.cpp)
        #target_compile_features(main PRIVATE cxx_range_for)
        set_property(TARGET main PROPERTY CXX_STANDARD 11)
        target_link_libraries (main ${raspicam_CV_LIBS})
ELSE()
        MESSAGE(FATAL_ERROR "OPENCV NOT FOUND IN YOUR SYSTEM")
ENDIF()
#####################################
_

ご覧のとおり、Raspberry PiでOpenCVをいじっています。ただし、C++ 11関数がないと、プログラムはコンパイルされ、問題は発生しません。しかし、C++ 11からスレッドやその他の機能を追加したいと思います。 CMAKEのドキュメントに従ってset_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11)行を追加しました:

https://cmake.org/cmake/help/v3.1/prop_tgt/CXX_STANDARD.html

そして、生成されたエラーに違いはありませんでした。最初に__REQUIRED_を使用せずに、次に使用しました。代わりにtarget_compile_features()も試しましたが、CMAKEは「不明なCMAKEコマンド」で戻りました。

その他の詳細:-Debian jessieを実行しているRaspberry Pi 3でのコンパイル-CXXコンパイラはGNU 4.9.2 -CMAKE 3.0.2

8
DrTarr

CMakeバージョン3.1よりも前では、

_ add_compile_options(-std=c++11) # CMake 2.8.12 or newer
_

CMake Docs で説明されているように、コンパイラ呼び出しにコンパイルオプションを追加します。

それは、アルバロの答えにあるものほどポータブルではないかもしれませんが、より読みやすく、RasPiを使用しているので、ターゲットコンパイラと同じようにGCCとClangを使用します。

Edit:完全を期すために:CMakeバージョン3.1以降 、C++ 11を強制する場合は、次の行が必要です。

_set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
_

これにより、コンパイル中にすべてのターゲットのオプションが有効になります。これをよりきめ細かく制御したい場合は、アルバロの答えまたはset_taget_properties()のCMake Docsをご覧ください。

_set_target_properties(myTarget PROPERTIES
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)
_

Edit:しかし、GCC 4でのC++ 11サポートは完全ではなく、定義された標準とは異なる動作をする可能性があることに注意してください。

30
Bugfinger

CMakeは、3.1バージョンでCXX_STANDARDおよびCXX_STANDARD_REQUIREDプロパティのサポートを追加します。 CXX_STANDARDCMAKE_CXX_STANDARD値の1つを取ります。これらの値は98, 11 and 14です。 CXX_STANDARD 11を渡し、コンパイラがc ++ 11をサポートしていない場合、CXX_STANDARDは自動的に98になり、CXX_STANDARD_REQUIREDOFFであるか設定されていない場合、cmakeはエラーを表示しません。セットCXX_STANDARD_REQUIRED "ON" CXX_STANDARD固有の値が、ビルドおよびcmakeがこれを処理するために必要なプロパティになる場合。

CHECK_CXX_COMPILER_FLAGを使用して、CheckCXXCompilerFlagモジュールを含めるように調整しました。

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
    message(STATUS "${COMPILER_SUPPORTS_CXX11}")
else(COMPILER_SUPPORTS_CXX11)
    message(FATAL_ERROR "${COMPILER_SUPPORTS_CXX11}")
endif(COMPILER_SUPPORTS_CXX11)

古いcmakeがある場合は、コンパイラーからの移植性のない複雑なフラグを処理する必要があります。

function(suported_compilers)
  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
    execute_process(
      COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
    if(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
      message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
    endif(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  else()
    message(FATAL_ERROR "Your compiler is supported in the build set?, please "
                  "contact the maintainer.")
  endif()
endfunction(suported_compilers)
function(set_targets_compilers_flags target_list)
  suported_compilers()
  foreach(tg ${target_list})
    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "-g -std=c++14 -Wall -Wextra -Werror")
    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "/W4 /WX /EHsc")
    endif()
  endforeach()
endfunction(set_targets_compilers_flags)
4

現在のcmakeリリースは3.10であるため、新しいメソッドを特定することが適切であると考えました。 add_compiler_を使用する提案が

ここで最新バージョンのcmake(3.1+)を探している人にとって、最も適切な答えは、特定のコンパイラーのバージョンを特定するのではなく、CMAKEに使用可能な機能を知らせることです。

target_compile_features(engine
    PRIVATE cxx_range_for
    )
0
Brian Bruggeman

この方法でCMakeを使用して、コードでc ++ 11を常に有効にします。

set(CMAKE_CXX_FLAGS "-std=c++11")

私のコンパイラはgcc(Debian 4.9.2-10)4.9.2ですが、職場では他のバージョンも使用しており、このアプローチは常に機能します。

編集(変数の上書きを避けるため):

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