CMake: How to build projects in a cross-platform manner? - cmake

I'm trying to build a project in a cross-platform manner.
I'm using CMake to generate project files on the fly, but it's not clear how to then compile those project files in a cross-platform way. I found try_compile but it's not clear whether this will do what I want. Any ideas?
For example, say I am using Visual Studio 2010 against project foo. I am expecting CMake to generate foo.sln, and then build it (generate the binaries). I know how to automate the first part, but how do I automate the second?

From the CMake docs:
"CMake is a cross-platform build system generator."
So in other words, once CMake has generated the project files, it's work is really done.
You can invoke the native build tool via CMake using the --build flag, e.g.
cmake --build . --config Release --target install -- /M:4
See here for further info.

Related

How to convert CMake project to gn (BUILD.gn)?

I working with custom fork of Chromium, and need introduce some //third_party dependency , which is CMake based project. Because Chromium uses gn and BUILD.gn as basic "make file" I can't understand how I can build CMake project with context of Chromium build or how to obtain semantically same BUILD.gn .
Because CMakeLists.txt of CMake project is huge, it's a little bit tricky to convert it manually .
Will be grateful for help.

How can I make colcon work with a plain preset-based CMake project with multiple presets in parallel?

Prologue
I have a preset-based plain CMake project so that I can build and test it with cmake --preset $PRESET && cmake --build --preset $PRESET && ctest --preset $PRESET. Note that it nicely interacts with Microsoft's CMake Tools extension for Visual Studio Code, be it for building, testing, debugging and Intellisense.
Since I want to handle multiple presets in parallel, I set CMakePresets.json's binaryDir property to ${sourceDir}/build/${presetName}/.
Issue
I want to also build this plain CMake project with colcon. colcon build --cmake-args "--preset $PRESET" doesn't work, though, as it produces
WARNING:colcon.colcon_cmake.task.cmake.build:Could not build CMake package 'root_project_name' because the CMake cache has no 'CMAKE_PROJECT_NAME' variable
root_project_name being the argument to CMake's project() command in the top CMakeLists.txt.
How can I resolve this warning and the subsequent build failure?
Straightforward solution
Not setting CMakePresets.json's binaryDir property at all works fine with colcon, but doesn't allow for multiple preset builds in parallel.
Solution with multiple preset builds in parallel
The reason for this behavior is colcon-core's build verb's passing the build base directory (default: build) suffixed by the found package's name (here: root_project_name) to the colcon-cmake extension here.
The solution is to pass the correct build base to colcon (i.e. colcon build --build-base ./build/$PRESET/ --cmake-args "--preset $PRESET") and to adapt your CMakePresets.json's binaryDir property to ${sourceDir}/build/${presetName}/root_project_name/.
Note that this then works with colcon test as well, i.e. colcon test --build-base ./build/$PRESET/ --ctest-args "--preset $PRESET".

Is it possible to build cmake projects directly using MSBuildTools

Currently we are planning to use VS2017 with a cmake project. Inside Visual Studio this works quite like a charm.
Now want to run our builds as part of CI on a dedicated build master running MSBuildTools.
Is it possible to directly run the build using the msbuild command, without creating solution files with cmake? Optimally, I would even use the CMakeSettings.json used from VS2017.
Use the build-tool-mode of CMake for this. It uses the underlying default build tool which is MSBuild for Visual Studio Generators.
From the build directory call:
cmake --build . --target ALL_BUILD --config Release -- /nologo /verbosity:minimal /maxcpucount
and you get a fast, nearly quiet build. To install use INSTALL target, for running your tests if configured use RUN_TESTS target.
Is it possible to directly run the build using the msbuild command, without creating solution files with cmake?
Is it possible to directly run the build using the msbuild command, without creating solution files with cmake?
As far as I know, CMake produces Visual Studio Projects and Solutions seamlessly. So you can produce projects/solutions.
The only tricky part is to remember to make any changes in the cmake files, rather than from within Visual Studio.
In particular, each CMake project will create a Visual Studio solution (.sln file), while all of the CMake targets belonging to that CMake project will appear as Visual Studio projects within the corresponding solution.
CMake Visual Studio
project <-> Solution (.sln)
Target <-> Project (.vcxproj)
You can check cmake-and-visual-studio for more details.
Since MSbuild can build both solution files and project files, so you could also call msbuild INSTALL.vcxproj
Is it possible to even use the CMakeSettings.json used in VS2017?
The answer is yes, check the blog for details.
If your CMake project requires additional settings to configure the
CMake cache correctly, you can customize these settings by creating a
CMakeSettings.json file in the same folder with the root
CMakeLists.txt. In this file you can specify as many CMake
configurations as you need – you will be able to switch between them
at any time.
You can create the CMakeSettings.json file by selecting the Project >
Edit Settings > path-to-CMakeLists (configuration-name) menu entry.

specify a custom build tool in CMake

I have a simple CMakeLists.txt
add_executable(myexecutable test.cpp)
I don't intend to use CMake to actually indirectly be responsible for building the program. I intend to use it so I can use CLion and have a nice IDE experience for working on my c++ program.
If I hit build in CLion, or cmake --build on the commandline, I want it to invoke my real buildtool. How can I specify a buildtool to run instead of the normal build cmake/clion would do? I have only been able to find add_custom_command which can be run before/after the normal cmake/clion build.
You need some fake target to let CLion understand which files are there in the project. Then you can add add_custom_target with your own build commands. So if you avoid building fake target, but instead run custom targets via run configuration by name (after CMake reload CLion will automatically create run configurations for such targets), they will call build for you.

Why -DCMAKE_EXPORT_COMPILE_COMMANDS does not create compile_commands.json file

My cmake --version is 2.8.12.2.
I configure my project build with these commands:
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=on
CMAKE_EXPORT_COMPILE_COMMANDS=1 cmake ../klein/ -DBUILD_KLEIN_DEPS=1
From a clean build, and from a directory with an existing successful build. And want to see the compiler_commands.json file, but it does not appear.
At which moment should it be created: after cmake, or after make command? Where should it be in ./, or in ../klein directory? My cmake does not say anything about this option while it always complains about unused build variables.
Should it work from in a "dirty" directory, where I've performed one successful build, or does it work only on a fresh run in an empty folder?
Edit:
I use a default generator "Unix Makefiles" on my ubuntu linux machine
Edit2:
I'm not an author of the project under the question (I just want to explore it with rtags which requires compile_commands.json file), and I'm not very familiar with CMake mechanics. However, the CMakeLists.txt is probably configured as a super-build (it indeed downloads and builds dependencies - like llvm, z3, ...), and it includes ExternalProject, however it also builds the project itself (klein) from sources. So it's a mix, as I would say.
Can you specify what generator your using? A quick scan of the cmake source from version 3.1.0 suggests that this command is still only available in the following 2 cases.
if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
and
if(CMAKE_GENERATOR MATCHES "Ninja")
if you're using Visual Studio directly you're out of luck unless you want to add a patch to CMake. Otherwise, I know many Windows developers who've gone to Ninja. One advantage is that it's vastly faster than Visual Studio for building. If you are, in fact using Ninja or Unix Makefiles, then it's worth digging deeper.