Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: What do CMake build types (DCMAKE_BUILD_TYPE) do?

Tags:

c++

c

cmake

clion

I am using CMake (within CLion IDE but that should not matter for this discussion). Up until now I have been using things like set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") or set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") to set compiler options for GCC. I assume CMake passes these on directly to the compiler. However, CMake is supposed to be platform independent and (at least in principle) able to build the same code using different compilers. Does this mean one should do it differently?

I have been thinking about using build configurations. For example, I assume calling CMake with a build type flag:

cmake .. -DCMAKE_BUILD_TYPE="Release"

enables some optimization. I was unable, however, to find any documentation on what exactly this flag does (maybe because it depends on things like the compiler being used). I have two questions:

  1. What does -DCMAKE_BUILD_TYPE="Release" (and other release types) do (as exactly as one can tell not knowing the system where the build happens)?
  2. What is the best way to view the compiler and all options actually being used at build time (both using CMake in command line and within an IDE like CLion) ?

Reading the makefile generated by CMake to find the flags does not seem like an option to me. I tried setting VERBOSE=yes for Make but somehow it didn't give me compiler flags, just some "entering end exiting directories".

like image 298
Adomas Baliuka Avatar asked Oct 26 '25 07:10

Adomas Baliuka


2 Answers

  1. What does -DCMAKE_BUILD_TYPE="Release" (and other release types) do (as exactly as one can tell not knowing the system where the build happens)?

It enables certain compiler options defined in the core CMake modules, which are specific to the target system. The documentation doesn't exactly explain what each of the build types mean, but the names are fairly commonly used. I understand Release to mean "disable debugging, enable highest optimisation".

For example, the module Modules/Compiler/GNU.cmake contains following:

string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG")

  1. What is the best way to view the compiler and all options actually being used at build time (both using CMake in command line and within an IDE like CLion) ?

One convenient way is the compilation database. The format is specified here and it is enabled with the option CMAKE_EXPORT_COMPILE_COMMANDS. The file compile_commands.json will then contain the exact commands used to compile each file.

Figuring out the compiler may need additional steps if the alias /usr/bin/c++ is used, as is common.


P.S. In many cases, it may be useful to enable debugging in release mode. While RELWITHDEBINFO does that, it doesn't enable highest optimisation (-O2 with GCC). As such, I personally find the default choices lacking.

like image 110
eerorika Avatar answered Oct 28 '25 21:10

eerorika


It makes you switch between "Debug" and "Release" configuration. What does it mean? There are default compile flags for each language and configuration

CMAKE_<LANG>_FLAGS_<CONFIG>

Changing from Debug to Release you are changing flags that CMake will use to set CMAKE_CXX_FLAGS.

Setting directly cmake flags "set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")" is not a best practice in modern cmake (version >= 3).

Why?

The modern CMake is about targets and properties. If you set flags in your project, that flags can affect other projects. (And in a huge code base it happens) So it's very important to take care of the visibility of variables and flags. Consider using target_compile_features, target_compile_options and target_compile_definitions. It makes your code more readable and less error-prone

like image 37
Equod Avatar answered Oct 28 '25 22:10

Equod



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!