From 44b2c08a5a3cc5a93af9045eae66b32c69ad97c9 Mon Sep 17 00:00:00 2001 From: Ian Anderson Date: Fri, 2 May 2025 23:57:08 -0700 Subject: [PATCH] [6.2][Driver][Frontend] -nostdimport and -nostdlibimport should remove the default framework search paths -nostdimport and -nostdlibimport only remove the toolchain and usr/lib/swift search paths, and they leave the framework search paths intact. That makes it impossible to get a fully custom SDK environment. Make their behavior match clang's -nostdinc/-nostdlibinc behavior: treat framework and non-framework paths the same. In other words, -nostdinc removes *all* compiler provided search paths, and -nostdlibinc removes *all* SDK search paths. Rename SkipRuntimeLibraryImportPaths to SkipAllImportPaths, and ExcludeSDKPathsFromRuntimeLibraryImportPaths to SkipSDKImportPaths to reflect their updated behavior. Move the DarwinImplicitFrameworkSearchPaths handling from SearchPathOptions to CompilerInvocation, where RuntimeLibraryImportPaths is managed. Rename it to just ImplicitFrameworkSearchPaths, and filter for Darwin when it's set up so that all of the clients don't have to do Darwin filtering themselves later. rdar://150557632 --- include/swift/AST/ASTContext.h | 4 -- include/swift/AST/SearchPathOptions.h | 45 ++++++++------------ lib/AST/ASTContext.cpp | 6 --- lib/AST/SearchPathOptions.cpp | 21 +++------ lib/Frontend/CompilerInvocation.cpp | 40 +++++++++++++++-- lib/Serialization/SerializedModuleLoader.cpp | 17 +++----- test/Frontend/default-search-paths.swift | 43 +++++++++++++++++++ 7 files changed, 110 insertions(+), 66 deletions(-) create mode 100644 test/Frontend/default-search-paths.swift diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 47e8fa4fe5e1d..95ac4ca708897 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -1090,10 +1090,6 @@ class ASTContext final { /// Retrieve the module interface checker associated with this AST context. ModuleInterfaceChecker *getModuleInterfaceChecker() const; - /// Compute the extra implicit framework search paths on Apple platforms: - /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. - std::vector getDarwinImplicitFrameworkSearchPaths() const; - /// Load extensions to the given nominal type from the external /// module loaders. /// diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index 1156288955327..0122d13fba2cc 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -35,7 +35,7 @@ namespace swift { enum class ModuleSearchPathKind { Import, Framework, - DarwinImplicitFramework, + ImplicitFramework, RuntimeLibrary, }; @@ -356,12 +356,8 @@ class SearchPathOptions { /// When on Darwin the framework paths that are implicitly imported. /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. /// - /// On non-Darwin platforms these are populated, but ignored. - /// - /// Computed when the SDK path is set and cached so we can reference the - /// Darwin implicit framework search paths as \c StringRef from - /// \c ModuleSearchPath. - std::vector DarwinImplicitFrameworkSearchPaths; + /// Must be modified through setter to keep \c Lookup in sync. + std::vector ImplicitFrameworkSearchPaths; /// Compiler plugin library search paths. std::vector CompilerPluginLibraryPaths; @@ -401,21 +397,6 @@ class SearchPathOptions { void setSDKPath(std::string NewSDKPath) { SDKPath = NewSDKPath; - - // Compute Darwin implicit framework search paths. - SmallString<128> systemFrameworksScratch(NewSDKPath); - llvm::sys::path::append(systemFrameworksScratch, "System", "Library", - "Frameworks"); - SmallString<128> systemSubFrameworksScratch(NewSDKPath); - llvm::sys::path::append(systemSubFrameworksScratch, "System", "Library", - "SubFrameworks"); - SmallString<128> frameworksScratch(NewSDKPath); - llvm::sys::path::append(frameworksScratch, "Library", "Frameworks"); - DarwinImplicitFrameworkSearchPaths = {systemFrameworksScratch.str().str(), - systemSubFrameworksScratch.str().str(), - frameworksScratch.str().str()}; - - Lookup.searchPathsDidChange(); } /// Retrieves the corresponding parent platform path for the SDK, or @@ -470,8 +451,14 @@ class SearchPathOptions { /// The extra implicit framework search paths on Apple platforms: /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. - ArrayRef getDarwinImplicitFrameworkSearchPaths() const { - return DarwinImplicitFrameworkSearchPaths; + ArrayRef getImplicitFrameworkSearchPaths() const { + return ImplicitFrameworkSearchPaths; + } + + void setImplicitFrameworkSearchPaths( + std::vector NewImplicitFrameworkSearchPaths) { + ImplicitFrameworkSearchPaths = NewImplicitFrameworkSearchPaths; + Lookup.searchPathsDidChange(); } ArrayRef getRuntimeLibraryImportPaths() const { @@ -505,11 +492,11 @@ class SearchPathOptions { /// Path to in-process plugin server shared library. std::string InProcessPluginServerPath; - /// Don't look in for compiler-provided modules. - bool SkipRuntimeLibraryImportPaths = false; + /// Don't automatically add any import paths. + bool SkipAllImplicitImportPaths = false; - /// Don't include SDK paths in the RuntimeLibraryImportPaths - bool ExcludeSDKPathsFromRuntimeLibraryImportPaths = false; + /// Don't automatically add any import paths from the SDK. + bool SkipSDKImportPaths = false; /// Scanner Prefix Mapper. std::vector ScannerPrefixMapper; @@ -619,6 +606,8 @@ class SearchPathOptions { RuntimeResourcePath, hash_combine_range(RuntimeLibraryImportPaths.begin(), RuntimeLibraryImportPaths.end()), + hash_combine_range(ImplicitFrameworkSearchPaths.begin(), + ImplicitFrameworkSearchPaths.end()), DisableModulesValidateSystemDependencies, ScannerModuleValidation, ModuleLoadMode); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b431967390b3f..ee7cc7ba7e95e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2198,12 +2198,6 @@ Identifier ASTContext::getRealModuleName(Identifier key, ModuleAliasLookupOption return value.first; } -std::vector ASTContext::getDarwinImplicitFrameworkSearchPaths() -const { - assert(LangOpts.Target.isOSDarwin()); - return SearchPathOpts.getDarwinImplicitFrameworkSearchPaths(); -} - void ASTContext::loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration) { PrettyStackTraceDecl stackTrace("loading extensions for", nominal); diff --git a/lib/AST/SearchPathOptions.cpp b/lib/AST/SearchPathOptions.cpp index 23bb767a5bdf2..308c0fc4754a0 100644 --- a/lib/AST/SearchPathOptions.cpp +++ b/lib/AST/SearchPathOptions.cpp @@ -58,14 +58,10 @@ void ModuleSearchPathLookup::rebuildLookupTable(const SearchPathOptions *Opts, Entry.value().IsSystem, Entry.index()); } - // Apple platforms have extra implicit framework search paths: - // $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. - if (IsOSDarwin) { - for (auto Entry : llvm::enumerate(Opts->getDarwinImplicitFrameworkSearchPaths())) { - addFilesInPathToLookupTable(FS, Entry.value(), - ModuleSearchPathKind::DarwinImplicitFramework, - /*isSystem=*/true, Entry.index()); - } + for (auto Entry : llvm::enumerate(Opts->getImplicitFrameworkSearchPaths())) { + addFilesInPathToLookupTable(FS, Entry.value(), + ModuleSearchPathKind::ImplicitFramework, + /*isSystem=*/true, Entry.index()); } for (auto Entry : llvm::enumerate(Opts->getRuntimeLibraryImportPaths())) { @@ -123,12 +119,9 @@ void SearchPathOptions::dump(bool isDarwin) const { << Entry.value().Path << "\n"; } - if (isDarwin) { - llvm::errs() << "Darwin implicit framework search paths:\n"; - for (auto Entry : - llvm::enumerate(getDarwinImplicitFrameworkSearchPaths())) { - llvm::errs() << " [" << Entry.index() << "] " << Entry.value() << "\n"; - } + llvm::errs() << "Implicit framework search paths:\n"; + for (auto Entry : llvm::enumerate(getImplicitFrameworkSearchPaths())) { + llvm::errs() << " [" << Entry.index() << "] " << Entry.value() << "\n"; } llvm::errs() << "Runtime library import search paths:\n"; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 22256cb84ba1b..660cf873fe0d1 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -254,7 +254,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts, SearchPathOpts.RuntimeLibraryPaths.push_back(DARWIN_OS_LIBRARY_PATH); // If this is set, we don't want any runtime import paths. - if (SearchPathOpts.SkipRuntimeLibraryImportPaths) { + if (SearchPathOpts.SkipAllImplicitImportPaths) { SearchPathOpts.setRuntimeLibraryImportPaths({}); return; } @@ -270,7 +270,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts, RuntimeLibraryImportPaths.push_back(std::string(LibPath.str())); } - if (!SearchPathOpts.ExcludeSDKPathsFromRuntimeLibraryImportPaths && !SearchPathOpts.getSDKPath().empty()) { + if (!SearchPathOpts.SkipSDKImportPaths && !SearchPathOpts.getSDKPath().empty()) { const char *swiftDir = FrontendOpts.UseSharedResourceFolder ? "swift" : "swift_static"; @@ -300,6 +300,35 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts, SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths); } +static void +updateImplicitFrameworkSearchPaths(SearchPathOptions &SearchPathOpts, + const LangOptions &LangOpts) { + if (SearchPathOpts.SkipAllImplicitImportPaths) { + SearchPathOpts.setImplicitFrameworkSearchPaths({}); + return; + } + + std::vector ImplicitFrameworkSearchPaths; + if (LangOpts.Target.isOSDarwin()) { + if (!SearchPathOpts.SkipSDKImportPaths && + !SearchPathOpts.getSDKPath().empty()) { + SmallString<128> SDKPath(SearchPathOpts.getSDKPath()); + SmallString<128> systemFrameworksScratch(SDKPath); + llvm::sys::path::append(systemFrameworksScratch, "System", "Library", + "Frameworks"); + SmallString<128> systemSubFrameworksScratch(SDKPath); + llvm::sys::path::append(systemSubFrameworksScratch, "System", "Library", + "SubFrameworks"); + SmallString<128> frameworksScratch(SDKPath); + llvm::sys::path::append(frameworksScratch, "Library", "Frameworks"); + ImplicitFrameworkSearchPaths = {systemFrameworksScratch.str().str(), + systemSubFrameworksScratch.str().str(), + frameworksScratch.str().str()}; + } + } + SearchPathOpts.setImplicitFrameworkSearchPaths(ImplicitFrameworkSearchPaths); +} + static void setIRGenOutputOptsFromFrontendOptions(IRGenOptions &IRGenOpts, const FrontendOptions &FrontendOpts) { @@ -411,11 +440,13 @@ void CompilerInvocation::setTargetTriple(StringRef Triple) { void CompilerInvocation::setTargetTriple(const llvm::Triple &Triple) { LangOpts.setTarget(Triple); updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); + updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts); } void CompilerInvocation::setSDKPath(const std::string &Path) { SearchPathOpts.setSDKPath(Path); updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); + updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts); } bool CompilerInvocation::setModuleAliasMap(std::vector args, @@ -2388,8 +2419,8 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_resource_dir)) Opts.RuntimeResourcePath = A->getValue(); - Opts.SkipRuntimeLibraryImportPaths |= Args.hasArg(OPT_nostdimport); - Opts.ExcludeSDKPathsFromRuntimeLibraryImportPaths |= Args.hasArg(OPT_nostdlibimport); + Opts.SkipAllImplicitImportPaths |= Args.hasArg(OPT_nostdimport); + Opts.SkipSDKImportPaths |= Args.hasArg(OPT_nostdlibimport); Opts.DisableModulesValidateSystemDependencies |= Args.hasArg(OPT_disable_modules_validate_system_headers); @@ -4053,6 +4084,7 @@ bool CompilerInvocation::parseArgs( } updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); + updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts); setDefaultPrebuiltCacheIfNecessary(); setDefaultBlocklistsIfNecessary(); setDefaultInProcessPluginServerPathIfNecessary(); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index c0d81d8d45b79..d56fe1b4fa852 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -108,14 +108,11 @@ std::optional forEachModuleSearchPath( callback(path.Path, ModuleSearchPathKind::Framework, path.IsSystem)) return result; - // Apple platforms have extra implicit framework search paths: - // $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. - if (Ctx.LangOpts.Target.isOSDarwin()) { - for (const auto &path : Ctx.getDarwinImplicitFrameworkSearchPaths()) - if (auto result = - callback(path, ModuleSearchPathKind::DarwinImplicitFramework, - /*isSystem=*/true)) - return result; + for (const auto &path : + Ctx.SearchPathOpts.getImplicitFrameworkSearchPaths()) { + if (auto result = callback(path, ModuleSearchPathKind::ImplicitFramework, + /*isSystem=*/true)) + return result; } for (const auto &importPath : @@ -240,7 +237,7 @@ void SerializedModuleLoaderBase::collectVisibleTopLevelModuleNamesImpl( return std::nullopt; } case ModuleSearchPathKind::Framework: - case ModuleSearchPathKind::DarwinImplicitFramework: { + case ModuleSearchPathKind::ImplicitFramework: { // Look for: // $PATH/{name}.framework/Modules/{name}.swiftmodule/{arch}.{extension} forEachDirectoryEntryPath(searchPath, [&](StringRef path) { @@ -964,7 +961,7 @@ bool SerializedModuleLoaderBase::findModule( continue; } case ModuleSearchPathKind::Framework: - case ModuleSearchPathKind::DarwinImplicitFramework: { + case ModuleSearchPathKind::ImplicitFramework: { isFramework = true; llvm::sys::path::append(currPath, moduleName + ".framework"); diff --git a/test/Frontend/default-search-paths.swift b/test/Frontend/default-search-paths.swift new file mode 100644 index 0000000000000..d626bd1506b23 --- /dev/null +++ b/test/Frontend/default-search-paths.swift @@ -0,0 +1,43 @@ +// UNSUPPORTED: OS=windows-msvc + +// Standard Apple paths. +// RUN: %swift_frontend_plain -target arm64-apple-macos15.4 %clang-importer-sdk-nosource -parse-stdlib -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=APPLE %s +// APPLE: Implicit framework search paths: +// APPLE-NEXT: [0] SOURCE_DIR/test/Inputs/clang-importer-sdk/System/Library/Frameworks +// APPLE-NEXT: [1] SOURCE_DIR/test/Inputs/clang-importer-sdk/System/Library/SubFrameworks +// APPLE-NEXT: [2] SOURCE_DIR/test/Inputs/clang-importer-sdk/Library/Frameworks +// APPLE-NEXT: Runtime library import search paths: +// APPLE-NEXT: [0] BUILD_DIR/lib/swift/macosx +// APPLE-NEXT: [1] SOURCE_DIR/test/Inputs/clang-importer-sdk/usr/lib/swift +// APPLE-NEXT: (End of search path lists.) + +// Non-Apple platforms don't have any implicit framework search paths. +// RUN: %swift_frontend_plain -target x86_64-unknown-linux-android %clang-importer-sdk-nosource -parse-stdlib -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=ANDROID %s +// ANDROID: Implicit framework search paths: +// ANDROID-NEXT: Runtime library import search paths: +// ANDROID-NEXT: [0] BUILD_DIR/lib/swift/android +// ANDROID-NEXT: [1] BUILD_DIR/lib/swift/android/x86_64 +// ANDROID-NEXT: [2] SOURCE_DIR/test/Inputs/clang-importer-sdk/usr/lib/swift/android +// ANDROID-NEXT: [3] SOURCE_DIR/test/Inputs/clang-importer-sdk/usr/lib/swift/android/x86_64 +// ANDROID-NEXT: (End of search path lists.) + +// -nostdimport doesn't set up any standard import paths at all. +// RUN: %swift_frontend_plain -target arm64-apple-macos15.4 %clang-importer-sdk-nosource -parse-stdlib -nostdimport -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=NOSTDIMPORT %s +// RUN: %swift_frontend_plain -target x86_64-unknown-linux-android %clang-importer-sdk-nosource -parse-stdlib -nostdimport -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=NOSTDIMPORT %s +// NOSTDIMPORT: Implicit framework search paths: +// NOSTDIMPORT-NEXT: Runtime library import search paths: +// NOSTDIMPORT-NEXT: (End of search path lists.) + +// -nostdlibimport removes all of the standard imports from the SDK but leaves the toolchain ones. +// RUN: %swift_frontend_plain -target arm64-apple-macos15.4 %clang-importer-sdk-nosource -parse-stdlib -nostdlibimport -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=APPLE-NOSTDLIBIMPORT %s +// APPLE-NOSTDLIBIMPORT: Implicit framework search paths: +// APPLE-NOSTDLIBIMPORT-NEXT: Runtime library import search paths: +// APPLE-NOSTDLIBIMPORT-NEXT: [0] BUILD_DIR/lib/swift/macosx +// APPLE-NOSTDLIBIMPORT-NEXT: (End of search path lists.) + +// RUN: %swift_frontend_plain -target x86_64-unknown-linux-android %clang-importer-sdk-nosource -parse-stdlib -nostdlibimport -parse %s -Rmodule-loading 2>&1 | %FileCheck -check-prefix=ANDROID-NOSTDLIBIMPORT %s +// ANDROID-NOSTDLIBIMPORT: Implicit framework search paths: +// ANDROID-NOSTDLIBIMPORT-NEXT: Runtime library import search paths: +// ANDROID-NOSTDLIBIMPORT-NEXT: [0] BUILD_DIR/lib/swift/android +// ANDROID-NOSTDLIBIMPORT-NEXT: [1] BUILD_DIR/lib/swift/android/x86_64 +// ANDROID-NOSTDLIBIMPORT-NEXT: (End of search path lists.)