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時間以上を費やしました。
バージョン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() を使用してターゲットごとに設定してください範囲。
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
必須機能を使用してライブラリをコンパイルする場合、それにリンクするバイナリにはこの要件が自動的に設定されます。
FORCE
フラグを使用すると役立ちますか?
SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)
おそらくこれはうまくいくでしょう:
set_source_files_properties(${SOURCES}
PROPERTIES
COMPILE_FLAGS "-std=c++0x")
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)
cm_add_flags および cm_print_flags のマクロをチェックアウトします cm のマクロ-適切なcmake変数にコンパイラフラグを追加し、結果を検査します
これは私が現在使用しているソリューションです:
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")
私は、古いバージョンの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})