Skip to content

Commit 31c9254

Browse files
committed
Use target triple for “universal” modules
When loading a module supporting multiple targets, the module loader now looks for a file named with a normalized version of the target triple first, and only falls back to the architecture name if the normalized triple is not found.
1 parent b85d6a6 commit 31c9254

File tree

9 files changed

+282
-15
lines changed

9 files changed

+282
-15
lines changed

include/swift/Basic/Platform.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ namespace swift {
7474
///
7575
/// This is a stop-gap until full Triple support (ala Clang) exists within swiftc.
7676
StringRef getMajorArchitectureName(const llvm::Triple &triple);
77+
78+
/// Computes the normalized target triple used as the most preferred name for
79+
/// module loading.
80+
///
81+
/// For platforms with module stability, this canonicalizes architecture,
82+
/// vendor, and OS names, strips OS versions, and makes inferred environments
83+
/// explicit. For other platforms, it returns the unmodified triple.
84+
///
85+
/// The input triple should already be "normalized" in the sense that
86+
/// llvm::Triple::normalize() would not affect it.
87+
llvm::Triple getTargetSpecificModuleTriple(const llvm::Triple &triple);
7788
} // end namespace swift
7889

7990
#endif // SWIFT_BASIC_PLATFORM_H

lib/Basic/Platform.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "swift/Basic/Platform.h"
1414
#include "llvm/ADT/Triple.h"
15+
#include "llvm/ADT/StringSwitch.h"
16+
#include "llvm/ADT/StringExtras.h"
1517

1618
using namespace swift;
1719

@@ -188,3 +190,78 @@ StringRef swift::getMajorArchitectureName(const llvm::Triple &Triple) {
188190
return Triple.getArchName();
189191
}
190192
}
193+
194+
static StringRef
195+
getArchForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
196+
auto tripleArchName = triple.getArchName();
197+
198+
return llvm::StringSwitch<StringRef>(tripleArchName)
199+
.Cases("arm64", "aarch64", "arm64")
200+
.Case ("armv7s", "armv7s")
201+
.Case ("armv7k", "armv7k")
202+
.Case ("armv7", "armv7")
203+
.Case ("x86_64h", "x86_64h")
204+
.Cases("x86_64", "amd64", "x86_64")
205+
.Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986",
206+
"i386")
207+
.Cases("unknown", "", "unknown")
208+
.Default(tripleArchName);
209+
}
210+
211+
static StringRef
212+
getVendorForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
213+
return "apple";
214+
}
215+
216+
static StringRef
217+
getOSForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
218+
auto tripleOSName = triple.getOSName();
219+
220+
// Truncate the OS name before the first digit.
221+
auto tripleOSNameNoVersion = tripleOSName.take_until(llvm::isDigit);
222+
223+
return llvm::StringSwitch<StringRef>(tripleOSNameNoVersion)
224+
.Cases("macos", "macosx", "darwin", "macos")
225+
.Case ("ios", "ios")
226+
.Case ("tvos", "tvos")
227+
.Cases("unknown", "", "unknown")
228+
.Default(tripleOSNameNoVersion);
229+
}
230+
231+
static Optional<StringRef>
232+
getEnvironmentForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
233+
auto tripleEnvironment = triple.getEnvironmentName();
234+
235+
if (tripleEnvironment == "") {
236+
if (swift::tripleIsAnySimulator(triple))
237+
return StringRef("simulator");
238+
else
239+
return None;
240+
}
241+
242+
return llvm::StringSwitch<Optional<StringRef>>(tripleEnvironment)
243+
.Case("simulator", StringRef("simulator"))
244+
.Case("unknown", None)
245+
.Default(tripleEnvironment);
246+
}
247+
248+
llvm::Triple swift::getTargetSpecificModuleTriple(const llvm::Triple &triple) {
249+
if (triple.isOSDarwin()) {
250+
StringRef newArch = getArchForAppleTargetSpecificModuleTriple(triple);
251+
252+
StringRef newVendor = getVendorForAppleTargetSpecificModuleTriple(triple);
253+
254+
StringRef newOS = getOSForAppleTargetSpecificModuleTriple(triple);
255+
256+
Optional<StringRef> newEnvironment =
257+
getEnvironmentForAppleTargetSpecificModuleTriple(triple);
258+
259+
if (newEnvironment)
260+
return llvm::Triple(newArch, newVendor, newOS, *newEnvironment);
261+
else
262+
return llvm::Triple(newArch, newVendor, newOS);
263+
} else {
264+
return triple;
265+
}
266+
}
267+

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/DiagnosticsSema.h"
1717
#include "swift/Basic/Defer.h"
1818
#include "swift/Basic/FileTypes.h"
19+
#include "swift/Basic/Platform.h"
1920
#include "swift/Basic/STLExtras.h"
2021
#include "swift/Basic/SourceManager.h"
2122
#include "swift/Basic/Version.h"
@@ -166,18 +167,24 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
166167
llvm::SmallString<64> moduleName(moduleID.first.str());
167168
ModuleFilenamePair fileNames(moduleName);
168169

169-
StringRef archName = Ctx.LangOpts.Target.getArchName();
170-
171170
SmallVector<ModuleFilenamePair, 4> targetFileNamePairs;
172-
targetFileNamePairs.push_back(archName);
171+
172+
auto normalizedTarget = getTargetSpecificModuleTriple(Ctx.LangOpts.Target);
173+
targetFileNamePairs.push_back(ModuleFilenamePair(normalizedTarget.str()));
174+
175+
// Before this, we used the un-normalized architecture as a target-specific
176+
// module name. Fall back to that behavior.
177+
targetFileNamePairs.push_back(
178+
ModuleFilenamePair(Ctx.LangOpts.Target.getArchName())
179+
);
173180

174181
// FIXME: We used to use "major architecture" names for these files---the
175182
// names checked in "#if arch(...)". Fall back to that name in the one case
176183
// where it's different from what Swift 4.2 supported: 32-bit ARM platforms.
177184
// We should be able to drop this once there's an Xcode that supports the
178185
// new names.
179186
if (Ctx.LangOpts.Target.getArch() == llvm::Triple::ArchType::arm)
180-
targetFileNamePairs.push_back(StringRef("arm"));
187+
targetFileNamePairs.push_back(ModuleFilenamePair("arm"));
181188

182189
auto &fs = *Ctx.SourceMgr.getFileSystem();
183190
isFramework = false;
@@ -202,7 +209,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
202209
// We can only get here if all targetFileNamePairs failed with
203210
// 'std::errc::no_such_file_or_directory'.
204211
if (maybeDiagnoseArchitectureMismatch(moduleID.second,
205-
moduleName, archName, currPath)) {
212+
moduleName, normalizedTarget.str(), currPath)) {
206213
return false;
207214
} else {
208215
return None;

test/ParseableInterface/ModuleCache/force-module-loading-mode-archs.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
// RUN: %empty-directory(%t/Lib.swiftmodule)
6161
// RUN: touch %t/Lib.swiftmodule/garbage.swiftmodule
6262
// RUN: touch %t/Lib.swiftmodule/garbage.swiftinterface
63-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
64-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
63+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
64+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6565
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=NO-SUCH-MODULE %s
66-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
66+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6767
// (default)
68-
// RUN: not %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP -I %t %s 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
68+
// RUN: not %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP -I %t %s 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6969

7070
// 8. Only the interface is present but for the wrong architecture.
7171
// (Diagnostics for the module only are tested elsewhere.)

test/ParseableInterface/ModuleCache/force-module-loading-mode-framework.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
// RUN: %empty-directory(%t/Lib.framework/Modules/Lib.swiftmodule)
6161
// RUN: touch %t/Lib.framework/Modules/Lib.swiftmodule/garbage.swiftmodule
6262
// RUN: touch %t/Lib.framework/Modules/Lib.swiftmodule/garbage.swiftinterface
63-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
64-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
63+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
64+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6565
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=NO-SUCH-MODULE %s
66-
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
66+
// RUN: not env SWIFT_FORCE_MODULE_LOADING=only-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -F %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6767
// (default)
68-
// RUN: not %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP -F %t %s 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
68+
// RUN: not %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP -F %t %s 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
6969

7070
// 8. Only the interface is present but for the wrong architecture.
7171
// (Diagnostics for the module only are tested elsewhere.)

test/Serialization/load-invalid-arch.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
// RUN: touch %t/new_module.swiftmodule/ppc65.swiftmodule
66
// RUN: touch %t/new_module.swiftmodule/i387.swiftdoc
77
// RUN: touch %t/new_module.swiftmodule/ppc65.swiftdoc
8-
// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%target-cpu
8+
// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%module-target-triple
99

1010
// RUN: %empty-directory(%t)
1111
// RUN: mkdir -p %t/new_module.framework/Modules/new_module.swiftmodule/
1212
// RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/i387.swiftmodule
1313
// RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/ppc65.swiftmodule
14-
// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%target-cpu
14+
// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%module-target-triple
1515

1616
// RUN: %empty-directory(%t)
1717
// RUN: mkdir %t/new_module.swiftmodule
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// Tests that we prefer the normalized target triple name for a .swiftmodule,
4+
// but fall back to the legacy architecture name if necessary.
5+
6+
// RUN: mkdir %t/TargetLibrary.swiftmodule
7+
// RUN: %target-swift-frontend -emit-module -o %t/TargetLibrary.swiftmodule/%module-target-triple.swiftmodule %S/Inputs/def_func.swift -module-name TargetLibrary
8+
// RUN: touch %t/TargetLibrary.swiftmodule/%target-cpu.swiftmodule
9+
10+
import TargetLibrary
11+
12+
// RUN: mkdir %t/ArchLibrary.swiftmodule
13+
// RUN: %target-swift-frontend -emit-module -o %t/ArchLibrary.swiftmodule/%target-cpu.swiftmodule %S/Inputs/def_func.swift -module-name ArchLibrary
14+
15+
import ArchLibrary
16+
17+
// RUN: mkdir -p %t/TargetModule.framework/Modules/TargetModule.swiftmodule
18+
// RUN: %target-swift-frontend -emit-module -o %t/TargetModule.framework/Modules/TargetModule.swiftmodule/%module-target-triple.swiftmodule %S/Inputs/def_func.swift -module-name TargetModule
19+
// RUN: touch %t/TargetModule.framework/Modules/TargetModule.swiftmodule/%target-cpu.swiftmodule
20+
21+
import TargetModule
22+
23+
// RUN: mkdir -p %t/ArchModule.framework/Modules/ArchModule.swiftmodule
24+
// RUN: %target-swift-frontend -emit-module -o %t/ArchModule.framework/Modules/ArchModule.swiftmodule/%target-cpu.swiftmodule %S/Inputs/def_func.swift -module-name ArchModule
25+
26+
import ArchModule
27+
28+
// RUN: %target-swift-frontend %s -typecheck -I %t -F %t

0 commit comments

Comments
 (0)