How do I add a linker or compile flag in a CMake f

2019-01-02 16:48发布

I am using the arm-linux-androideabi-g++ compiler. When I try to compile a simple "Hello, World!" program it compiles fine. When I test it by adding a simple exception handling in that code it works too (after adding -fexceptions .. I guess it is disabled by default).

This is for an Android device, and I only want to use CMake, not ndk-build.

For example - first.cpp

#include <iostream>

using namespace std;

int main()
{
   try{
   }
   catch(...)
   {
   }
   return 0;
}

./arm-linux-androideadi-g++ -o first-test first.cpp -fexceptions

It works with no problem...

The problem ... I am trying to compile the file with a CMake file.

I want to add the -fexceptions as a flag. I tried with

set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" )

and

set ( CMAKE_C_FLAGS "fexceptions")

It still displays an error.

标签: cmake
5条回答
初与友歌
2楼-- · 2019-01-02 17:25

In newer versions of CMake you can set compiler and linker flags for a single target with target_compile_options and target_link_libraries respectively (yes, the latter sets linker options too):

target_compile_options(first-test PRIVATE -fexceptions)

The advantage of this method is that you can control propagation of options to other targets that depend on this one via PUBLIC and PRIVATE.

As of CMake 3.13 you can also use target_link_options to add linker options which makes the intent more clear.

查看更多
情到深处是孤独
3楼-- · 2019-01-02 17:27

You can also add linker flags to a specific target using the LINK_FLAGS property:

set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}")

If you want to propagate this change to other targets, you can create a dummy target to link to.

查看更多
后来的你喜欢了谁
4楼-- · 2019-01-02 17:40

Checkout the ucm_add_flags and ucm_add_linker_flags macros of ucm (my set of useful CMake macros) - they deal with appending compiler/linker flags.

查看更多
公子世无双
5楼-- · 2019-01-02 17:43

Suppose you want to add those flags (better to declare them in a constant):

SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS    "-lgcov")

There are several ways to add them:

  1. The easiest one (not clean, but easy and convenient, and works only for compile flags, C & C++ at once):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
    
  2. Appending to corresponding CMake variables:

    SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
    SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
    
  3. Using target properties, cf. doc CMake compile flag target property and need to know the target name.

    get_target_property(TEMP ${THE_TARGET} COMPILE_FLAGS)
    if(TEMP STREQUAL "TEMP-NOTFOUND")
      SET(TEMP "") # Set to empty string
    else()
      SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content
    endif()
    # Append our values
    SET(TEMP "${TEMP}${GCC_COVERAGE_COMPILE_FLAGS}" )
    set_target_properties(${THE_TARGET} PROPERTIES COMPILE_FLAGS ${TEMP} )
    

Right now I use method 2.

查看更多
若你有天会懂
6楼-- · 2019-01-02 17:45

Try setting the variable CMAKE_CXX_FLAGS instead of CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

The variable CMAKE_C_FLAGS only affects the C compiler, but you are compiling C++ code.

Adding the flag to CMAKE_EXE_LINKER_FLAGS is redundant.

查看更多
登录 后发表回答