cxxmodules: synthetic targets for dependencies of imported module aware targets are not generated
I'm testing the new modules support (MR !8828 (merged)) and found that no synthetic targets for dependencies of imported targets are generated, resulting in compiler errors. Example from a CMake config file:
# Create imported target mylib::mylib
add_library(mylib::mylib SHARED IMPORTED)
set_target_properties(mylib::mylib PROPERTIES
CXX_EXTENSIONS "OFF"
IMPORTED_CXX_MODULES_COMPILE_FEATURES "cxx_std_20"
IMPORTED_CXX_MODULES_COMPILE_OPTIONS ""
IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
IMPORTED_CXX_MODULES_LINK_LIBRARIES "\$<COMPILE_ONLY:libc++::std>;\$<COMPILE_ONLY:ICU::uc>;\$<COMPILE_ONLY:simdutf::simdutf>"
INTERFACE_COMPILE_FEATURES "cxx_std_20"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "libc++::std"
)
Here, libc++::std
is another imported target (that I created by playing around with libc++'s module support) which contains sources in a CXX_MODULES fileset. If I understand CMake's support correctly, then CMake should not only create a synthetic target for mylib::mylib
but also for libc++::std
and wire up the dependencies between them appropriately.
I played around a bit in the code and found the following changes make my project compile:
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 04d7bb1081..f726fc1ce8 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -8322,6 +8322,9 @@ bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
// Create the generator target and attach it to the local generator.
auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+
+ gtp->DiscoverSyntheticTargets(cache, config);
+
synthDep = gtp.get();
lg->AddGeneratorTarget(std::move(gtp));
} else {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index abbf29ec64..6ec678aa3a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1784,6 +1784,8 @@ void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt)
this->impl->LinkLibraries.Entries.clear();
this->impl->LinkLibraries.CopyFromEntries(
cmMakeRange(tgt->impl->LinkLibraries.Entries));
+ this->impl->LinkLibraries.CopyFromEntries(
+ cmMakeRange(tgt->impl->InterfaceLinkLibraries.Entries));
// Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
// target's `PRIVATE`.
...i.e. when creating the LinkLibraries
of a synthetic target, also take the INTERFACE_LINK_LIBRARIES
(and/or IMPORTED_CXX_MODULES_LINK_LIBRARIES
?) of the "template" target into account. Also, when a synthetic target is created, discover the synthetic targets for its dependencies recursively.
Does this sound reasonable?