47

CMakeLists.txt に次のコンテンツがあります。

project( Matfile )

SET ( CMAKE_CXX_FLAGS "-std=c++0x" )

set ( SOURCES
      "foo.cpp"
      "bar.cpp"
    )

add_library(
        Matfile
        ${SOURCES}
)

ご想像のとおり、私がやりたいことは、フラグ -std=c++0x を使用して C++ ソースをコンパイルすることです (gcc を使用しており、C++11 機能が必要です)。残念ながら、cmake を使用してメイクファイルを生成すると、変数 CMAKE_CXX_FLAGS が完全に無効になるという意味で、これは機能しません。

プロジェクト ファイルでこの変数を設定するにはどうすればよいですか?

非常にばかげた質問のようですが、これを理解するのに 2 時間以上費やしました。

4

11 に答える 11

61

add_compile_options()バージョン 2.8.12 以降を使用している場合は、最も簡単な解決策を使用する必要があります。古いバージョンの場合、「悪用」できますadd_definitions()。add -D フラグのみを対象としていますが、他のコンパイラ フラグでも機能します。ただし、そのように使用することを意図したものではなく、将来のバージョンで壊れる可能性があると思います.

add_compile_options(-std=c++0x) # CMake 2.8.12 or newer

また

add_definitions(-std=c++0x) # CMake 2.8.11 or older

CMake 3.3 から、奇妙なジェネレータ式の構文を使用して、このフラグを特定の言語 (たとえば、C または C++ のみ) にのみ適用することもできます。

 add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++14> $<$<COMPILE_LANGUAGE:C>:-std=c99>)

ただし、これはVisual Studio ジェネレーターでは機能しないため、これを Make/Ninja ジェネレーターにのみ使用するか、target_compile_options()を使用してターゲットごとのスコープに設定してください。

于 2014-02-04T19:35:38.747 に答える
27

CMake 3.1 以降で C++ 標準を設定する正しい方法は次のとおりです。

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED on)

1 つの個々のターゲットに対して標準を指定することもできます。

set_property(TARGET mylib PROPERTY CXX_STANDARD 11)

CMake 3.8 以降、ターゲットに必要な標準を設定できる新しいオプションがtarget_compile_featuresコマンドに追加されました。

target_compile_features(mylib PUBLIC cxx_std_11)

利点は、要件が依存ターゲットに伝播されることです。必要な機能を備えたライブラリをコンパイルすると、cxx_std_11それにリンクするすべてのバイナリに、この要件セットが自動的に設定されます。

于 2017-09-20T19:32:54.423 に答える
14

FORCEフラグを使用すると役立ちますか?

SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)
于 2013-02-27T01:06:21.683 に答える
5

おそらくこれはうまくいくでしょう:

set_source_files_properties(${SOURCES}
       PROPERTIES
       COMPILE_FLAGS  "-std=c++0x")
于 2013-02-26T22:17:39.267 に答える
3

ar31 によるジェネレーター式の回答で ADD_COMPILE_OPTIONS() を少し拡張するには、cmake にはジェネレーター式に厄介なバグがあるため、スペースで区切られた複数のフラグを追加するときに問題が発生する可能性があります。

私が使用したソリューションは FOREACH ループでした。これは、私が取り組んでいるプロジェクトの例です。

IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # common flags
    SET(MY_C_AND_CXX_FLAGS -mtune=generic -pipe -fPIC -Wformat -Wformat-security -fomit-frame-pointer -fstack-protector-strong --param ssp-buffer-size=4 -fexceptions -D_FORTIFY_SOURCE=2 -feliminate-unused-debug-types)

    SET(MY_C_FLAGS   ${MY_C_FLAGS}   ${MY_C_AND_CXX_FLAGS})
    SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} ${MY_C_AND_CXX_FLAGS})

    IF(MINGW)
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -static-libgcc)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -static-libgcc -static-libstdc++)
    ENDIF(MINGW)

    IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -g2 -Wall)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -g2 -Wall)
    ELSE()
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -O2 -Wno-error)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -O2 -Wno-error)
    ENDIF()

    FOREACH(C_COMPILE_FLAG ${MY_C_FLAGS})
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C>:${C_COMPILE_FLAG}>)
    ENDFOREACH()

    FOREACH(CXX_COMPILE_FLAG ${MY_CXX_FLAGS})
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:${CXX_COMPILE_FLAG}>)
    ENDFOREACH()

    # for the gcc -fstack-protector* flags we need libssp
    # clang does not have this
    IF(CMAKE_COMPILER_IS_GNUCXX)
        SET(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lssp")
        SET(CMAKE_C_LINK_EXECUTABLE   "${CMAKE_C_LINK_EXECUTABLE}   -lssp")
    ENDIF()
ENDIF()

# Assembler flags

IF(ASM_ENABLED)
    FOREACH(ASM_FLAG -I${CMAKE_SOURCE_DIR}/src/filters/hq/asm/ -O1 -w-orphan-labels)
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:ASM_NASM>:${ASM_FLAG}>)
    ENDFOREACH()
ENDIF(ASM_ENABLED)
于 2016-11-20T19:31:29.410 に答える
2

コンパイラに特定の標準が必要な特定のケースでは、cmake 3.1 は標準バージョンまたは一連のコンパイラ機能を要求する方法を提供することで問題を解決します。この回答公式ドキュメントを参照してください。

于 2015-04-27T16:43:04.173 に答える
1

ucmのucm_add_flagsおよびucm_print_flagsマクロをチェックアウトして、適切な cmake 変数にコンパイラ フラグを追加し、結果を検査します。

于 2016-10-05T21:22:32.733 に答える