Browse Source

Ninja: Fix mixed Swift/CXX library target generation

With how things were before, mixed Swift/C++ libraries would result in a
broken ninja file.  `cpp.cpp.o` was emitted by the compiler, but was
also being included in the `linkBuild.Outputs` list, so it was being
emitted by multiple targets.

The fix checks that the source language is Swift before adding it to the
list of additional outputs. If it is Swift, this isn't a problem. If it
isn't Swift, we don't include it in the list of outputs.

On the other side, the C++ file was also being passed as a source file,
which the Swift compiler can't compile. So we add the C++ object file as
an explicit dependency and the object file is then added to the list of
Swift sources.
Evan Wilde 3 years ago
parent
commit
a9509cec7e
1 changed files with 14 additions and 7 deletions
  1. 14 7
      Source/cmNinjaNormalTargetGenerator.cxx

+ 14 - 7
Source/cmNinjaNormalTargetGenerator.cxx

@@ -1085,10 +1085,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
       this->GetGeneratorTarget()->GetObjectSources(sources, config);
       this->GetGeneratorTarget()->GetObjectSources(sources, config);
       cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
       cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
       for (const auto& source : sources) {
       for (const auto& source : sources) {
+        const std::string sourcePath = source->GetLanguage() == "Swift"
+          ? this->GetCompiledSourceNinjaPath(source)
+          : this->GetObjectFilePath(source, config);
         oss << " "
         oss << " "
-            << LocalGen->ConvertToOutputFormat(
-                 this->GetCompiledSourceNinjaPath(source),
-                 cmOutputConverter::SHELL);
+            << LocalGen->ConvertToOutputFormat(sourcePath,
+                                               cmOutputConverter::SHELL);
       }
       }
       return oss.str();
       return oss.str();
     }();
     }();
@@ -1106,10 +1108,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     std::vector<cmSourceFile const*> sources;
     std::vector<cmSourceFile const*> sources;
     gt->GetObjectSources(sources, config);
     gt->GetObjectSources(sources, config);
     for (const auto& source : sources) {
     for (const auto& source : sources) {
-      linkBuild.Outputs.push_back(
-        this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)));
-      linkBuild.ExplicitDeps.emplace_back(
-        this->GetCompiledSourceNinjaPath(source));
+      if (source->GetLanguage() == "Swift") {
+        linkBuild.Outputs.push_back(
+          this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)));
+        linkBuild.ExplicitDeps.emplace_back(
+          this->GetCompiledSourceNinjaPath(source));
+      } else {
+        linkBuild.ExplicitDeps.emplace_back(
+          this->GetObjectFilePath(source, config));
+      }
     }
     }
     linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
     linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
   } else {
   } else {