diff --git a/include/swift-c/DependencyScan/DependencyScan.h b/include/swift-c/DependencyScan/DependencyScan.h index 87cc29113f1f3..50f6e9329a8cd 100644 --- a/include/swift-c/DependencyScan/DependencyScan.h +++ b/include/swift-c/DependencyScan/DependencyScan.h @@ -164,6 +164,10 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_swift_binary_detail_get_module_source_info_path( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC bool +swiftscan_swift_binary_detail_get_is_framework( + swiftscan_module_details_t details); + //=== Swift Placeholder Module Details query APIs -------------------------===// SWIFTSCAN_PUBLIC swiftscan_string_ref_t diff --git a/include/swift/DependencyScan/DependencyScanImpl.h b/include/swift/DependencyScan/DependencyScanImpl.h index 491173a4f32c4..2f9046a09d80f 100644 --- a/include/swift/DependencyScan/DependencyScanImpl.h +++ b/include/swift/DependencyScan/DependencyScanImpl.h @@ -104,6 +104,9 @@ typedef struct { /// The path to the .swiftSourceInfo file. swiftscan_string_ref_t module_source_info_path; + + /// A flag to indicate whether or not this module is a framework. + bool is_framework; } swiftscan_swift_binary_details_t; /// Swift placeholder modules carry additional details that specify their diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index 9a6d2267f50d1..52bc806093f0b 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -137,7 +137,7 @@ class SerializedModuleLoaderBase : public ModuleLoader { } /// Scan the given serialized module file to determine dependencies. - llvm::ErrorOr scanModuleFile(Twine modulePath); + llvm::ErrorOr scanModuleFile(Twine modulePath, bool isFramework); /// Load the module file into a buffer and also collect its module name. static std::unique_ptr diff --git a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp index b8cf014d1d406..f9405b17c355b 100644 --- a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp +++ b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp @@ -838,7 +838,8 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul Out, ScratchRecord, AbbrCodes[SwiftBinaryModuleDetailsLayout::Code], getIdentifier(swiftBinDeps->compiledModulePath), getIdentifier(swiftBinDeps->moduleDocPath), - getIdentifier(swiftBinDeps->sourceInfoPath), swiftBinDeps->isFramework); + getIdentifier(swiftBinDeps->sourceInfoPath), + swiftBinDeps->isFramework); break; } diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 604d6309babef..9a3a1341ecbc8 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -728,7 +728,9 @@ static void writeJSON(llvm::raw_ostream &out, writeJSONSingleField(out, "moduleSourceInfoPath", swiftBinaryDeps->module_source_info_path, /*indentLevel=*/5, - /*trailingComma=*/false); + /*trailingComma=*/true); + writeJSONSingleField(out, "isFramework", swiftBinaryDeps->is_framework, + 5, /*trailingComma=*/false); } else { out << "\"clang\": {\n"; @@ -893,7 +895,8 @@ generateFullDependencyGraph(CompilerInstance &instance, details->swift_binary_details = { create_clone(swiftBinaryDeps->compiledModulePath.c_str()), create_clone(swiftBinaryDeps->moduleDocPath.c_str()), - create_clone(swiftBinaryDeps->sourceInfoPath.c_str())}; + create_clone(swiftBinaryDeps->sourceInfoPath.c_str()), + swiftBinaryDeps->isFramework}; } else { // Clang module details details->kind = SWIFTSCAN_DEPENDENCY_INFO_CLANG; diff --git a/lib/Serialization/ModuleDependencyScanner.cpp b/lib/Serialization/ModuleDependencyScanner.cpp index e9f131fde371d..d5a9f93cbb3bc 100644 --- a/lib/Serialization/ModuleDependencyScanner.cpp +++ b/lib/Serialization/ModuleDependencyScanner.cpp @@ -43,7 +43,7 @@ std::error_code ModuleDependencyScanner::findModuleFilesInDirectory( if (LoadMode == ModuleLoadingMode::OnlySerialized || !fs.exists(InPath)) { if (fs.exists(ModPath)) { // The module file will be loaded directly. - auto dependencies = scanModuleFile(ModPath); + auto dependencies = scanModuleFile(ModPath, IsFramework); if (dependencies) { this->dependencies = std::move(dependencies.get()); return std::error_code(); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 78f9bef2eb1a6..e9080e3a25f29 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -392,7 +392,7 @@ std::error_code SerializedModuleLoaderBase::openModuleFile( } llvm::ErrorOr SerializedModuleLoaderBase::scanModuleFile( - Twine modulePath) { + Twine modulePath, bool isFramework) { // Open the module file auto &fs = *Ctx.SourceMgr.getFileSystem(); auto moduleBuf = fs.getBufferForFile(modulePath); @@ -401,7 +401,6 @@ llvm::ErrorOr SerializedModuleLoaderBase::scanModuleFile( // Load the module file without validation. std::shared_ptr loadedModuleFile; - bool isFramework = false; serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load( modulePath.str(), std::move(moduleBuf.get()), nullptr, nullptr, isFramework, isRequiredOSSAModules(), Ctx.LangOpts.SDKName, diff --git a/test/ScanDependencies/binary_framework_dependency.swift b/test/ScanDependencies/binary_framework_dependency.swift new file mode 100644 index 0000000000000..252d295a35154 --- /dev/null +++ b/test/ScanDependencies/binary_framework_dependency.swift @@ -0,0 +1,28 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: mkdir -p %t/Frameworks +// RUN: mkdir -p %t/Frameworks/Foo.framework/ +// RUN: mkdir -p %t/Frameworks/Foo.framework/Modules +// RUN: mkdir -p %t/Frameworks/Foo.framework/Modules/Foo.swiftmodule + +// Build a dependency into a binary module +// RUN: echo "public func foo() {}" >> %t/foo.swift +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Frameworks/Foo.framework/Modules/Foo.swiftmodule/%target-cpu.swiftmodule -module-cache-path %t.module-cache %t/foo.swift -module-name Foo + +// Run the scan +// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -F %t/Frameworks/ -sdk %t +// RUN: %FileCheck %s < %t/deps.json + +import Foo + +// CHECK: "swiftPrebuiltExternal": "Foo" +// CHECK: "swiftPrebuiltExternal": "Foo" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "modulePath": +// CHECK-NEXT: "directDependencies": [ +// CHECK: "details": { +// CHECK-NEXT: "swiftPrebuiltExternal": { +// CHECK-NEXT: "compiledModulePath": +// CHECK-NEXT: "isFramework": true +// CHECK-NEXT: } diff --git a/tools/libSwiftScan/libSwiftScan.cpp b/tools/libSwiftScan/libSwiftScan.cpp index 050dcc4570a9f..c2788d287dd22 100644 --- a/tools/libSwiftScan/libSwiftScan.cpp +++ b/tools/libSwiftScan/libSwiftScan.cpp @@ -311,6 +311,11 @@ swiftscan_swift_binary_detail_get_module_source_info_path( return details->swift_binary_details.module_source_info_path; } +bool swiftscan_swift_binary_detail_get_is_framework( + swiftscan_module_details_t details) { + return details->swift_binary_details.is_framework; +} + //=== Swift Placeholder Module Details query APIs -------------------------===// swiftscan_string_ref_t diff --git a/tools/libSwiftScan/libSwiftScan.exports b/tools/libSwiftScan/libSwiftScan.exports index 2400404c02cba..5ec5b882a5bc7 100644 --- a/tools/libSwiftScan/libSwiftScan.exports +++ b/tools/libSwiftScan/libSwiftScan.exports @@ -18,6 +18,7 @@ swiftscan_swift_textual_detail_get_is_framework swiftscan_swift_binary_detail_get_compiled_module_path swiftscan_swift_binary_detail_get_module_doc_path swiftscan_swift_binary_detail_get_module_source_info_path +swiftscan_swift_binary_detail_get_is_framework swiftscan_swift_placeholder_detail_get_compiled_module_path swiftscan_swift_placeholder_detail_get_module_doc_path swiftscan_swift_placeholder_detail_get_module_source_info_path