summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2020-02-04 05:32:51 (GMT)
committerBrad King <brad.king@kitware.com>2020-03-12 15:50:43 (GMT)
commit2026915f8f08413a04e2612483eec28d844102d7 (patch)
tree3dfb7367e7e6c70fb15092472f3a9b7083c53806 /Source/cmGeneratorTarget.cxx
parentcb8227ecbf8907c793d9e34a7aa77cbaa47c1bd8 (diff)
downloadCMake-2026915f8f08413a04e2612483eec28d844102d7.zip
CMake-2026915f8f08413a04e2612483eec28d844102d7.tar.gz
CMake-2026915f8f08413a04e2612483eec28d844102d7.tar.bz2
Swift: Propagate Swift_MODULE_DIRECTORY as include directory
Teach include directory computation for Swift to implicitly propagate the `Swift_MODULE_DIRECTORY` of all linked targets as include directories. This is required to ensure that the swiftmodule of a linked target is accessible to the compiler of the current target. Fixes: #19272
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r--Source/cmGeneratorTarget.cxx84
1 files changed, 84 insertions, 0 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ad142d7..cb80fe6 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1282,6 +1282,86 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
+std::string AddSwiftInterfaceIncludeDirectories(
+ const cmGeneratorTarget* root, const cmGeneratorTarget* target,
+ const std::string& config, cmGeneratorExpressionDAGChecker* context)
+{
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ context };
+ switch (dag.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dag.ReportError(nullptr,
+ "$<TARGET_PROPERTY:" + target->GetName() +
+ ",Swift_MODULE_DIRECTORY>");
+ return "";
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return "";
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We have already seen this transitive property.
+ return "";
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ std::string directories;
+ if (const auto* interface =
+ target->GetLinkInterfaceLibraries(config, root, true)) {
+ for (const cmLinkItem& library : interface->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ std::string value =
+ dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+ if (value.empty()) {
+ value =
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ }
+
+ if (!directories.empty()) {
+ directories += ";";
+ }
+ directories += value;
+ }
+ }
+ }
+ }
+ return directories;
+}
+
+void AddSwiftImplicitIncludeDirectories(
+ const cmGeneratorTarget* target, const std::string& config,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
+{
+ if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ nullptr };
+
+ for (const cmLinkImplItem& library : libraries->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
+
+ if (const char* val =
+ dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+ entry.Values.emplace_back(val);
+ } else {
+ entry.Values.emplace_back(
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ }
+
+ cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
+ config, &dag),
+ entry.Values);
+
+ entries.emplace_back(std::move(entry));
+ }
+ }
+ }
+ }
+}
+
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
@@ -3177,6 +3257,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
this->IncludeDirectoriesEntries);
+ if (lang == "Swift") {
+ AddSwiftImplicitIncludeDirectories(this, config, entries);
+ }
+
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries);