Why is the default for --build different than --install?

I’m working on a Windows machine with Visual Studio’s compiles.

I create the visual studio project/solution from a build directory using the command

cmake ..

When it’s time to compile I will use the command

cmake --build .

The default for this action is to compile the Debug image.


Then when I want to test install I will use the command

cmake --install . --prefix "%CD%\..\INSTALL"

However this fails because it cannot find the Release image.

I learned that I could use the --config option for install. For examle

cmake --install . --prefix "%CD%\..\INSTALL" --config Debug

Will work.

Now the question…

Why is the default for --build the Debug image but the default for --install the Release image? Or did I inadvertantly set this behavior elsewhere in my CMake logic?

It’s probably just been an oversight. It sounds like a new issue to me though.

An issue has now been filed as https://gitlab.kitware.com/cmake/cmake/-/issues/25548.

I don’t think this is a bug, I think it is behavior as intended, so I’ll respond here instead and close the bug with a link back to here.

A build step defaults to Debug for multi-config generators because that’s generally close to what compilers do by default if given no flags. For a single-config generator, you get an empty configuration which does generally correspond to that default compiler behavior. In my experience, when you ask developers what they want as the default configuration if they don’t specify it, most of the time, the answer is Debug. So looking at the build step in isolation, Debug makes the most sense as the default for builds.

For an install step, it is very rare to install the Debug configuration. Most of the time, you will be wanting to install the Release configuration, so it makes the most sense to make that the default when installing.

Looking at the build and install steps together, you need to consider what you’re actually trying to do. In your scenario, you want to build with the intention of installing, but that isn’t the default or most common workflow. A build intended for an install or packaging won’t be built with the same settings as a developer working locally. Since installation or packaging is typically a scripted process, it makes the most sense to add flags there rather than forcing developers to add flags for their workflow, which typically isn’t script-driven. In other words, the build defaults are optimised for developers, so when building for other use cases like installing or packaging, you should expect to need to add some additional flags or settings. The install step is optimised for the most common scenario, which is a Release build, which helps keep scripted installs and packaging simpler.

1 Like