cmake CMAKE_BUILD_TYPE

发布时间 2023-04-03 15:43:54作者: ploolq

https://stackoverflow.com/questions/24460486/cmake-build-type-is-not-being-used-in-cmakelists-txt

There are two types of generators: single-configurations and multi-configurations.

1. Single configurations

Make-like generators: Unix Makefiles, NMake Makefiles, MinGW Makefiles, ...

You set the configuration type in the generate step:

cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"

In this case, the build step is always Debug:

> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...

2. Multi-configuration

IDE generators: Visual Studio, Xcode

CMAKE_BUILD_TYPE on generate step is ignored,

CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_BUILD_TYPE

both:

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"

and

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"

will have the same effect:

This is because all the configurations is internal (i.e., _builds/msvc-opaque/Release and _builds/msvc-opaque/Debug or something, doesn't matter).

You can use --config options to switch:

> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...

3. Control

Yes, you can. Just define CMAKE_CONFIGURATION_TYPES:

# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

Default output:

-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done

Rewrite it:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done

You can even define your own configuration type:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"

And build:

    cmake --build _builds --config MyRelease

4. Messy (?)

Not at all if you know the trick ? This is how to build/test configuration in a script/CI server/documentation's build instructions, etc.:

> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile

Bad pattern

if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...

Good one

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")

Works nice.

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")

Thank you! ? You save a day for one programmer.

Works for me with Makefile, I'm happy ...

Some quote from a nice book of a nice guy you probably know (emphasis mine):

Why should you bother? People who program on a variety of systems or use a variety of compilers care a lot because if they don’t, they are forced to **waste time** finding and fixing obscure bugs. People who claim they **don’t care** about portability usually do so because they use only a single system and feel they can afford the attitude that ‘‘the language is what my compiler implements.’’ This is a **narrow** and **shortsighted** view. If your program is a success, it is likely to be ported, so someone will have to find and fix problems related to implementation dependent features. In addition, programs often need to be compiled with other compilers for the same system, and even a future release of your favorite compiler may do some things differently from the current one. It is far easier to know and limit the impact of implementation dependencies when a program is written than to try to untangle the mess afterwards.

origin

https://stackoverflow.com/questions/24460486/cmake-build-type-is-not-being-used-in-cmakelists-txt

answered Jun 28, 2014 at 21:11
user2288008

edited Aug 31, 2019 at 15:51
Peter Mortensen