在项目中更改CMAKE_CXX_FLAGS

时间:2013-02-26 22:10:01

标签: cmake compiler-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完全无效。

如何在项目文件中设置此变量?

这似乎是一个非常愚蠢的问题,但我只花了不少于两个小时试图解决这个问题。

9 个答案:

答案 0 :(得分:47)

如果您使用的是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>)

但是这将是not work with the Visual studio generator,因此请确保仅将此用于Make / Ninja生成器,或使用target_compile_options()将其设置为每个目标范围。

答案 1 :(得分:14)

set the C++ standard in CMake 3.1 and later的正确方法是:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED on)

specify the standard for one individual target也可以:

set_property(TARGET mylib PROPERTY CXX_STANDARD 11)

从CMake 3.8开始,有一个new option to the target_compile_features command允许为目标设置所需的标准:

target_compile_features(mylib PUBLIC cxx_std_11)

优势在于它将需求传播到依赖目标。如果您使用cxx_std_11必需功能编译库,则链接到该库的任何二进制文件都将自动设置此要求。

答案 2 :(得分:13)

使用FORCE标志有帮助吗?

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

答案 3 :(得分:5)

也许这会更好:

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

答案 4 :(得分:2)

在需要编译器的特定标准的特定情况下,cmake 3.1通过提供请求标准版本或一组编译器功能的方法来解决该问题。请参阅this answerofficial documentation

答案 5 :(得分:2)

要使用生成器表达式answer by ar31在ADD_COMPILE_OPTIONS()上展开一点,当您想要添加由空格分隔的多个标志时,可能会遇到问题,因为cmake有nasty bug in generator expressions

我使用的解决方案是一个FOREACH循环,这是我正在研究的项目的一个例子:

cat /usr/local/var/postgres/server.log

答案 6 :(得分:1)

签出ucm_add_flagsucm_print_flagsucm宏 - 将编译器标志添加到相应的cmake变量并检查结果

答案 7 :(得分:0)

这是我目前使用的解决方案:

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")

答案 8 :(得分:0)

我在C ++ / clr项目中遇到这种情况,我需要在此修改两个变量-CMAKE_CXX_FLAGSCMAKE_CXX_FLAGS_DEBUG。可以使用CMAKE_CXX_FLAGS修改set_source_files_properties / COMPILE_FLAGS,但不能修改CMAKE_CXX_FLAGS_DEBUG。 我已经得出结论,要在单独的文件夹中创建单独的,项目特定的cmake文件。 如果项目是隔离的,则变量修改仅在当前的C ++ / clr项目中有效。

我想,如果您想拥有多个C ++项目和多个C ++ / clr项目,将它们至少分成两个不同的文件夹(如果不是更多的话)是有意义的-特定于本机C ++和特定于托管C ++。

您可以通过类似的方式在cmake测试应用程序中找到: https://github.com/Kitware/CMake/blob/master/Tests/CSharpLinkToCxx/CMakeLists.txt

这是同一件事,只是有更多解释:

# These variables affects also other C++ projects, that's why separate cmake for this c++ dll

# Clr compiling requires these:

# "Enable C++ Exceptions" - "Yes (/EHsc)" => "Yes with SEH Exceptions (/EHa)"
string(REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# "Basic Run-time checks" - "Both (/RTC1, equiv. to /RTCsu) (/RTC1)" => "Default"
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")

这是一种方法。但是,如果您想循环生成本机c ++和托管c ++项目-一种方法是禁用全局标志:

# Disable global flag, configure on per project basis, using target_compile_options, target_link_options
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/INCREMENTAL" "" CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
#string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

,然后为每个项目分别配置每个项目设置,例如:

if(${is_managed})
    # Managed C++ code
    set_target_properties(${project} PROPERTIES VS_GLOBAL_CLRSupport "true")
    set_property(TARGET ${project} PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2")

    # Being able to debug dll
    target_link_options(${project} PRIVATE "$<$<CONFIG:Debug>:/ASSEMBLYDEBUG>")

    # Disable incremental linking
    target_link_options(${project} PRIVATE "$<$<CONFIG:Debug>:/INCREMENTAL:NO>")

    # "Enable C++ Exceptions" - "Yes with SEH Exceptions (/EHa)"
    set(compile_flags /EHa)
else()
    # Native C++ code
    # "Basic Run-time checks" - "Both (/RTC1, equiv. to /RTCsu) (/RTC1)" => "Default"
    target_compile_options(${project} PRIVATE "$<$<CONFIG:Debug>:/RTC1>")

    # Enable incremental linking
    target_link_options(${project} PRIVATE "$<$<CONFIG:Debug>:/INCREMENTAL>")

    # "Enable C++ Exceptions" - "Yes (/EHsc)"
    set(compile_flags /EHsc)
endif()
set_target_properties(${project} PROPERTIES COMPILE_FLAGS ${compile_flags})