[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
This commit is contained in:
Ian Anderson
2025-05-02 23:57:08 -07:00
parent e2ee46d724
commit 44b2c08a5a
7 changed files with 110 additions and 66 deletions

View File

@@ -1090,10 +1090,6 @@ public:
/// Retrieve the module interface checker associated with this AST context. /// Retrieve the module interface checker associated with this AST context.
ModuleInterfaceChecker *getModuleInterfaceChecker() const; ModuleInterfaceChecker *getModuleInterfaceChecker() const;
/// Compute the extra implicit framework search paths on Apple platforms:
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
std::vector<std::string> getDarwinImplicitFrameworkSearchPaths() const;
/// Load extensions to the given nominal type from the external /// Load extensions to the given nominal type from the external
/// module loaders. /// module loaders.
/// ///

View File

@@ -35,7 +35,7 @@ namespace swift {
enum class ModuleSearchPathKind { enum class ModuleSearchPathKind {
Import, Import,
Framework, Framework,
DarwinImplicitFramework, ImplicitFramework,
RuntimeLibrary, RuntimeLibrary,
}; };
@@ -356,12 +356,8 @@ private:
/// When on Darwin the framework paths that are implicitly imported. /// When on Darwin the framework paths that are implicitly imported.
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
/// ///
/// On non-Darwin platforms these are populated, but ignored. /// Must be modified through setter to keep \c Lookup in sync.
/// std::vector<std::string> ImplicitFrameworkSearchPaths;
/// 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<std::string> DarwinImplicitFrameworkSearchPaths;
/// Compiler plugin library search paths. /// Compiler plugin library search paths.
std::vector<std::string> CompilerPluginLibraryPaths; std::vector<std::string> CompilerPluginLibraryPaths;
@@ -401,21 +397,6 @@ public:
void setSDKPath(std::string NewSDKPath) { void setSDKPath(std::string NewSDKPath) {
SDKPath = 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 /// Retrieves the corresponding parent platform path for the SDK, or
@@ -470,8 +451,14 @@ public:
/// The extra implicit framework search paths on Apple platforms: /// The extra implicit framework search paths on Apple platforms:
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. /// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
ArrayRef<std::string> getDarwinImplicitFrameworkSearchPaths() const { ArrayRef<std::string> getImplicitFrameworkSearchPaths() const {
return DarwinImplicitFrameworkSearchPaths; return ImplicitFrameworkSearchPaths;
}
void setImplicitFrameworkSearchPaths(
std::vector<std::string> NewImplicitFrameworkSearchPaths) {
ImplicitFrameworkSearchPaths = NewImplicitFrameworkSearchPaths;
Lookup.searchPathsDidChange();
} }
ArrayRef<std::string> getRuntimeLibraryImportPaths() const { ArrayRef<std::string> getRuntimeLibraryImportPaths() const {
@@ -505,11 +492,11 @@ public:
/// Path to in-process plugin server shared library. /// Path to in-process plugin server shared library.
std::string InProcessPluginServerPath; std::string InProcessPluginServerPath;
/// Don't look in for compiler-provided modules. /// Don't automatically add any import paths.
bool SkipRuntimeLibraryImportPaths = false; bool SkipAllImplicitImportPaths = false;
/// Don't include SDK paths in the RuntimeLibraryImportPaths /// Don't automatically add any import paths from the SDK.
bool ExcludeSDKPathsFromRuntimeLibraryImportPaths = false; bool SkipSDKImportPaths = false;
/// Scanner Prefix Mapper. /// Scanner Prefix Mapper.
std::vector<std::string> ScannerPrefixMapper; std::vector<std::string> ScannerPrefixMapper;
@@ -619,6 +606,8 @@ public:
RuntimeResourcePath, RuntimeResourcePath,
hash_combine_range(RuntimeLibraryImportPaths.begin(), hash_combine_range(RuntimeLibraryImportPaths.begin(),
RuntimeLibraryImportPaths.end()), RuntimeLibraryImportPaths.end()),
hash_combine_range(ImplicitFrameworkSearchPaths.begin(),
ImplicitFrameworkSearchPaths.end()),
DisableModulesValidateSystemDependencies, DisableModulesValidateSystemDependencies,
ScannerModuleValidation, ScannerModuleValidation,
ModuleLoadMode); ModuleLoadMode);

View File

@@ -2198,12 +2198,6 @@ Identifier ASTContext::getRealModuleName(Identifier key, ModuleAliasLookupOption
return value.first; return value.first;
} }
std::vector<std::string> ASTContext::getDarwinImplicitFrameworkSearchPaths()
const {
assert(LangOpts.Target.isOSDarwin());
return SearchPathOpts.getDarwinImplicitFrameworkSearchPaths();
}
void ASTContext::loadExtensions(NominalTypeDecl *nominal, void ASTContext::loadExtensions(NominalTypeDecl *nominal,
unsigned previousGeneration) { unsigned previousGeneration) {
PrettyStackTraceDecl stackTrace("loading extensions for", nominal); PrettyStackTraceDecl stackTrace("loading extensions for", nominal);

View File

@@ -58,14 +58,10 @@ void ModuleSearchPathLookup::rebuildLookupTable(const SearchPathOptions *Opts,
Entry.value().IsSystem, Entry.index()); Entry.value().IsSystem, Entry.index());
} }
// Apple platforms have extra implicit framework search paths: for (auto Entry : llvm::enumerate(Opts->getImplicitFrameworkSearchPaths())) {
// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. addFilesInPathToLookupTable(FS, Entry.value(),
if (IsOSDarwin) { ModuleSearchPathKind::ImplicitFramework,
for (auto Entry : llvm::enumerate(Opts->getDarwinImplicitFrameworkSearchPaths())) { /*isSystem=*/true, Entry.index());
addFilesInPathToLookupTable(FS, Entry.value(),
ModuleSearchPathKind::DarwinImplicitFramework,
/*isSystem=*/true, Entry.index());
}
} }
for (auto Entry : llvm::enumerate(Opts->getRuntimeLibraryImportPaths())) { for (auto Entry : llvm::enumerate(Opts->getRuntimeLibraryImportPaths())) {
@@ -123,12 +119,9 @@ void SearchPathOptions::dump(bool isDarwin) const {
<< Entry.value().Path << "\n"; << Entry.value().Path << "\n";
} }
if (isDarwin) { llvm::errs() << "Implicit framework search paths:\n";
llvm::errs() << "Darwin implicit framework search paths:\n"; for (auto Entry : llvm::enumerate(getImplicitFrameworkSearchPaths())) {
for (auto Entry : llvm::errs() << " [" << Entry.index() << "] " << Entry.value() << "\n";
llvm::enumerate(getDarwinImplicitFrameworkSearchPaths())) {
llvm::errs() << " [" << Entry.index() << "] " << Entry.value() << "\n";
}
} }
llvm::errs() << "Runtime library import search paths:\n"; llvm::errs() << "Runtime library import search paths:\n";

View File

@@ -254,7 +254,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
SearchPathOpts.RuntimeLibraryPaths.push_back(DARWIN_OS_LIBRARY_PATH); SearchPathOpts.RuntimeLibraryPaths.push_back(DARWIN_OS_LIBRARY_PATH);
// If this is set, we don't want any runtime import paths. // If this is set, we don't want any runtime import paths.
if (SearchPathOpts.SkipRuntimeLibraryImportPaths) { if (SearchPathOpts.SkipAllImplicitImportPaths) {
SearchPathOpts.setRuntimeLibraryImportPaths({}); SearchPathOpts.setRuntimeLibraryImportPaths({});
return; return;
} }
@@ -270,7 +270,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
RuntimeLibraryImportPaths.push_back(std::string(LibPath.str())); RuntimeLibraryImportPaths.push_back(std::string(LibPath.str()));
} }
if (!SearchPathOpts.ExcludeSDKPathsFromRuntimeLibraryImportPaths && !SearchPathOpts.getSDKPath().empty()) { if (!SearchPathOpts.SkipSDKImportPaths && !SearchPathOpts.getSDKPath().empty()) {
const char *swiftDir = FrontendOpts.UseSharedResourceFolder const char *swiftDir = FrontendOpts.UseSharedResourceFolder
? "swift" : "swift_static"; ? "swift" : "swift_static";
@@ -300,6 +300,35 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths); SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths);
} }
static void
updateImplicitFrameworkSearchPaths(SearchPathOptions &SearchPathOpts,
const LangOptions &LangOpts) {
if (SearchPathOpts.SkipAllImplicitImportPaths) {
SearchPathOpts.setImplicitFrameworkSearchPaths({});
return;
}
std::vector<std::string> 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 static void
setIRGenOutputOptsFromFrontendOptions(IRGenOptions &IRGenOpts, setIRGenOutputOptsFromFrontendOptions(IRGenOptions &IRGenOpts,
const FrontendOptions &FrontendOpts) { const FrontendOptions &FrontendOpts) {
@@ -411,11 +440,13 @@ void CompilerInvocation::setTargetTriple(StringRef Triple) {
void CompilerInvocation::setTargetTriple(const llvm::Triple &Triple) { void CompilerInvocation::setTargetTriple(const llvm::Triple &Triple) {
LangOpts.setTarget(Triple); LangOpts.setTarget(Triple);
updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts);
updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts);
} }
void CompilerInvocation::setSDKPath(const std::string &Path) { void CompilerInvocation::setSDKPath(const std::string &Path) {
SearchPathOpts.setSDKPath(Path); SearchPathOpts.setSDKPath(Path);
updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts);
updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts);
} }
bool CompilerInvocation::setModuleAliasMap(std::vector<std::string> args, bool CompilerInvocation::setModuleAliasMap(std::vector<std::string> args,
@@ -2388,8 +2419,8 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_resource_dir)) if (const Arg *A = Args.getLastArg(OPT_resource_dir))
Opts.RuntimeResourcePath = A->getValue(); Opts.RuntimeResourcePath = A->getValue();
Opts.SkipRuntimeLibraryImportPaths |= Args.hasArg(OPT_nostdimport); Opts.SkipAllImplicitImportPaths |= Args.hasArg(OPT_nostdimport);
Opts.ExcludeSDKPathsFromRuntimeLibraryImportPaths |= Args.hasArg(OPT_nostdlibimport); Opts.SkipSDKImportPaths |= Args.hasArg(OPT_nostdlibimport);
Opts.DisableModulesValidateSystemDependencies |= Opts.DisableModulesValidateSystemDependencies |=
Args.hasArg(OPT_disable_modules_validate_system_headers); Args.hasArg(OPT_disable_modules_validate_system_headers);
@@ -4053,6 +4084,7 @@ bool CompilerInvocation::parseArgs(
} }
updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts); updateRuntimeLibraryPaths(SearchPathOpts, FrontendOpts, LangOpts);
updateImplicitFrameworkSearchPaths(SearchPathOpts, LangOpts);
setDefaultPrebuiltCacheIfNecessary(); setDefaultPrebuiltCacheIfNecessary();
setDefaultBlocklistsIfNecessary(); setDefaultBlocklistsIfNecessary();
setDefaultInProcessPluginServerPathIfNecessary(); setDefaultInProcessPluginServerPathIfNecessary();

View File

@@ -108,14 +108,11 @@ std::optional<bool> forEachModuleSearchPath(
callback(path.Path, ModuleSearchPathKind::Framework, path.IsSystem)) callback(path.Path, ModuleSearchPathKind::Framework, path.IsSystem))
return result; return result;
// Apple platforms have extra implicit framework search paths: for (const auto &path :
// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/. Ctx.SearchPathOpts.getImplicitFrameworkSearchPaths()) {
if (Ctx.LangOpts.Target.isOSDarwin()) { if (auto result = callback(path, ModuleSearchPathKind::ImplicitFramework,
for (const auto &path : Ctx.getDarwinImplicitFrameworkSearchPaths()) /*isSystem=*/true))
if (auto result = return result;
callback(path, ModuleSearchPathKind::DarwinImplicitFramework,
/*isSystem=*/true))
return result;
} }
for (const auto &importPath : for (const auto &importPath :
@@ -240,7 +237,7 @@ void SerializedModuleLoaderBase::collectVisibleTopLevelModuleNamesImpl(
return std::nullopt; return std::nullopt;
} }
case ModuleSearchPathKind::Framework: case ModuleSearchPathKind::Framework:
case ModuleSearchPathKind::DarwinImplicitFramework: { case ModuleSearchPathKind::ImplicitFramework: {
// Look for: // Look for:
// $PATH/{name}.framework/Modules/{name}.swiftmodule/{arch}.{extension} // $PATH/{name}.framework/Modules/{name}.swiftmodule/{arch}.{extension}
forEachDirectoryEntryPath(searchPath, [&](StringRef path) { forEachDirectoryEntryPath(searchPath, [&](StringRef path) {
@@ -964,7 +961,7 @@ bool SerializedModuleLoaderBase::findModule(
continue; continue;
} }
case ModuleSearchPathKind::Framework: case ModuleSearchPathKind::Framework:
case ModuleSearchPathKind::DarwinImplicitFramework: { case ModuleSearchPathKind::ImplicitFramework: {
isFramework = true; isFramework = true;
llvm::sys::path::append(currPath, moduleName + ".framework"); llvm::sys::path::append(currPath, moduleName + ".framework");

View File

@@ -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.)