How do I use CMake with debugging information? - cmake

At the moment I'm compiling via
cmake --build . --config RelWithDebInfo
I'm not sure if this makes sense but it works. I would like to use the debugging of CMake which, afaik, can be set via DCMAKE_BUILD_TYPE=Debug. When I try to use this the compiling itself works:
cmake -DCMAKE_BUILD_TYPE=Debug .
but here I don't get an .exe file somewhere. I guess I miss the --build or --config option from before but how do I properly add them?
edit: Thanks to vre's input I'm coming along better. However, this is the output now:
C:\geant4\sim> cmake -DCMAKE_BUILD_TYPE=Debug .
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19042.
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_BUILD_TYPE
-- Build files have been written to: C:/geant4/sim
why is the build type not used?

Related

CMake: detect "--config Release" in if condition

I want to build a target only in release mode, so i need a 'if(RELEASE)' or something.
I found
if (CMAKE_BUILD_TYPE EQUAL "RELEASE")
but it doesnt work, because i build with the following command
cmake --build . --config Release
which apparently doesnt set CMAKE_BUILD_TYPE.
What's the correct way to detect Release vs Debug build with modern cmake?
(I cant use generator expressions because i need an actual if() )

How do I build a CMake project?

I have just acquired an arbitrary CMake project from the internet and I am not sure how to compile it. What commands do I need to run to build it from the command line?
Basic steps
If you're on a Unix-y operating system, like Linux or macOS, then you would run:
$ cmake -DCMAKE_BUILD_TYPE=Release -S /path/to/source-dir -B /path/to/build-dir
$ cmake --build /path/to/build-dir
Here, /path/to/source-dir is the directory containing the root-level CMakeLists.txt, this is most commonly the root of a source control repository. Meanwhile, /path/to/build-dir is a distinct directory (that does not need to exist yet) that CMake will use to store the generated build system and its outputs. This is called an out-of-tree build. You should never attempt an in-tree build with CMake because of the possibility of name clashes and difficulty involved with cleaning up the generated files.
When building with a single-config generator (like Make, which is the default on Unix), you specify the build type by setting the CMAKE_BUILD_TYPE variable in the first command, known as the configure step. You must always set this variable when working with a single-config generator. The built-in configs are Debug, Release, RelWithDebInfo, and MinSizeRel. See this answer for more detail on this.
After the configure step, you may build the project by either calling the underlying build tool (in this case, make) or by calling CMake's generic build launcher command (cmake --build), as I do here.
If you're on Windows, then the default generator is Visual Studio, which is a multi-config generator. This means the build type is chosen during the build step rather than the configure step, and the commands must be adjusted accordingly:
$ cmake -S /path/to/source-dir -B /path/to/build-dir
$ cmake --build /path/to/build-dir --config Release
These steps assume that the CMake build you are looking at is well behaved. If a project fails to build with the above steps and you have all of its dependencies installed to system locations (and they are well behaved), then you should open an issue with the upstream project. The most common source of bad behavior in mature CMake builds is dependency handling. Too often you will have to read the build or its documentation to determine which variables need to be set (via -D, like we did with CMAKE_BUILD_TYPE above) for the project to find its dependencies.
Advanced topics
Setting options and cache variables
Some projects offer options to enable/disable tests, components, features, etc. These are typically done by writing entries to the CMake cache during the configure step. For example, a common way to disable building tests is to set BUILD_TESTING to NO at the command line:
$ cmake -S /path/to/source-dir -B /path/to/binary-dir [...] -DBUILD_TESTING=NO
This particular variable is a convention, but is not guaranteed to be honored. Check the project's documentation to see which options are available.
Selecting a generator and toolchain
When using the Visual Studio generators specifically, you can tell CMake which platform you wish to target and which version of the compiler you would like to use. The full form of the CMake configure command for this is:
$ cmake -G "Visual Studio 16 2019" -A <ARCH> -T<TOOLSET> [...]
Valid values of <ARCH> include Win32, x64, ARM, and ARM64. If <TOOLSET> is not specified, then the 32-bit MSVC compiler will be used. Typically, you will want this to be host=x64 to ensure that 64-bit MSVC is used, which can allocate more memory for large linking steps. You can also set <TOOLSET> to ClangCL to use the Visual Studio provided ClangCL tools.
On all generators, CMake sniffs the environment for which compiler to use. It checks the CC and CXX environment variables for the C and C++ compilers, respectively. If those are empty, it will look for cc and c++ executables in the PATH. You can manually override the compilers by setting the CMAKE_C_COMPILER and CMAKE_CXX_COMPILER CMake cache (not environment) variables at the CMake command line (using -D again).
Installing & using dependencies
Once a CMake project has been built, you may install it either systemwide or (preferably) to a local prefix by running:
$ cmake --install /path/to/build-dir --prefix /path/to/install-dir [--config Release]
Where --config is only required if a multi-config generator was used. Once installed to a local prefix, a project that depends on it may be configured by setting CMAKE_PREFIX_PATH to /path/to/install-dir.

How to make a project written with Tcl in CMake?

I am using cmake version 3.14.0-rc3 to make my codes. When I target any code written in C or C++ in my CMakelist.txt as follows, it works pretty and makes the executable file.
cmake_minimum_required(VERSION 3.3)
PROJECT (HELLO)
ADD_EXECUTABLE(hello hello_world.cpp)
but while I am trying to make this code with Tcl scripts, it fails and I receive the following fatal error:
Fatal error while making a tcl script with cmake
Can anyone help me to overcome this issue? It seems that cmake is not normally able to compile Tcl scripts.
Thank in advance for your kind replies and helps.
Bests,
Daryon
You have to watch out for a different path, e.g., running custom commands or adding custom targets to your CMake project. You seem to confuse the nature of libraries, executables, and external commands in the context of CMake, I am afraid.
I think there should be a way to execute Tcl scripts with CMake as
well.
You might want to attempt the following: In CMakeLists.txt, you define a custom target MyTarget that calls out to a TCLSH executable, if available:
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
PROJECT (HELLO)
find_program (TCLSH tclsh)
if (TCLSH)
add_custom_target(
MyTarget ALL
COMMAND TCLSH myScript.tcl
)
endif (TCLSH)
(1) find_program and if/endif will make the custom target only available under the condition that an executable called tclsh was found.
(2) myScript.tcl is a Tcl script in your project directory.
(3) Running cmake . && make will call out to effectively to: tclsh myScript.tcl, producing:
$cmake . && make
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/hello
This is a message written by Tcl scripts
Built target MyTarget
This is just to get you started, you will have to read more about adding commands, targets, or executing sub-processes from within CMake.

Proper way to determine generator for cmake project

I'm in a cmake build directory and want to build the project, but don't know if cmake was run with -G Unix\ Makefile or -G Ninja.
Now I know I can just be ignorant of that and use cmake --build ., but when I want to provide additional options cmake --build . -- SOMETHING I should know if I should provide gnumake or ninja options.
As possible solutions I found that I can just check the presence of a Makefile or build.ninja file. Or grep in the CMakeCache.txt for CMAKE_GENERATOR.
EDIT:
In a similar question here it is explained that values passed to cmake with -D can be queried with cmake -LA -N. But this doesn't list the -G parameter.
I am wondering if there is a more proper way (just like cmake -LA -N instead of grepping for variable values).
You've cited two possible solutions:
Check presence of build system files. Not a general solution, as it only works for some generators, but it may work in your case. This would not work for Visual Studio (for example, unless you parse the Visual Studio files themselves), as each generator version creates the same filenames.
Grep CMakeCache.txt for CMAKE_GENERATOR. Relies on platform specific tools (grep), and the location of the CMakeCache.txt. Both likely not a problem in most situations.
A slight modification to the second option, which makes it more portable, is to cache the CMAKE_GENERATOR in another variable:
set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}" CACHE STRING "Expose CMAKE_GENERATOR" FORCE)
Then, when you use cmake -L, USED_CMAKE_GENERATOR will show up.

CMake command line arguments in a Ninja build

I am trying to use Ninja + CMake to build a project.
This project has a custom target that takes additional arguments.
E.g. make target option=value
It works fine in make, however I am not sure how to get Ninja to take in additional command line arguments.
Is this possible with a Ninja build?
I don't think it's possible to do directly through Ninja. I just scanned through the Ninja documentation to double check and didn't see anything.
Instead, you could modify CMake cache variables via CMake (see cmake -D and cmake -L). That way you could change your build on the fly, or create a few different build directories with different settings in each one.