Skip to content

Commit a007833

Browse files
committed
Add IsSDKRelative field to ModuleInterfaceLayout
When serializing the module interface path of an interface that is part of the SDK, we serialize relative to the SDK path. During deserialization we need to know if a path was serialized relative to the SDK or not. The existing logic assumes any relative path has been serialized relative to the SDK, which makes it impossible to compile modules from relative swiftinterface paths that are not part of the SDK. Update the swiftmodule file to include an attribute to show if the path was serialized relative to the SDK or not, which is used during deserialization to correctly reconstruct the interface path.
1 parent 9e7fa1a commit a007833

File tree

10 files changed

+50
-11
lines changed

10 files changed

+50
-11
lines changed

include/swift/Serialization/SerializationOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class SerializationOptions {
162162
bool SkipNonExportableDecls = false;
163163
bool ExplicitModuleBuild = false;
164164
bool EnableSerializationRemarks = false;
165+
bool IsInterfaceSDKRelative = false;
165166
};
166167

167168
} // end namespace swift

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,10 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
291291
StringRef SDKPath = Instance.getASTContext().SearchPathOpts.getSDKPath();
292292

293293
auto SDKRelativePath = getRelativeDepPath(InPath, SDKPath);
294-
if (SDKRelativePath.has_value())
294+
if (SDKRelativePath.has_value()) {
295295
SerializationOpts.ModuleInterface = SDKRelativePath.value();
296-
else
296+
SerializationOpts.IsInterfaceSDKRelative = true;
297+
} else
297298
SerializationOpts.ModuleInterface = InPath;
298299

299300
SerializationOpts.SDKName = Instance.getASTContext().LangOpts.SDKName;

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
16151615
break;
16161616
}
16171617
case input_block::MODULE_INTERFACE_PATH: {
1618+
input_block::ModuleInterfaceLayout::readRecord(
1619+
scratch, IsModuleInterfaceSDKRelative);
16181620
ModuleInterfacePath = blobData;
16191621
break;
16201622
}
@@ -1837,10 +1839,12 @@ bool ModuleFileSharedCore::hasSourceInfo() const {
18371839
std::string ModuleFileSharedCore::resolveModuleDefiningFilePath(const StringRef SDKPath) const {
18381840
if (!ModuleInterfacePath.empty()) {
18391841
std::string interfacePath = ModuleInterfacePath.str();
1840-
if (llvm::sys::path::is_relative(interfacePath) && !ModuleInterfacePath.starts_with(SDKPath)) {
1841-
SmallString<128> absoluteInterfacePath(SDKPath);
1842-
llvm::sys::path::append(absoluteInterfacePath, interfacePath);
1843-
return absoluteInterfacePath.str().str();
1842+
if (IsModuleInterfaceSDKRelative &&
1843+
!ModuleInterfacePath.starts_with(SDKPath) &&
1844+
llvm::sys::path::is_relative(interfacePath)) {
1845+
SmallString<128> resolvedPath(SDKPath);
1846+
llvm::sys::path::append(resolvedPath, interfacePath);
1847+
return resolvedPath.str().str();
18441848
} else
18451849
return interfacePath;
18461850
} else

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ class ModuleFileSharedCore {
7474
/// Empty if this module didn't come from an interface file.
7575
StringRef ModuleInterfacePath;
7676

77+
/// true if this module interface was serialized relative to the SDK path.
78+
bool IsModuleInterfaceSDKRelative = false;
79+
7780
/// The module interface path if this module is adjacent to such an interface
7881
/// or it was itself compiled from an interface. Empty otherwise.
7982
StringRef CorrespondingInterfacePath;

lib/Serialization/ModuleFormat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 904; // @available renamed decl ID removed
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 905; // IsModuleInterfaceSDKRelative
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -1158,7 +1158,8 @@ namespace input_block {
11581158

11591159
using ModuleInterfaceLayout = BCRecordLayout<
11601160
MODULE_INTERFACE_PATH,
1161-
BCBlob // file path
1161+
BCFixed<1>, // SDK-relative?
1162+
BCBlob // file path
11621163
>;
11631164

11641165
}

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,8 @@ void Serializer::writeInputBlock() {
13521352
}
13531353

13541354
if (!Options.ModuleInterface.empty())
1355-
ModuleInterface.emit(ScratchRecord, Options.ModuleInterface);
1355+
ModuleInterface.emit(ScratchRecord, Options.IsInterfaceSDKRelative,
1356+
Options.ModuleInterface);
13561357

13571358
SmallVector<ExternalMacroPlugin> macros;
13581359
M->getExternalMacros(macros);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -target arm64-apple-macosx15.0 -module-name A
3+
4+
import B
5+
6+
public struct AStruct {
7+
var y : BStruct
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -target arm64-apple-macosx15.0 -module-name B
3+
4+
import Swift
5+
6+
public struct BStruct {
7+
var x : Int
8+
public init()
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t.relative_interface_path)
2+
// RUN: cp -R %S/Inputs/relative_path %t.relative_interface_path/
3+
// RUN: cd %t.relative_interface_path
4+
// RUN: mkdir out
5+
6+
// RUN: %target-swift-frontend -target arm64-apple-macosx15.0 -compile-module-from-interface \
7+
// RUN: relative_path/B.swiftmodule/arm64-apple-macos.swiftinterface -o out/B.swiftmodule
8+
// RUN: %target-swift-frontend -target arm64-apple-macosx15.0 -compile-module-from-interface \
9+
// RUN: relative_path/A.swiftmodule/arm64-apple-macos.swiftinterface -o out/A.swiftmodule -I out
10+
11+
// REQUIRES: OS=macosx

test/Serialization/module_defining_interface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
// RUN: llvm-bcanalyzer -dump %t/inputs/Foo.swiftmodule > %t/Foo.sdk.moduledump.txt
1919
// RUN: cat %t/Foo.sdk.moduledump.txt | %FileCheck %s -check-prefix CHECK-SDK-FOO
2020

21-
// CHECK-FREESTANDING-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = '{{.*}}{{/|\\}}modules{{/|\\}}Foo.swiftinterface'
22-
// CHECK-SDK-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = 'usr/lib/Foo.swiftmodule/Foo.swiftinterface'
21+
// CHECK-FREESTANDING-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}} op0=0/> blob data = '{{.*}}{{/|\\}}modules{{/|\\}}Foo.swiftinterface'
22+
// CHECK-SDK-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}} op0=1/> blob data = 'usr/lib/Foo.swiftmodule/Foo.swiftinterface'
2323

2424
//--- modules/Foo.swiftinterface
2525
// swift-interface-format-version: 1.0

0 commit comments

Comments
 (0)