Cmake --config since version 3.20 - cmake

All the build hierarchy of my project is based on ExternalProject with --config option. A few days ago I updated to cmake 3.20, and now --config is gone:
$ cmake --config
CMake Error: Unknown argument --config
CMake Error: Run 'cmake --help' for all supported options.
while documentation still advises to use it. Release notes are also silent about the option.
What should I use instead of --config?

You should use for configure
cmake -S . `-D CMAKE_BUILD_TYPE=Release`
CMAKE_BUILD_TYPE will be ignored at configure
And for build
cmake --build . --config Release
Based on https://stackoverflow.com/a/64719718
I don't understand why docs ignored this movement

Based on github Issue you should use
cmake --build .

OK I had the same problem on macOS with the XCode generator.
Turns out all I was missing was the --build command.
i.e. instead of:
cmake . --config Debug
I have to type:
cmake --build . --config Debug

Related

CMAKE how to pass arguments to msbuild.exe

I have a cmake project and I'm using the msvc 2019 generator on windows 10.
I can successfully build with the following:
cmake -S . -B build
cd build
cmake --build . -- /m
I'm interested in passing the /m switch to msbuild.exe within the CMakeLists.txt itself.
I've tried the following without success as arguments get passed to cl.exe:
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /m")
message(STATUS "NOTICE: Setting parallel build for msbuild.exe")
add_definitions(/M)
endif()
Also bonus question: How does -- work in the last cmake command above? I'm struggling finding documentation on it.
The answer as #Johnny_xy pointed out is you can't. You need to use ninja as the cmake generator.
cmake -S . -B build -G Ninja Multi-Config
cd build
cmake --build .
link to ninja releases:
https://github.com/ninja-build/ninja/releases
ninja build time: 17.51s
cmake default build time: 44.54s

What happened to CMake's --target argument?

With CMake version 3.19.2 I can use --target argument to build specific targets, instead of all.
For example --target tests to build tests.
However, with CMake 3.22.1 I'm getting an error like this:
CMake Error: Unknown argument --target
CMake Error: Run 'cmake --help' for all supported options.
You can see the manual of CMake here:
https://cmake.org/cmake/help/latest/manual/cmake.1.html
(There is a drop-down list for version selection)
It describes the --target argument, and It doesn't seem any different from what it was earlier. Nonetheless, after switching from 3.19.2 to 3.22.1 it doesn't let me use --target.
#EDIT thank you for your feedback, here's what I use:
cmake -G Ninja -DCROSS_COMPILER_PREFIX=<some_prefix> -Dsomeothervariables=1 --target tests $directory_with_cmake_project
It works with 3.19.2, but executing the same thing with cmake 3.22.1 causes the error.
I expect that the order of providing -G Ninja, variables, target directory and --target matters, but I haven't managed to get it to work in any order I could think of.
CMake is composed of stages - first you configure the project, then you build it:
configuration stage cmake <sourcedir> ... https://cmake.org/cmake/help/v3.22/manual/cmake.1.html#generate-a-project-buildsystem
build stage cmake --build <builddir> ... https://cmake.org/cmake/help/v3.22/manual/cmake.1.html#build-a-project
--target argument if for the build stage, and it is invalid for configuration stage, hence your error.
CMake prints this message, if you haven't specified a directory to build by passing --build <some dir> first. (The --target option only if mentioned in this usage version of the cmake command line tool, see the documentation.)
Wrong
cmake --target foo
CMake Error: Unknown argument --target
CMake Error: Run 'cmake --help' for all supported options.
Correct
(assuming in the subdirectory build of the current working directory contains a configured cmake project with a target foo).
cmake --build build --target foo

CMake build types make no difference

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?
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.
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

How do I enable SSE2 from the command line

I'm compiling Dlib's Python Examples.
The compile script is:
mkdir build
cd build
cmake ../../tools/python
cmake --build . --config Release --target install
cd ..
How do I enable SSE2 from the command line? I tried adding the argument -USE_SSE2_INSTRUCTIONS=ON but got unknown argument error.
From Cmake cache file:
//Compile your program with SSE2 instructions
USE_SSE2_INSTRUCTIONS:BOOL=OFF
You forgot the -D. So you have to say, cmake -DUSE_SSE2_INSTRUCTIONS=ON

the option "--build" of cmake

I want to use the cmake --build command to build my project.
This command has a --config option. I don't know how many different parameters I can assign to. And I found cmake doesn't check if the parameter of --config is correct or not
You can call cmake --build like this:
cmake --build . --target MyExe --config Debug
This would be run from your build root, since the directory is passed as ., and would build the target MyExe in Debug mode.
If your build tool is a multi-configuration one (like devenv on Windows), the --config argument matters. If you pass an invalid parameter as the config type here, the build tool should give an error.
If the build tool isn't multi-config (like gcc), then the --config argument is ignored. Instead the build type is set via the CMAKE_BUILD_TYPE CMake variable; i.e. it's set when running CMake, not when running the build tool.
You can pass further options to the build tool by adding them at the end after a --, e.g to pass -j4 if using gcc:
cmake --build . --target MyExe -- -j4