CMake Error: Unknown argument --clean-first - cmake

When running the follow CMake command, I am receiving an error. I am working with CMake version 3.20.5.
cmake --clean-first ./src/basis_universal/CMakeLists.txt
CMake Error: Unknown argument --clean-first
However, --clean-first appears to be supported.

Just to make it abundantly clear to you... typically there are 2 steps you take in any cmake project... configuration and building.
In the configuration step, CMake looks for the files on your system, the compiler, etc. and prepares everything for building.
The building step of actually turning your code into an executable is a second, separate step.
When you run
cmake --clean-first ./src/basis_universal/CMakeLists.txt
you are just configuring your project. The --clean-first command is not available during configuration.
After configuration, you need to build your project. In that step, you can use the --clean-first option.

Related

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

CMake with Emscripten and vcpkg can't bind two TOOLCHAIN_FILES

Both vcpkg and Emscripten require to set CMAKE_TOOLCHAIN_FILE to
vcpkg/scripts/buildsystems/vcpkg.cmake and emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake respectively.
How do i do that? or what is the best way to get them both working together?
right now i have a naive attempt:
set(CMAKE_TOOLCHAIN_FILE "/Users/screen-photo-to-text/vcpkg/scripts/buildsystems/vcpkg.cmake" "/Users/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")
But it get Could not find toolchain file error and i can't find a way to get this working
To my delight, recently vcpkg received Emscripten support - see PR.
One can install packages like so:
vcpkg install zlib:wasm32-emscripten
Usage is pretty usual standard, for example CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(zpipe CXX)
find_package(ZLIB REQUIRED)
add_executable(zpipe zpipe.cpp)
target_link_libraries(zpipe ZLIB::ZLIB)
The tricky part is still as in question how to combine two toolchains. This invocation works for me:
mkdir build
cd build
emcmake "c:\Program files\CMake\bin\cmake" .. "-G" "Ninja" "-DCMAKE_MAKE_PROGRAM=F:/vcpkg/downloads/tools/ninja/1.10.1-windows/ninja.exe" "-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=%EMSDK%/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" "-DVCPKG_TARGET_TRIPLET=wasm32-emscripten" "-DCMAKE_TOOLCHAIN_FILE=F:/vcpkg/scripts/buildsystems/vcpkg.cmake" "-DCMAKE_BUILD_TYPE=Release"
emmake ninja
As usually, this needs first Emscripten environment variables set (e.g. with emsdk_env.bat).
Failing to provide this asked second toolchain will result with errors like wasm-ld: error: unknown argument: --out-implib
If for whatever reason (e.g. not absolute path) emcmake can't find the CMake executable, it may result with errors like FileNotFoundError: [WinError 2] The system cannot find the file specified
In case of CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set., as hinted, the CMAKE_MAKE_PROGRAM needs to be set pointing to ninja executable.

Problem with VSOME/IP: I can't complete CMake

I would like to cmake on the first step of my vsomeip build. However, I get an error where:
GTEST_ROOT is not defined. For building the tests the variable
GTEST_ROOT has to be defined. Tests can not be built.
I am an amateur in this subject, so please bear with me.
This repository depends on GTest as mentioned here in the documentation. The CMake attempts to find the GTest source code locally and build a static library of GTest. So, you should add the GTEST_ROOT directory when calling cmake using the -D definition flag:
cmake -DGTEST_ROOT=/path/to/your/gtest/dir ..

Building a CMake library within a Bazel project

I've written a module on top of a private fork off of TensorFlow that uses nanomsg.
For my local development server, I used cmake install to install nanomsg (to /usr/local) and accessed the header files from their installed location. The project runs fine locally.
However, I now need to package nanomsg within my TensorFlow workspace. I've tried the following two approaches, and find neither satisfactory:
Similar to this answer for OpenCV, I precompiled nanomsg into a private repository, loaded it within my workspace (within tensorflow/workspace.bzl) using an http_archive directive then included the headers and libraries in the relevant build script. This runs fine, but is not a portable solution.
A more portable solution, I created a genrule to run a specific sequence of cmake commands that can be used to build nanomsg. This approach is neater, but the genrule cannot be reused to cmake other projects. (I referred to this discussion).
Clearly cmake is not supported as a first-class citizen in Bazel builds. Is there anyone who has faced this problem in your own projects created a generic, portable way to include libraries within Bazel projects that are built using cmake? If so, how did you approach it?
As Ulf wrote, I think your suggested option 2 should work fine.
Regarding "can I identify if the cmake fails", yes: cmake should return with an error exit code (!= 0) when it fails. This in turn will cause Bazel to automatically recognize the genrule action as failed and thus fail the build. Because Bazel sets "set -e -o pipefail" before running your command (cf. https://docs.bazel.build/versions/master/be/general.html#genrule-environment), it should also work if you chain multiple cmake commands in your genrule "cmd".
If you call out to a shell script in your "cmd" attribute that then actually runs the cmake commands, make sure to put "set -e -o pipefail" in the first line of your script yourself. Otherwise the script will not fail when cmake fails.
If I misunderstood your question "Can I identify if the cmake fails", please let me know. :)
This new project: https://github.com/bazelbuild/rules_foreign_cc seems like a solution(it build rules for cmake to build your project inside bazel).

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.