Search code examples
c++cmake

How do I add a linker or compile flag in a CMake file?


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.


Solution


  • Please be aware that due to the evolution of CMake since the writing of this answer in 2012, the majority of the recommendations provided here are now obsolete or no longer recommended, with improved alternatives available.


    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 compiler 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.