[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.
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
/// module loaders.
///

View File

@@ -35,7 +35,7 @@ namespace swift {
enum class ModuleSearchPathKind {
Import,
Framework,
DarwinImplicitFramework,
ImplicitFramework,
RuntimeLibrary,
};
@@ -356,12 +356,8 @@ private:
/// 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<std::string> DarwinImplicitFrameworkSearchPaths;
/// Must be modified through setter to keep \c Lookup in sync.
std::vector<std::string> ImplicitFrameworkSearchPaths;
/// Compiler plugin library search paths.
std::vector<std::string> CompilerPluginLibraryPaths;
@@ -401,21 +397,6 @@ public:
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 @@ public:
/// The extra implicit framework search paths on Apple platforms:
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
ArrayRef<std::string> getDarwinImplicitFrameworkSearchPaths() const {
return DarwinImplicitFrameworkSearchPaths;
ArrayRef<std::string> getImplicitFrameworkSearchPaths() const {
return ImplicitFrameworkSearchPaths;
}
void setImplicitFrameworkSearchPaths(
std::vector<std::string> NewImplicitFrameworkSearchPaths) {
ImplicitFrameworkSearchPaths = NewImplicitFrameworkSearchPaths;
Lookup.searchPathsDidChange();
}
ArrayRef<std::string> getRuntimeLibraryImportPaths() const {
@@ -505,11 +492,11 @@ public:
/// 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<std::string> ScannerPrefixMapper;
@@ -619,6 +606,8 @@ public:
RuntimeResourcePath,
hash_combine_range(RuntimeLibraryImportPaths.begin(),
RuntimeLibraryImportPaths.end()),
hash_combine_range(ImplicitFrameworkSearchPaths.begin(),
ImplicitFrameworkSearchPaths.end()),
DisableModulesValidateSystemDependencies,
ScannerModuleValidation,
ModuleLoadMode);

View File

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

View File

@@ -58,15 +58,11 @@ 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())) {
for (auto Entry : llvm::enumerate(Opts->getImplicitFrameworkSearchPaths())) {
addFilesInPathToLookupTable(FS, Entry.value(),
ModuleSearchPathKind::DarwinImplicitFramework,
ModuleSearchPathKind::ImplicitFramework,
/*isSystem=*/true, Entry.index());
}
}
for (auto Entry : llvm::enumerate(Opts->getRuntimeLibraryImportPaths())) {
addFilesInPathToLookupTable(FS, Entry.value(),
@@ -123,13 +119,10 @@ 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() << "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";
for (auto Entry : llvm::enumerate(getRuntimeLibraryImportPaths())) {

View File

@@ -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<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
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<std::string> 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();

View File

@@ -108,12 +108,9 @@ std::optional<bool> 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,
for (const auto &path :
Ctx.SearchPathOpts.getImplicitFrameworkSearchPaths()) {
if (auto result = callback(path, ModuleSearchPathKind::ImplicitFramework,
/*isSystem=*/true))
return result;
}
@@ -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");

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