Changing CMAKE_CXX_FLAGS in project

2020-02-02 17:39发布

I have the following content in my CMakeLists.txt:

project( Matfile )

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

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

add_library(
        Matfile
        ${SOURCES}
)

As you may imagine, what I want to do is to compile my C++ sources using the flag -std=c++0x (I'm using gcc and I need the C++11 features). Unfortunately, this does not work, in the sense that, when I use cmake to generate the makefiles, the variable CMAKE_CXX_FLAGS is completely void.

How can I set this variable in the project file?

It seems to be a very stupid question, but I just spent not less than two houres trying to figure this out.

9条回答
叛逆
2楼-- · 2020-02-02 18:00

Perhaps this would work better:

set_source_files_properties(${SOURCES}
       PROPERTIES
       COMPILE_FLAGS  "-std=c++0x")
查看更多
女痞
3楼-- · 2020-02-02 18:05

checkout the ucm_add_flags and ucm_print_flags macros of ucm - to add compiler flags to the appropriate cmake variables and to inspect the results

查看更多
对你真心纯属浪费
4楼-- · 2020-02-02 18:06

The most straightforward solution should be using add_compile_options() if you are using version 2.8.12 or newer. For older versions you can "abuse" add_definitions(). While it is only meant for add -D flags, it also works with any other compiler flag. However, I think it is not meant to be used that way and could break in a future version.

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

or

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

Starting with CMake 3.3 you can also make this flag only apply to a specific language (e.g. only C or C++) using the strange generator expressions syntax:

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

However this will not work with the Visual studio generator, so make sure to only use this for Make/Ninja generators or use target_compile_options() to set it on a per-target scope.

查看更多
叛逆
5楼-- · 2020-02-02 18:09

Does it help to use the FORCE flag?

SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)
查看更多
贼婆χ
6楼-- · 2020-02-02 18:10

To expand a bit on the ADD_COMPILE_OPTIONS() with generator expression answer by ar31, you may run into a problem when you want to add multiple flags separated by spaces, as cmake has a nasty bug in generator expressions.

The solution I used was a FOREACH loop, here is an example from the project I'm working on:

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)
查看更多
该账号已被封号
7楼-- · 2020-02-02 18:11

The correct way to set the C++ standard in CMake 3.1 and later is:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED on)

It is possible to specify the standard for one individual target also:

set_property(TARGET mylib PROPERTY CXX_STANDARD 11)

Since CMake 3.8 there is a new option to the target_compile_features command that allows to set the required standard for a target:

target_compile_features(mylib PUBLIC cxx_std_11)

The advantage would be that it propagates the requirement to dependent targets. If you compile a library with the cxx_std_11 required feature, any binary that links to it will automatically have this requirement set.

查看更多
登录 后发表回答