I have a project which is using protobuf and a custom command.
However I get a compile error, because my custom_command is not executed in the correct order.
The problem occurs only with the ninja code generator. With make the code compiles fine.
Steps to reproduce:
cmake -S . -GNinja -B build
cmake --build build
../Main.cpp:2:10: fatal error: some_header.h: No such file or directory
2 | #include "some_header.h"
For unknown reason I cannot upload my test case code in the forum…
So I uploaded it to a third party site. It is a minimal test case.
This cannot work when creating the header file like this. Ninja does not know what creates some_header.h (or if it exists somewhere in the include search path). And it is free to compile Main.cpp before create MyProtoLib static library.
You should prefer a custom command that is not bound to a target:
Hi Hendrik, thanks for your reply, this gives me a hint in the right direction.
Unfortunately I missed some important part of the test case. So the MyProtoLib creates some python files during compilation and this python file should be used when running test.py
so I added the missing import statement import foo_pb2.py
Thats why there is the dependency from the test.py to MyProtoLib
So the dependency tree is like that:
Compile MyProtoLib
Run test.py
Compile ConsumingService
I adjusted the test case to reflect this, now the compilation fails again, also with make.
some_header.h should be added as PRIVATE to MyProtoLib, not ConsumingService.
After that the dependency chain between Main.cpp.obj and some_header.h should be working
The add_custom_command for some_header.h needs an additions DEPENDS on ${CMAKE_CURRENT_BINARY_DIR}/foo_pb2.py to trigger it’s creating prior to running test.py.
I added
find_package(Python3 REQUIRED)
in the top-level CMakeLists.txt and used “${Python3_EXECUTABLE}” instead of plain python to make it work in Windows with python not in PATH.
Then I fixed the test.py to “import foo_pb2” (remove the .py suffix).
I then build with Ninja generator and it worked.
Since the test.py could not be run, there was not some_header.h. Always look at the first error message, not the last.