Skip to content

Last updated:2026-10-12

CMake Essentials in Practice

CMake Essentials, Part One

1.Setting Compiler Flags

For example: setting the C++ standard and showing all warnings.

set(CMAKE_CXX_FLAGS "-std=c++0x -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
add_compile_options("$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-std=c++11>")

You can also set some optimization flags.

Official documentation: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

For example:

-O0, -O1, -O2, -O3

If you use LLVM, you can refer to this:

https://clang.llvm.org/docs/DiagnosticsReference.html

2.Setting Source File Properties

This is one of CMake's more complex features: when multiple targets exist, you may need to change the behavior of only one target. For example, if you want to build main.cpp with C++11 while building the library itself as C++14, you can use the set_source_files_properties command to configure the properties of specific source files, as shown below:

cmakeCopy code
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/*.cpp PROPERTIES COMPILE_FLAGS "-std=c++11")

You can browse a large number of properties in the following manual; each of them can be used to meet your specific needs.

https://cmake.org/cmake/help/v3.3/manual/cmake-properties.7.html#source-file-properties

3.Linker Flags

The following is a list of linker flags for the GNU GCC linker.

GNU GCC link options

https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

By default, the GCC linker can search the directories defined in environment variables (/usr/lib; /usr/local/lib) and then links the standard libraries by default.

One of the most common flags is -l, used to link the required libraries, such as -lzlib, -lboost, and so on.

There are also additional flags that help you change the linking-option behavior of your executable.

The following are the variables to which you can add linker flags:

  • CMAKE_EXE_LINKER_FLAGS: flags used by the linker when creating executables
  • CMAKE_EXE_LINKER_FLAGS_RELEASE: flags used by the linker when creating release executables
  • CMAKE_EXE_LINKER_FLAGS_DEBUG: flags used by the linker when creating debug executables
  • CMAKE_STATIC_LINKER_FLAGS: flags used by the linker when creating static libraries (.a, .lib)
  • CMAKE_SHARED_LINKER_FLAGS: flags used by the linker when creating shared libraries (.so, .dll)
  • CMAKE_MODULE_LINKER_FLAGS: flags used by the linker when creating module libraries

For example, you can add linker flags with the following code:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl")

Knowing how to use these flags helps you better control the linking behavior of your executables.

4.Debug and Release Builds

Inside the CMakeLists.txt file, you can access CMAKE_BUILD_TYPE. You can easily check the build type in CMakeLists.txt:

if(${CMAKE_BUILD_TYPE} MATCHES Debug)
    message("Debug Build")
elseif(${CMAKE_BUILD_TYPE} MATCHES Release)
    message("Release Build")
endif()

You can also use the configuration variables shown in the previous section to set compiler and linker flags separately for the different build types:

  • CMAKE_EXE_LINKER_FLAGS_RELEASE: flags used to create release executables
  • CMAKE_EXE_LINKER_FLAGS_DEBUG: flags used to create debug executables
  • CMAKE_CXX_FLAGS_RELEASE
  • CMAKE_CXX_FLAGS_DEBUG

Comments