mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
This commit is contained in:
@@ -162,6 +162,7 @@ public:
|
||||
bool SkipNonExportableDecls = false;
|
||||
bool ExplicitModuleBuild = false;
|
||||
bool EnableSerializationRemarks = false;
|
||||
bool IsInterfaceSDKRelative = false;
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
@@ -291,9 +291,10 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
|
||||
StringRef SDKPath = Instance.getASTContext().SearchPathOpts.getSDKPath();
|
||||
|
||||
auto SDKRelativePath = getRelativeDepPath(InPath, SDKPath);
|
||||
if (SDKRelativePath.has_value())
|
||||
if (SDKRelativePath.has_value()) {
|
||||
SerializationOpts.ModuleInterface = SDKRelativePath.value();
|
||||
else
|
||||
SerializationOpts.IsInterfaceSDKRelative = true;
|
||||
} else
|
||||
SerializationOpts.ModuleInterface = InPath;
|
||||
|
||||
SerializationOpts.SDKName = Instance.getASTContext().LangOpts.SDKName;
|
||||
|
||||
@@ -1615,6 +1615,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
||||
break;
|
||||
}
|
||||
case input_block::MODULE_INTERFACE_PATH: {
|
||||
input_block::ModuleInterfaceLayout::readRecord(
|
||||
scratch, IsModuleInterfaceSDKRelative);
|
||||
ModuleInterfacePath = blobData;
|
||||
break;
|
||||
}
|
||||
@@ -1837,10 +1839,12 @@ bool ModuleFileSharedCore::hasSourceInfo() const {
|
||||
std::string ModuleFileSharedCore::resolveModuleDefiningFilePath(const StringRef SDKPath) const {
|
||||
if (!ModuleInterfacePath.empty()) {
|
||||
std::string interfacePath = ModuleInterfacePath.str();
|
||||
if (llvm::sys::path::is_relative(interfacePath) && !ModuleInterfacePath.starts_with(SDKPath)) {
|
||||
SmallString<128> absoluteInterfacePath(SDKPath);
|
||||
llvm::sys::path::append(absoluteInterfacePath, interfacePath);
|
||||
return absoluteInterfacePath.str().str();
|
||||
if (IsModuleInterfaceSDKRelative &&
|
||||
!ModuleInterfacePath.starts_with(SDKPath) &&
|
||||
llvm::sys::path::is_relative(interfacePath)) {
|
||||
SmallString<128> resolvedPath(SDKPath);
|
||||
llvm::sys::path::append(resolvedPath, interfacePath);
|
||||
return resolvedPath.str().str();
|
||||
} else
|
||||
return interfacePath;
|
||||
} else
|
||||
|
||||
@@ -74,6 +74,9 @@ class ModuleFileSharedCore {
|
||||
/// Empty if this module didn't come from an interface file.
|
||||
StringRef ModuleInterfacePath;
|
||||
|
||||
/// true if this module interface was serialized relative to the SDK path.
|
||||
bool IsModuleInterfaceSDKRelative = false;
|
||||
|
||||
/// The module interface path if this module is adjacent to such an interface
|
||||
/// or it was itself compiled from an interface. Empty otherwise.
|
||||
StringRef CorrespondingInterfacePath;
|
||||
|
||||
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
|
||||
/// describe what change you made. The content of this comment isn't important;
|
||||
/// it just ensures a conflict if two people change the module format.
|
||||
/// Don't worry about adhering to the 80-column limit for this line.
|
||||
const uint16_t SWIFTMODULE_VERSION_MINOR = 904; // @available renamed decl ID removed
|
||||
const uint16_t SWIFTMODULE_VERSION_MINOR = 905; // IsModuleInterfaceSDKRelative
|
||||
|
||||
/// A standard hash seed used for all string hashes in a serialized module.
|
||||
///
|
||||
@@ -1158,7 +1158,8 @@ namespace input_block {
|
||||
|
||||
using ModuleInterfaceLayout = BCRecordLayout<
|
||||
MODULE_INTERFACE_PATH,
|
||||
BCBlob // file path
|
||||
BCFixed<1>, // SDK-relative?
|
||||
BCBlob // file path
|
||||
>;
|
||||
|
||||
}
|
||||
|
||||
@@ -1352,7 +1352,8 @@ void Serializer::writeInputBlock() {
|
||||
}
|
||||
|
||||
if (!Options.ModuleInterface.empty())
|
||||
ModuleInterface.emit(ScratchRecord, Options.ModuleInterface);
|
||||
ModuleInterface.emit(ScratchRecord, Options.IsInterfaceSDKRelative,
|
||||
Options.ModuleInterface);
|
||||
|
||||
SmallVector<ExternalMacroPlugin> macros;
|
||||
M->getExternalMacros(macros);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// swift-interface-format-version: 1.0
|
||||
// swift-module-flags: -target arm64-apple-macosx15.0 -module-name A
|
||||
|
||||
import B
|
||||
|
||||
public struct AStruct {
|
||||
var y : BStruct
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// swift-interface-format-version: 1.0
|
||||
// swift-module-flags: -target arm64-apple-macosx15.0 -module-name B
|
||||
|
||||
import Swift
|
||||
|
||||
public struct BStruct {
|
||||
var x : Int
|
||||
public init()
|
||||
}
|
||||
11
test/ModuleInterface/relative-interface-path.swift
Normal file
11
test/ModuleInterface/relative-interface-path.swift
Normal file
@@ -0,0 +1,11 @@
|
||||
// RUN: %empty-directory(%t.relative_interface_path)
|
||||
// RUN: cp -R %S/Inputs/relative_path %t.relative_interface_path/
|
||||
// RUN: cd %t.relative_interface_path
|
||||
// RUN: mkdir out
|
||||
|
||||
// RUN: %target-swift-frontend -target arm64-apple-macosx15.0 -compile-module-from-interface \
|
||||
// RUN: relative_path/B.swiftmodule/arm64-apple-macos.swiftinterface -o out/B.swiftmodule
|
||||
// RUN: %target-swift-frontend -target arm64-apple-macosx15.0 -compile-module-from-interface \
|
||||
// RUN: relative_path/A.swiftmodule/arm64-apple-macos.swiftinterface -o out/A.swiftmodule -I out
|
||||
|
||||
// REQUIRES: OS=macosx
|
||||
@@ -18,8 +18,8 @@
|
||||
// RUN: llvm-bcanalyzer -dump %t/inputs/Foo.swiftmodule > %t/Foo.sdk.moduledump.txt
|
||||
// RUN: cat %t/Foo.sdk.moduledump.txt | %FileCheck %s -check-prefix CHECK-SDK-FOO
|
||||
|
||||
// CHECK-FREESTANDING-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = '{{.*}}{{/|\\}}modules{{/|\\}}Foo.swiftinterface'
|
||||
// CHECK-SDK-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = 'usr/lib/Foo.swiftmodule/Foo.swiftinterface'
|
||||
// CHECK-FREESTANDING-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}} op0=0/> blob data = '{{.*}}{{/|\\}}modules{{/|\\}}Foo.swiftinterface'
|
||||
// CHECK-SDK-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}} op0=1/> blob data = 'usr/lib/Foo.swiftmodule/Foo.swiftinterface'
|
||||
|
||||
//--- modules/Foo.swiftinterface
|
||||
// swift-interface-format-version: 1.0
|
||||
|
||||
Reference in New Issue
Block a user