Ninja+MSVC: Broken dependencies on headers generated in source tree
I have the following structure:
<root>
- CMakeLists.txt
- generator
- CMakeLists.txt
- main.cpp
- generated
- my_header.h
- client
- CMakeLists.txt
- f1.cpp
- f2.cpp
- main.cpp
<root>/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(test)
cmake_path(SET my-gen-file NORMALIZE "${CMAKE_SOURCE_DIR}/generated/my_header.h")
add_subdirectory(generator)
add_subdirectory(client)
<root>/generator/CMakeLists.txt
add_executable(my-file-generator main.cpp)
add_custom_command(
OUTPUT ${my-gen-file}
COMMAND "$<TARGET_FILE:my-file-generator>" ${my-gen-file}
DEPENDS my-file-generator
)
add_custom_target(generate-my-file DEPENDS "${my-gen-file}")
<root>/generator/main.cpp
#include <fstream>
#include <string>
int main(int argc, char**argv){
std::string path = argv[1];
std::ofstream file(path);
file << "#pragma once\n";
return 0;
}
<root>/client/CMakeLists.txt
add_executable(client main.cpp f1.cpp f2.cpp)
add_dependencies(client generate-my-file)
# Need to do this because GENERATED property doesn't propagate
set_source_files_properties("${my-gen-file}" PROPERTIES GENERATED TRUE)
target_include_directories(client PRIVATE "${CMAKE_SOURCE_DIR}")
<root>/client/f1.cpp
#include "generated/my_header.h"
<root>/client/f2.cpp
#include "generated/my_header.h"
<root>/client/main.cpp
#include <iostream>
#include "generated/my_header.h"
int main(){
std::cout << "hello\n";
return 0;
}
Using Visual Studio + Ninja, if I rebuild I get:
[1/7] Building CXX object generator\CMakeFiles\my-file-generator.dir\main.cpp.obj
[2/7] Linking CXX executable generator\my-file-generator.exe
[3/7] Generating D:/dev/cmake_gen_update_detection/generated/my_header.h
[4/7] Building CXX object client\CMakeFiles\client.dir\f1.cpp.obj
[5/7] Building CXX object client\CMakeFiles\client.dir\f2.cpp.obj
[6/7] Building CXX object client\CMakeFiles\client.dir\main.cpp.obj
[7/7] Linking CXX executable client\client.exe
Rebuild All succeeded.
If I then touch <root>/generator/main.cpp
and build I get:
[1/3] Building CXX object generator\CMakeFiles\my-file-generator.dir\main.cpp.obj
[2/3] Linking CXX executable generator\my-file-generator.exe
[3/3] Generating D:/dev/cmake_gen_update_detection/generated/my_header.h
Build All succeeded.
and then if I build again I get:
[1/4] Building CXX object client\CMakeFiles\client.dir\f1.cpp.obj
[2/4] Building CXX object client\CMakeFiles\client.dir\f2.cpp.obj
[3/4] Building CXX object client\CMakeFiles\client.dir\main.cpp.obj
[4/4] Linking CXX executable client\client.exe
After touching <root>/generator/main.cpp
I expect everything to be updated in a single build.
Edited by rconde01