After reading Professional CMake (almost) back to back, I’m once again asking for your support
I’m struggling to define a fixed pre-build command for a target. I need to generate a header with the current time at every build, and I really don’t want to define a custom target just to do that. Targets are a big deal, they’re global, and need work and attention to be reliable.
So, out of the three main options to define a custom command, as the book suggests, only add_custom_command
meets the need.
From the documentation:
If
DEPENDS
is not specified, the command will run whenever theOUTPUT
is missing; if the command does not actually create theOUTPUT
, the rule will always run.
The idea was to create a custom command with two OUTPUT
s: the generated header file, which establishes a dependency (and precedence) with the related target (the “light”, automatic dependency is enough in this case), and a dummy one, which causes the command to always trigger.
add_custom_command(OUTPUT "foo" "${VisualT_BINARY_DIR}/src/buildDate.h"
COMMAND ${CMAKE_COMMAND} -P "${VisualT_BINARY_DIR}/cmake/ConfigureBuildDate.cmake"
COMMENT "generating build date header"
)
add_library(VisualT_library SHARED "${private_headers}" "${public_headers}" "${sources}") #buildDate.h is contained in "private_headers"
It doesn’t work. Most of the times. Sometime it does. There’s definitely something wrong with the outputs because they seem to be order-sensitive. I’ve never managed to get it working with the outputs switched. I’ve never read anything about the output order ?
What I have now is:
====================[ Build | VisualT_library | Debug WSL ]=====================
/usr/bin/cmake --build "/mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/cmake-build-debug-wsl" --target VisualT_library -- -j 12
[ 33%] generating build date header
Scanning dependencies of target VisualT_library
[ 33%] generating build date header
[ 66%] Building C object src/CMakeFiles/VisualT_library.dir/visualt.c.o
[100%] Linking C shared library libvisualt.so
[100%] Built target VisualT_library
Build finished
It’s currently working, but it looks like it’s generating the header twice, which is wrong.
What usually happens is that it says “generating build date header” but no file is generated, and the compilation fails due to a missing header. In the case the library was already up to date, it does the same, but no errors are displayed, as no compilation occurs (and that’s still wrong, since the header should have changed).
With the outputs switched:
CMake output
/usr/bin/cmake --build "/mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/cmake-build-debug-wsl" --target VisualT_library -- -j 12
[ 33%] generating build date header
Scanning dependencies of target VisualT_library
[ 66%] Building C object src/CMakeFiles/VisualT_library.dir/visualt.c.o
/mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/src/visualt.c:3:10: fatal error: buildDate.h: No such file or directory
#include "buildDate.h"
^~~~~~~~~~~~~
compilation terminated.
src/CMakeFiles/VisualT_library.dir/build.make:89: recipe for target 'src/CMakeFiles/VisualT_library.dir/visualt.c.o' failed
make[3]: *** [src/CMakeFiles/VisualT_library.dir/visualt.c.o] Error 1
CMakeFiles/Makefile2:199: recipe for target 'src/CMakeFiles/VisualT_library.dir/all' failed
make[2]: *** [src/CMakeFiles/VisualT_library.dir/all] Error 2
CMakeFiles/Makefile2:206: recipe for target 'src/CMakeFiles/VisualT_library.dir/rule' failed
make[1]: *** [src/CMakeFiles/VisualT_library.dir/rule] Error 2
Makefile:149: recipe for target 'VisualT_library' failed
make: *** [VisualT_library] Error 2