Cmake - set the global linker flag (for all purposes in the directory)

I want to pass linker flags to all subprojects (CMakeList subdirectory) in my project.

Prior to upgrading to the new cmake 3.3, I used the following code (cmake 3.2) that worked well, adding flags for both compilation and linking:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -stdlibc++") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -stdlibc++") 

With cmake 3.3, this no longer works and sets flags only for the compilation phase. I updated CMakeList to use the more "modern" cmake syntax:

 set(MY_DEBUG_OPTIONS -g -stdlib=libstdc++ -Wfatal-errors) set(MY_RELEASE_OPTIONS -O3 -stdlib=libstdc++ -Wfatal-errors) add_compile_options( "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>" "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>") 

This set of compilation flags for all subprojects, is there a similar way to do this for linker flags? I know that you can add linker flags on a target basis with the target_link_libraries , but cannot find anything.

I tried using the variable CMAKE_SHARED_LINKER_FLAGS (and the corresponding variable for exe, module, ..) without success.

Update:

It turns out that this has nothing to do with the cmake version, everything works correctly with the CMAKE_CXX_FLAGS_XXX variables, except for the first make command. If you run make second time (with a modification in CmakeList), the flags will be presented.

I think I found a solution when testing with a simple CMakeList: if flags are declared after the project command, it works as expected. I don’t know if this is a requirement from cmake itself or just weird behavior.

 cmake_minimum_required (VERSION 3.2) set(PROJECT Test_Project) # Not working (on first run) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libstdc++ -Wfatal-errors") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -stdlib=libstdc++ -Wfatal-errors") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -stdlib=libstdc++ -Wfatal-errors") project(${PROJECT}) # Declare here instead... add_executable(Test test.cpp) MESSAGE( STATUS "Config flags : " ${CMAKE_CXX_FLAGS_RELEASE}) 

Using:

 cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release . 
+4
c ++ linker cmake
Sep 21 '15 at 15:05
source share
1 answer

Your problems are related / not related to a specific version of CMake.

This is the same for all linker / compiler flag variables in CMake. Since these variables are cached variables and are set using the project() / enable_language() see details here ), you either need to

  • pre-populate the cache with set(... CACHE ...) before the project() command
  • usually use set(... CACHE ... FORCE) to force / overwrite
  • move set() after the project() command to hide or add to cached variables

Here is an example for CMAKE_EXE_LINKER_FLAGS showing all three options:

CMakeLists.txt

 cmake_minimum_required(VERSION 2.8) # 1. prefill #set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "") project(Test_Project CXX) # 2. force set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE) # 3. hide #set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map") # 3. or append #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=output.map") # TODO: Remove, this is just for testing file(WRITE "foo.cpp" "int main() {}") add_executable(${PROJECT_NAME} foo.cpp) 

No matter what the values ​​of these variables are at the end of your given CMakeLists.txt file, they will be applied to all the corresponding targets in the same CMakeLists.txt file as by default (see CMAKE - setting compilation flags for libraries and What is the syntax CMake to set and use variables? ).

The first option has the disadvantage that it is really only the initial value. The second and third options most likely need an if (CMAKE_COMPILER_IS_GNUCXX) around it, so I prefer the second option with moving these parameters to my own initial cache file:

MyGNUSettings.cmake

 set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -Wfatal-errors" CACHE INTERNAL "" FORCE) set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE INTERNAL "" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "" FORCE) set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE) 

Use for example

 cmake -G "Unix Makefiles" -C MyGNUSettings.cmake -DCMAKE_BUILD_TYPE=Release . 

And yes - for global and for compiler options - I prefer global cached variables with the add_compile_options() command. I think add_compile_options() did not replace global variables, it was mainly done to prevent people from adding compiler parameters to add_definitions() commands.

+2
Sep 22 '15 at 10:58
source share



All Articles