Debug VS Release in Cmake

Debug vs Release in CMake

With CMake, it's generally recommended to do an "out of source" build. Create your CMakeLists.txt in the root of your project. Then from the root of your project:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make

And for Debug (again from the root of your project):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

Release / Debug will add the appropriate flags for your compiler. There are also RelWithDebInfo and MinSizeRel build configurations.


You can modify/add to the flags by specifying a toolchain file in which you can add CMAKE_<LANG>_FLAGS_<CONFIG>_INIT variables, e.g.:

set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")

See CMAKE_BUILD_TYPE for more details.


As for your third question, I'm not sure what you are asking exactly. CMake should automatically detect and use the compiler appropriate for your different source files.

What are CMAKE_BUILD_TYPE: Debug, Release, RelWithDebInfo and MinSizeRel?

RelWithDebInfo is the same as Release, allowing you to have symbol files for debugging.

For example in Visual Studio, you'll have .pdb files and without them, it'll be hard to debug because all the signatures in the binary files are not going to be human readable and there's no way to map them to the source code.

MinSizeRel is the same as Release, with its optimization configuration just set to Minimize Size instead of Maximize Speed as illustrated in this link in Visual Studio, for example.

If I want to generate a production build, should I choose Release?

Yes, that should do the right job for you. Debug/Release are the most commonly used options.

Reading this CMAKE FAQ will actually help you a lot.

CMake conditional for Release,Debug and Etc

Variable CMAKE_BUILD_TYPE has no sense with multiconfiguration generators, and Visual Studio is one of such generators.

Canonical way for define in CMake a pre-built library which have different locations for different configuration is to create IMPORTED library target with several properties IMPORTED_LOCATION_<CONFIG> to be set:

add_library(thirdPartyLib IMPORTED UNKNOWN)
set_target_properties(thirdPartyLib PROPERTIES
IMPORTED_LOCATION_RELEASE
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/release/libalpha.a
IMPORTED_LOCATION_DEBUG
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/debug/libalpha.a
)

Then you need to create a mapping between build types of the main project and build types of the IMPORTED target.

Such mapping could be created either on per-target basis, by setting properties MAP_IMPORTED_CONFIG_<CONFIG>:

set_target_properties(thirdPartyLib PROPERTIES
# For Debug version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_DEBUG DEBUG
# For Release version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_RELEASE RELEASE
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG
# For MinSizeRel version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
)

Alternatively, the mapping could be created for all IMPORTED targets by setting variables CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>. Note, that these variables should be set before creation of IMPORTED target(s).

# For Debug version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG DEBUG)
# For Release version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE RELEASE)
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG)
# For MinSizeRel version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE)

Having IMPORTED libraries and configurations mapping, using these libraries is quite straightforward:

target_link_libraries(my_exe PRIVATE thirdPartyLib)

Depending on the build type of the project, CMake will automatically select proper library for linking.

Detect build type (debug/release) in visual studio when using CMake

You may want to use generator expressions here. They are evaluated at build time and therefore the build type is set even for multi-configuration generators as Visual Studio or Xcode.

target_compile_definitions(OverEngine
PRIVATE
_CRT_SECURE_NO_WARNINGS
GLFW_INCLUDE_NONE
PUBLIC
$<$<CONFIG:Debug>:OE_DEBUG>
$<$<CONFIG:RelWithDebInfo>:OE_DEBUG>
$<$<CONFIG:Release>:OE_RELEASE>
$<$<CONFIG:MinSizeRel>:OE_RELEASE>
)

Cmake create a Makefile supports debug and release with different configuration

In this CMakeLists.txt file you set up a second version of the project during the configuration of the original project that is responsible for generating another version of the project for the release version. There are several drawbacks to this approach:

  • Doesn't deal with multi configuration generators(e.g. Visual Studio), properly
  • It sets up the release configuration twice, if you pass -DCMAKE_BUILD_TYPE=Release to the original setup.
  • It shares the same binary directory; This could very easily mess up the project badly

My recommendation would be to use generator expressions in all places where they are allowed

target_link_libraries(my_target PRIVATE
$<$<CONFIG:Release>:libLinkedInReleaseOnly>
$<$<CONFIG:Debug>:libLinkedInDebugOnly>
)

# define preprocessor macro containg the configuration name
target_compile_definitions(my_target PRIVATE MY_CONFIG_DEFINE=\"$<CONFIG>\")

and fall back to versions of properties and variables that are configuration dependent (i.e. include <CONFIG> in the linked lists) and setting up projects in multiple build directories with different configurations.

#bash example
for CONFIG in Debug Release
do
mkdir $CONFIG
cmake -D CMAKE_BUILD_TYPE=$CONFIG -S . -B $CONFIG
done

which allows you to do cmake --build Debug or cmake --build Release to build debug or release configurations of your project respectively. (You may want to set this up in a location different to the source dir btw which would require you to pass a different path as -S parameter.)

How to build CMake Debug version using different target name for executables?

You are not missing anything. As the documentation says (emphasis mine):

When a non-executable target is created its <CONFIG>_POSTFIX target property is initialized with the value of this variable if it is set.

See: https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIG_POSTFIX.html

By the sounds of it, though, you could manually set the property on your executable target with set_target_properties:

set_target_properties(
target1 ... targetN
PROPERTIES
DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}"
)

Note, however, that it doesn't apply to executables by default because that's rarely what you want. For libraries, it's fairly common to package and deploy debug and release configurations simultaneously. On Windows, for development, it is a requirement. On the other hand, one very rarely needs to deploy debug applications and hence one very rarely wants a postfix applied.



Related Topics



Leave a reply



Submit