I have a target hello
with two source files a.cpp
and b.cpp
. And both contain the #import
directive:
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "EndOfFile")
which will generate the header file msado15.tlh
during compilation.
Ninja builds source files in parallel which causes race on the header file generation.
This is related to Developer Community.
I tried OBJECT_DEPENDS
, it worked well, but the path to the output object file is implementation detail.
set_source_files_properties(b.cpp PROPERTIES OBJECT_DEPENDS "CMakeFiles/hello.dir/a.cpp.obj")
Using PCH should work also. But is there an official way to make a source file compile before any others?
#import
is effectively a code generation step, ie it has outputs that further steps in the build graph depend on.
Worse, it is a code generation step where the output of the step is dependent on the content of the input to the step. The generated header files are based on what set of symbols is present in the #import
directive.
CMake has no general purpose mechanism for modeling this, it’s a known weakness and oft-requested feature. OBJECT_DEPENDS
is a reasonable work around. Normally you could get the object name with $<TARGET_OBJECTS:tgt>
but we don’t support generator expressions in OBJECT_DEPENDS
, see:
So ya, it’s a hard problem (even MSBuild doesn’t solve it very well), your solution isn’t bad.
2 Likes
I found that even the document says OBJECT_DEPENDS
is a list of full-paths to files, it doesn’t need to be actually. With OBJECT_OUTPUTS
and OBJECT_DEPENDS
, I can accomplish the goal perfectly:
set_source_files_properties(a.cpp PROPERTIES OBJECT_OUTPUTS "hello_first_obj")
set_source_files_properties(b.cpp PROPERTIES OBJECT_DEPENDS "hello_first_obj")
hello_first_obj
can be any string, it doesn’t need to be a path to a file. At least for Ninja generator it works.