Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake
I just wanted to add the four possibilities I see:
Having your own toolchain files containing the presets for each compiler you support like:
GNUToolchain.cmake
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")
And then use it with
cmake -DCMAKE_TOOLCHAIN_FILE:string=GNUToolchain.cmake ...
You can try to determine the compiler by checking
CMAKE_GENERATOR
(which is valid before theproject()
command):CMakeLists.txt
if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR
("${CMAKE_GENERATOR}" MATCHES "Ninja" AND NOT WIN32))
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "")
endif()
project(your_project C CXX)You can use
CMAKE_USER_MAKE_RULES_OVERRIDE
to give a script with your own..._INIT
values:It is loaded after CMake’s builtin compiler and platform information modules have been loaded but before the information is used. The file may set platform information variables to override CMake’s defaults.
MyInitFlags.cmake
# Overwrite the init values choosen by CMake
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-ggdb3 -O0")
endif()CMakeLists.txt
set(CMAKE_USER_MAKE_RULES_OVERRIDE "MyInitFlags.cmake")
project(your_project C CXX)You can simplify your solution from March 1st by checking against the
..._INIT
variants of the compiler flag variables:CMakeLists.txt
project(your_project C CXX)
if (DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT AND
"${CMAKE_CXX_FLAGS_DEBUG_INIT}" STREQUAL "${CMAKE_CXX_FLAGS_DEBUG}")
# Overwrite the init values choosen by CMake
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3 -O0" CACHE STRING "" FORCE)
endif()
endif()
Comments:
I prefer and use the toolchain variant. But I admit it has the disadvantage of having to give the toolchain file manually (if you are not calling cmake
via a script/batch file).
References:
- CMake: In which order are files parsed (cache, toolchain, etc.)?
- cmake - Global linker flag setting (for all targets in directory)
- Switching between GCC and Clang/LLVM using CMake
In CMake, how do you change default compiler flags for a build type on a per-user basis?
I normally set compiler flags in cmakelists.txt by adding an environment variable into my build script, then referencing that in cmakelists.txt.
#build.sh
export MY_CXXFLAGS="-std=gnu++11 -Ofast -NDEBUG -Wall -Wno-unused-function -Wno-unknown-pragmas"
cmake `pwd` -Dtest=ON
make -j9
Then in my CMakeLists.txt, I'll have the following line:
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{MY_CXXFLAGS}")
It's simple then to pass arguments to build.sh, which is just a bash script, to change the content of MY_CXXFLAGS, based on the users needs. (E.g. build.sh -b DEVELOP|DEBUG|RELEASE etc).
CMake CMAKE_CXX_FLAGS enabled optimization unexpectly
With the code in your question you are hiding the default parameters - including the optimization level - that CMake does apply.
Please try appending your options with
SET ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd" )
or with the use of generator expressions and add_compile_options()
:
add_compile_options("$<$<CONFIG:Debug>:/MDd>")
But you may not need this particular option, because /MDd
is already part of CMake's default MSVC debug flag's setting.
Background
If you look at CMake's Windows-MSVC.cmake
you'll see the following initialization settings:
set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}")
Without changing any flags in your CMakeLists.txt
you will see in your CMakeCache.txt
:
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
With your code you are hiding this cached variable and you will end up with just /MDd
.
References
- What's the CMake syntax to set and use variables?
- cmake - Global linker flag setting (for all targets in directory)
- CMAKE - setting compile flags for libraries
- Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake
cmake - Global linker flag setting (for all targets in directory)
Your problems are/were not related to a specific CMake version.
It's the same for all linker/compiler flag variables in CMake. Because those variables are cached variables and set with the project()
/enable_language()
command (details see here), you either have to
- prefill the cache with
set(... CACHE ...)
before theproject()
command - generally use the
set(... CACHE ... FORCE)
to force/overwrite - move the
set()
after theproject()
command to hide or append to the cached variables
Here is an example for CMAKE_EXE_LINKER_FLAGS
showing all three variants:
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)
Whatever the values of those variables are at the end of your any given CMakeLists.txt
file will be applied to all corresponding targets in the same CMakeLists.txt
file as defaults (see CMAKE - setting compile flags for libraries and What's the CMake syntax to set and use variables?).
The first variant has the disadvantage that it's really only the initial value. The second and third variant would most likely need an if (CMAKE_COMPILER_IS_GNUCXX)
around it, so I prefer the second variant with moving those settings to its 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)
Using e.g.
cmake -G "Unix Makefiles" -C MyGNUSettings.cmake -DCMAKE_BUILD_TYPE=Release .
And yes - for the global and per compiler settings - I prefer the global cached variables over the add_compile_options()
command. I think add_compile_options()
haven't replaced the global variables, it was mainly introduced to prevent people putting compiler options in add_definitions()
commands.
How to enabled gdb -g3 debug level with CMake?
set the CMAKE_C_FLAGS "-Og -g3 ...
CMake AMRCC + custom linker
Apparently this is a bug in the cmake's armcc support, so I will keep my change in the ARMCC.cmake file.
Related Topics
Convert Std::Tuple to Std::Array C++11
Is It Legal to Compare Dangling Pointers
Explain Morris Inorder Tree Traversal Without Using Stacks or Recursion
Very Poor Boost::Lexical_Cast Performance
How to Generate a Random Double Uniformly Distributed Between 0 and 1 from C++
Why Is My Log in the Std Namespace
"Not Declared in This Scope" Error with Templates and Inheritance
Cin for an Int Inputing a Char Causes Loop That Is Supposed to Check Input to Go Wild
Microsecond Resolution Timestamps on Windows
Template Within Template: Why "'>>' Should Be '> >' Within a Nested Template Argument List"
Are Multiple Mutations of the Same Variable Within Initializer Lists Undefined Behavior Pre C++11
Std::Unique_Lock<Std::Mutex> or Std::Lock_Guard<Std::Mutex>
Automatic Perspective Correction Opencv
How to Sort a Std::Map First by Value, Then by Key