diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 135ef9e941e..c83b6986a9d 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -386,6 +386,11 @@ void CompilerInstance::setupDependencyTrackerIfNeeded() { return; DepTracker = std::make_unique(*collectionMode); + + // Collect compiler plugin dependencies. + auto &searchPathOpts = Invocation.getSearchPathOptions(); + for (auto &path : searchPathOpts.getCompilerPluginLibraryPaths()) + DepTracker->addDependency(path, /*isSystem=*/false); } bool CompilerInstance::setup(const CompilerInvocation &Invoke, diff --git a/lib/FrontendTool/LoadedModuleTrace.cpp b/lib/FrontendTool/LoadedModuleTrace.cpp index 92016988ebe..e120e21217d 100644 --- a/lib/FrontendTool/LoadedModuleTrace.cpp +++ b/lib/FrontendTool/LoadedModuleTrace.cpp @@ -552,6 +552,7 @@ void ABIDependencyEvaluator::printABIExportMap(llvm::raw_ostream &os) const { // FIXME: Use the VFS instead of handling paths directly. We are particularly // sloppy about handling relative paths in the dependency tracker. static void computeSwiftModuleTraceInfo( + ASTContext &ctx, const SmallPtrSetImpl &abiDependencies, const llvm::DenseMap &pathToModuleDecl, const DependencyTracker &depTracker, StringRef prebuiltCachePath, @@ -569,6 +570,8 @@ static void computeSwiftModuleTraceInfo( SmallVector dependencies{deps.begin(), deps.end()}; auto incrDeps = depTracker.getIncrementalDependencyPaths(); dependencies.append(incrDeps.begin(), incrDeps.end()); + auto sharedLibraryExtRegex = + llvm::Regex("dylib|so|dll", llvm::Regex::IgnoreCase); for (const auto &depPath : dependencies) { // Decide if this is a swiftmodule based on the extension of the raw @@ -580,8 +583,10 @@ static void computeSwiftModuleTraceInfo( auto isSwiftmodule = moduleFileType == file_types::TY_SwiftModuleFile; auto isSwiftinterface = moduleFileType == file_types::TY_SwiftModuleInterfaceFile; + auto isSharedLibrary = + sharedLibraryExtRegex.match(llvm::sys::path::extension(depPath)); - if (!(isSwiftmodule || isSwiftinterface)) + if (!(isSwiftmodule || isSwiftinterface || isSharedLibrary)) continue; auto dep = pathToModuleDecl.find(depPath); @@ -637,6 +642,34 @@ static void computeSwiftModuleTraceInfo( continue; } + // If we found a shared library, it must be a compiler plugin dependency. + if (isSharedLibrary) { + // Infer the module name by dropping the library prefix and extension. + // e.g "/path/to/lib/libPlugin.dylib" -> "Plugin" + auto moduleName = llvm::sys::path::stem(depPath); + #if !defined(_WIN32) + moduleName.consume_front("lib"); + #endif + + StringRef realDepPath = + fs::real_path(depPath, buffer, /*expand_tile*/ true) + ? StringRef(depPath) + : buffer.str(); + + traceInfo.push_back( + {/*Name=*/ + ctx.getIdentifier(moduleName), + /*Path=*/ + realDepPath.str(), + /*IsImportedDirectly=*/ + false, + /*SupportsLibraryEvolution=*/ + false}); + buffer.clear(); + + continue; + } + // Skip cached modules in the prebuilt cache. We will add the corresponding // swiftinterface from the SDK directly, but this isn't checked. :-/ // @@ -731,8 +764,9 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule, } std::vector swiftModules; - computeSwiftModuleTraceInfo(abiDependencies, pathToModuleDecl, *depTracker, - opts.PrebuiltModuleCachePath, swiftModules); + computeSwiftModuleTraceInfo(ctxt, abiDependencies, pathToModuleDecl, + *depTracker, opts.PrebuiltModuleCachePath, + swiftModules); LoadedModuleTraceFormat trace = { /*version=*/LoadedModuleTraceFormat::CurrentVersion, diff --git a/test/Driver/Inputs/loaded_module_trace_compiler_plugin.swift b/test/Driver/Inputs/loaded_module_trace_compiler_plugin.swift new file mode 100644 index 00000000000..a1a790aa620 --- /dev/null +++ b/test/Driver/Inputs/loaded_module_trace_compiler_plugin.swift @@ -0,0 +1 @@ +// Don't need anything here, just for the module to exist. diff --git a/test/Driver/loaded_module_trace.swift b/test/Driver/loaded_module_trace.swift index acacf5e7dd1..941b30dc7c9 100644 --- a/test/Driver/loaded_module_trace.swift +++ b/test/Driver/loaded_module_trace.swift @@ -2,7 +2,8 @@ // RUN: %empty-directory(%t/cache) // RUN: %target-build-swift -emit-module -module-name Module %S/Inputs/loaded_module_trace_empty.swift -o %t/Module.swiftmodule -module-cache-path %t/cache // RUN: %target-build-swift -emit-module -module-name Module2 %S/Inputs/loaded_module_trace_imports_module.swift -o %t/Module2.swiftmodule -I %t -module-cache-path %t/cache -// RUN: %target-build-swift %s -emit-loaded-module-trace -o %t/loaded_module_trace -I %t -module-cache-path %t/cache +// RUN: %target-build-swift -emit-library -module-name Plugin %S/Inputs/loaded_module_trace_compiler_plugin.swift -o %t/%target-library-name(Plugin) -module-cache-path %t/cache +// RUN: %target-build-swift %s -emit-loaded-module-trace -o %t/loaded_module_trace -I %t -module-cache-path %t/cache -load-plugin-library %t/%target-library-name(Plugin) // RUN: %FileCheck -check-prefix=CHECK %s < %t/loaded_module_trace.trace.json // RUN: %FileCheck -check-prefix=CHECK-CONFIRM-ONELINE %s < %t/loaded_module_trace.trace.json @@ -25,6 +26,7 @@ // CHECK-DAG: {"name":"Swift","path":"{{[^"]*\\[/\\]}}Swift.swiftmodule{{(\\[/\\][^"]+[.]swiftmodule)?}}","isImportedDirectly":true,"supportsLibraryEvolution":true} // CHECK-DAG: {"name":"SwiftOnoneSupport","path":"{{[^"]*\\[/\\]}}SwiftOnoneSupport.swiftmodule{{(\\[/\\][^"]+[.]swiftmodule)?}}","isImportedDirectly":true,"supportsLibraryEvolution":true} // CHECK-DAG: {"name":"Module","path":"{{[^"]*\\[/\\]}}Module.swiftmodule","isImportedDirectly":false,"supportsLibraryEvolution":false} +// CHECK-DAG: {"name":"Plugin","path":"{{[^"]*\\[/\\]}}{{libPlugin.dylib|libPlugin.so|Plugin.dll}}","isImportedDirectly":false,"supportsLibraryEvolution":false} // CHECK: ] // CHECK: }