1

I've worked in c++ for many years but I am new to CMake.

I build my app with

cmake --build build_dir --config Debug --target all -- -j 1

This works fine and builds the Debug version.

If I change the --config to anything else, for example Release with the following command:

cmake --build build_dir --config Release --target all -- -j 1

ninja says "no work to do" and exits. Running the compiled app it is clearly not optimised. There are two other options in this Cmake Project, RelWithDebug and MinSizeRel, and they act the same.

In CmakeLists.txt there is:

set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")

There are a lot of other mentions of the various types, but it's all slightly greek to me at this time.

What can I do to work out where the issue is?

Ðаn
  • 10,934
  • 11
  • 59
  • 95
Omroth
  • 883
  • 7
  • 24
  • 2
    Are you using the multiconfig ninja generator? In that caes: If you're not specifying the config during the build won't have any effect; only the configuration that was specified(or defaulted to) during cmake configuration is used... – fabian Mar 28 '21 at 12:27

1 Answers1

14

I'm going to give you the full in depth answer. Just in case someone else has this confusion.

What is a generator?

Essentially a generator is the build system CMake creates. CMake doesn't directly build your project. Because CMake is a meta-build system. IE CMake is a build system that 'generates' your true build system. That's why it is called a 'generator'.

"Visual Studio 16 2019" was designed to handles multiple configurations in 1 build.

enter image description here

Which is why when you open a Visual Studio project created by CMake you can easily change between Debug, Release, etc.

Where as "Unix Makefiles" and "Ninja" can only handle 1 config type at a time.

This difference in build system abilities leads to slightly different CLI when running CMake.

Visual Studio 16 2019 (Multi-Config)

As mentioned before Visual Studio supports multiple config types in the build.

cmake -S . -B build/vs -G "Visual Studio 16 2019"

cmake --build build/vs --config Debug
cmake --build build/vs --config Release

In the first command you are creating the Visual Studio 2019 project.

In the second command you are actually building the binaries. And since Visual Studio projects are multi-config you don't need a different build folder for each type. Since Visual Studio handles it for you!

Ninja (Single Config)

cmake -S . -B build/ninja/ -G "Ninja" -D CMAKE_BUILD_TYPE=Debug
cmake --build build/ninja/

# Now I've updated the project to make Release binaries
cmake -S . -B build/ninja/ -D CMAKE_BUILD_TYPE=Release
cmake --build build/ninja/

In the example above you create a Ninja project for a debug build. Then you build it.

Then you create a Ninja project for a release build. Then you build it.

Notice how you have to manually specify 2 build folders for each type yourself.

Ninja Multi-Config (new in CMake 3.17)

Thanks to advances in Ninja and CMake you can create avoid the hassle of specifying the build type at project creation time. So now it's just like Visual Studio.

So now you can create a "Ninja Multi-Config" project instead of just a "Ninja" project.

cmake -S . -B build/nin -G "Ninja Multi-Config"

cmake --build build/nin --config Debug
cmake --build build/nin --config Release

Further Elaboration

Single Config Vs Multi-Config

How can you tell if your generator is Multi vs Single?

Read the docs. Or if you need to in your scripts you can check it programmatically.

You can query the global property GENERATOR_IS_MULTI_CONFIG

CMAKE_BUILD_TYPE

A minor thing to mention is that CMAKE_BUILD_TYPE doesn't do anything on multi-config generators. So avoid using it in your CMake code.

See this answer: CMAKE_BUILD_TYPE is not being used in CMakeLists.txt

  • I'm using VS Code (with the Cmake extension) to do the configuring. I select either Release or Debug (or one of the other two) from the Cmake menu, and it appears to reconfigure. But when I build it - either from VS Code or from the command line - it says no work to do... what would I look for in the build folder to see where optimisation/debug tokens would be set? – Omroth Mar 29 '21 at 08:40
  • I don't use VS code. Perhaps try opening a vs code specific question. –  Mar 29 '21 at 15:38
  • @Omroth did I answer your question well enough? I know you are having an issue with the cmake extension but please make that a separate question instead. Try just manually writing the cmake cli I suggested. Then figure out what the extension is doing. If I had to guess the extension is only creating 1 build folder which isn't enough. –  Mar 31 '21 at 00:46
  • "what would I look for in the build folder to see where optimisation/debug tokens would be set?" - You can look at the generated Ninja files and see the CLI you are creating. –  Mar 31 '21 at 00:48