Skip to content

Commit bdcadcb

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 bdcadcb

File tree

10 files changed

+47
-10
lines changed

10 files changed

+47
-10
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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,8 +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+
SerializationOpts.IsInterfaceSDKRelative = true;
297+
}
296298
else
297299
SerializationOpts.ModuleInterface = InPath;
298300

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
16151615
break;
16161616
}
16171617
case input_block::MODULE_INTERFACE_PATH: {
1618+
input_block::ModuleInterfaceLayout::readRecord(scratch, IsModuleInterfaceSDKRelative);
16181619
ModuleInterfacePath = blobData;
16191620
break;
16201621
}
@@ -1837,10 +1838,10 @@ bool ModuleFileSharedCore::hasSourceInfo() const {
18371838
std::string ModuleFileSharedCore::resolveModuleDefiningFilePath(const StringRef SDKPath) const {
18381839
if (!ModuleInterfacePath.empty()) {
18391840
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();
1841+
if (IsModuleInterfaceSDKRelative && !ModuleInterfacePath.starts_with(SDKPath)) {
1842+
SmallString<128> resolvedPath(SDKPath);
1843+
llvm::sys::path::append(resolvedPath, interfacePath);
1844+
return resolvedPath.str().str();
18441845
} else
18451846
return interfacePath;
18461847
} else

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ class ModuleFileSharedCore {
7373
///
7474
/// Empty if this module didn't come from an interface file.
7575
StringRef ModuleInterfacePath;
76+
77+
/// true if this module interface was serialized relative to the SDK path.
78+
bool IsModuleInterfaceSDKRelative = false;
7679

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.

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)