CMake - customize 'make help' output - cmake

I introduced CMake to my project it replaced Make's makefiles. Anyhow I'm not able to find how to customize 'make help' output. This target is created automagically anyhow I would like to add some descriptions for particular targets. It is anyhow possible?

Overwriting help with add_custom_target results in:
See also "/tmp/20/CMakeFiles/CMakeOutput.log".
CMake Error at CMakeLists.txt:5 (add_custom_target):
The target name "help" is reserved or not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
Instead of overwriting what cmake generates, write your own make wrapper one directory above the cmake one. Like so:
$ cd /your/project
$ ls
_build CMakeLists.txt source_file.c Makefile
$ cmake -S. -B./_build
... configure the project in ./_build builddir ...
$ make
cmake --build _build --target all
<builds the project>
$ make help
This is your help
With Makefile:
all:
cmake --build _build --target all
configure_for_some_configuration:
cmake -S. -B_build -DSOME_OPTION=true
help:
#echo 'This is your help'
.PHONY: help configure_for_some_configuration all
Remember that make is one of several of supported generators. I recommend Ninja for faster builds. Use cmake --build <the build dir> to abstractly build the project independently of the used generator.

Related

How do I make makefile generatedby cmake output the last command when error occur? [duplicate]

I use CMake with GNU Make and would like to see all commands exactly (for example how the compiler is executed, all the flags etc.).
GNU make has --debug, but it does not seem to be that helpful are there any other options? Does CMake provide additional flags in the generated Makefile for debugging purpose?
When you run make, add VERBOSE=1 to see the full command output. For example:
cmake .
make VERBOSE=1
Or you can add -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON to the cmake command for permanent verbose command output from the generated Makefiles.
cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make
To reduce some possibly less-interesting output you might like to use the following options. The option CMAKE_RULE_MESSAGES=OFF removes lines like [ 33%] Building C object..., while --no-print-directory tells make to not print out the current directory filtering out lines like make[1]: Entering directory and make[1]: Leaving directory.
cmake -DCMAKE_RULE_MESSAGES:BOOL=OFF -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON .
make --no-print-directory
It is convenient to set the option in the CMakeLists.txt file as:
set(CMAKE_VERBOSE_MAKEFILE ON)
Or simply export VERBOSE environment variable on the shell like this:
export VERBOSE=1
cmake --build . --verbose
On Linux and with Makefile generation, this is likely just calling make VERBOSE=1 under the hood, but cmake --build can be more portable for your build system, e.g. working across OSes or if you decide to do e.g. Ninja builds later on:
mkdir build
cd build
cmake ..
cmake --build . --verbose
Its documentation also suggests that it is equivalent to VERBOSE=1:
--verbose, -v
Enable verbose output - if supported - including the build commands to be executed.
This option can be omitted if VERBOSE environment variable or CMAKE_VERBOSE_MAKEFILE cached variable is set.
Tested on Cmake 3.22.1, Ubuntu 22.04.
If you use the CMake GUI then swap to the advanced view and then the option is called CMAKE_VERBOSE_MAKEFILE.
I was trying something similar to ensure the -ggdb flag was present.
Call make in a clean directory and grep the flag you are looking for. Looking for debug rather than ggdb I would just write.
make VERBOSE=1 | grep debug
The -ggdb flag was obscure enough that only the compile commands popped up.
CMake 3.14+
CMake now has --verbose to specify verbose build output. This works regardless of your generator.
cd project
cmake -B build/
cmake --build build --verbose
It's worth noting however Xcode may not work with --verbose
Some generators such as Xcode don't support this option currently.
Another option it to use the VERBOSE environment variable.
New in version 3.14.
Activates verbose output from CMake and your build tools of choice when you start to actually build your project.
Note that any given value is ignored. It's just checked for existence.
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE will generate a file with all compilation commands.
This file is required by some LSP to know how to compile a source file out of the box, but it could also help for debugging compilation problems.
The output file is named ${CMAKE_BINARY_DIR}/compile_commands.json.

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, how to specify the output directory

I'm using cmake to generate a VS2017 solution (and projects...), I try to generate everything in a different folder.
I used both the command line and different variables, but no way, it generate in the "source" folder !
Here are some examples of what I tried:
cd source
cmake -B../build ...
cd build
cmake ../source
cmake --build "../build"
cmake -Dxxx=../build
Any idea ? all theses solutions are expected to generate in the build folder !
Once you have performed in-source build (in source directory), it is impossible to build the project out-of-source: every such attempt will modify in-source build.
You need to clear build files (CMakeCache.txt, probably some other ones) in source directory before using out-of-source builds.
I fixed with:
cd VSBuild
cmake ../
instead of
cd VSBuild
cmake ..
Have you tried this? This will put all the build files under "out"
$ cmake -H. -Bout
To execute:
$ cmake --build out

How to setup make options with cmake

I would like to setup commands like make debug, make test, etc... What is the best way to do this with cmake, so that I run cmake .. one time (it takes a while) and then be able to choose the build type with make?
I couldn't find any resources on this.
As #Tsyvarev has commented this needs a little extra work for single-configuration environments (respectively CMake's Makefile generators) since the build type is chosen during CMake's configuration and finalized during the build environment generation step.
So here is what I've done:
First you run - e.g. in a script - CMake for all configurations you want to support and choose respective sub-folders for the output:
> cmake -H"." -B"Debug" -DCMAKE_BUILD_TYPE=Debug
> cmake -H"." -B"Release" -DCMAKE_BUILD_TYPE=Release
Note: -H (for "home directory") and -B (for "binary output directory") are undocumented options, but very useful in those cases. And they work with all CMake releases so far. Just be careful not to put spaces between the option and the their values.
Then you can use again CMake to build from/in those sub-folders:
> cmake --build "Debug"
> cmake --build "Release"
And if you want to run the tests you can:
> cmake --build "Debug" --target "test"
> cmake --build "Release" --target "test"
References
Changing CMake files standard location
Does CMake always generate configurations for all possible project configurations?
cmake build multiple targets in different build directories
CMAKE_BUILD_TYPE not being used in CMakeLists.txt

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