We are using cmake with ninja as the generated build system.
Cmake has a feature where the generated build will also check if the cmake inputs themselves are out of date, which will trigger a call back into cmake to reconfigure before the build proceeds. E.g., if you call ninja but some CMakeLists.txt has been modified, ninja notice and calls cmake with a special --reconfigure-during-build argument or something like that.
This doesn't work in our case because it loses arguments passed to the original cmake invocation. Is there some way to disable it? An error would be fine.
Related
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".
I have one build script per each environment (debug, release, relwithdebuginfo etc).
Each script calls CMake with the relevant build environment set:
cmake -DCMAKE_BUILD_TYPE=Debug -DARG_FORCE_CLANG=True
a flag inside the CMakeLists.txt file controls the sanitize flag. However, I would like to control this from a new sanitize build script, something like:
cmake -DCMAKE_BUILD_TYPE=Debug -DARG_FORCE_CLANG=True -SANITIZE=true
Is there any way to achieve this?
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.
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.
In CMake I currently have a simple Python script to generate a header, but if I update the script itself CMake won't re-run the script. Is there a way I can get CMake to do this?
It seems you are directly invoking your code generation script when cmake is run. While it is possible solution but it is definitely not a right way to use code generators with cmake.
I recommend you to use add_custom_command for your case:
add_custom_command(
OUTPUT generated.h
COMMAND ${PYTHON_EXECUTABLE} generator.py
DEPENDS generator.py
)
And next you can simple put your header to the list of source files passed to add_library/add_executable commands. cmake will automatically track all the dependencies and invoke your script.
Term DEPENDS generator.py informs cmake that it should regenerate header if script is changed.
With this approach file generated.h will be generated only at build time (when you run make or execute a build command in IDE). In contrast if you are running your script at cmake time (with execute_process command) then you have to rerun cmake to regenerate your file. Which is possible but you need to use some tricks to introduce a non-standard dependency.