Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

cmake

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.

like image 527
solti Avatar asked Aug 02 '12 18:08

solti


People also ask

How do you attach a linker flag?

Right-click the target in the Xcode Groups and Files list and select Get Info from the contextual menu. In the Build tab, type linker into the search field and then locate the Other Linker Flags item. Double-click the Other Linker Flags item and add -lgmp .

What is Flag in CMake?

CMake will compute the appropriate compile flags to use by considering the features specified for each target. Such compile flags are added even if the compiler supports the particular feature without the flag. For example, the GNU compiler supports variadic templates (with a warning) even if -std=gnu++98 is used.

Can CMake compile?

CMake can generate a native build environment that will compile source code, create libraries, generate wrappers and build executables in arbitrary combinations.


2 Answers

Note: Given CMake evolution since this was answer was written, most of the suggestions here are now outdated/deprecated and have better alternatives


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.

like image 75
Offirmo Avatar answered Sep 26 '22 02:09

Offirmo


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.

like image 21
vitaut Avatar answered Sep 24 '22 02:09

vitaut