web-dev-qa-db-ja.com

プロジェクトのCMAKE_CXX_FLAGSを変更する

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を使用してmakefileを生成すると、変数CMAKE_CXX_FLAGSは完全に無効になるという意味で、これは機能しません。

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

それは非常にばかげた質問のように思えますが、私はこれを理解しようとして2時間以上を費やしました。

39
Spiros

バージョン2.8.12以降を使用している場合、最も簡単な解決策は add_compile_options() を使用することです。古いバージョンでは、「乱用」することができます add_definitions() 。 -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() を使用してターゲットごとに設定してください範囲。

51
ar31

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必須機能を使用してライブラリをコンパイルする場合、それにリンクするバイナリにはこの要件が自動的に設定されます。

14
Cris Luengo

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

SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)
13

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

set_source_files_properties(${SOURCES}
       PROPERTIES
       COMPILE_FLAGS  "-std=c++0x")
5

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)
3
Rafael Kitover

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

2
Spiros

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

1
onqtam

これは私が現在使用しているソリューションです:

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

または、古いバージョンのcmakeがあり、それをcmake-guiで表示したい場合:

set_property(CACHE CMAKE_CXX_FLAGS PROPERTY VALUE "-std=c++0x")
0
user2364011

私は、古いバージョンのcmakeで機能するより良い方法を考え出しました。 Ubuntu 14には2.8.12があり、ターゲット式は3.3機能です。

C++固有のフラグを設定する方法は次のとおりです。

STRING(REGEX REPLACE "<FLAGS>" "<FLAGS> -std=gnu++11 -fpermissive -fexceptions " CMAKE_CXX_COMPILE_OBJECT ${CMAKE_CXX_COMPILE_OBJECT})
0
Rafael Kitover