From 45714f11411b5097f8ed5b537969402216809e93 Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Wed, 26 Feb 2025 04:33:08 +0530 Subject: [PATCH 1/4] Have the frontend and new swift-driver look in an external `-sdk` for non-Darwin platform runtime libraries and modules too as done originally in #25990 with the legacy C++ Driver, but since lost in the new swift-driver --- lib/ClangImporter/ClangImporter.cpp | 12 ------------ lib/Frontend/CompilerInvocation.cpp | 10 +++++++++- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index fa3e771bf9adc..c1132518dc176 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -761,23 +761,11 @@ void importer::getNormalInvocationArguments( invocationArgStrs.push_back("-fapinotes-swift-version=" + languageVersion.asAPINotesVersionString()); - // Prefer `-sdk` paths. - if (!searchPathOpts.getSDKPath().empty()) { - llvm::SmallString<261> path{searchPathOpts.getSDKPath()}; - llvm::sys::path::append(path, "usr", "lib", "swift", "apinotes"); - - invocationArgStrs.push_back("-iapinotes-modules"); - invocationArgStrs.push_back(path.str().str()); - } - - // Fallback to "legacy" `-resource-dir` paths. - { llvm::SmallString<261> path{searchPathOpts.RuntimeResourcePath}; llvm::sys::path::append(path, "apinotes"); invocationArgStrs.push_back("-iapinotes-modules"); invocationArgStrs.push_back(path.str().str()); - } } static void diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 01222304fc5e0..6c92cfe84a9a8 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2281,6 +2281,7 @@ static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModule static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, + const llvm::Triple &Triple, const CASOptions &CASOpts, const FrontendOptions &FrontendOpts, StringRef workingDirectory) { @@ -2415,6 +2416,13 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_resource_dir)) Opts.RuntimeResourcePath = A->getValue(); + else if (Args.hasArg(OPT_sdk)) { + llvm::SmallString<128> SDKResourcePath(Opts.getSDKPath()); + llvm::sys::path::append( + SDKResourcePath, "usr", "lib", + FrontendOpts.UseSharedResourceFolder ? "swift" : "swift_static"); + Opts.RuntimeResourcePath = SDKResourcePath.str(); + } Opts.SkipAllImplicitImportPaths |= Args.hasArg(OPT_nostdimport); Opts.SkipSDKImportPaths |= Args.hasArg(OPT_nostdlibimport); @@ -4060,7 +4068,7 @@ bool CompilerInvocation::parseArgs( ParseSymbolGraphArgs(SymbolGraphOpts, ParsedArgs, Diags, LangOpts); - if (ParseSearchPathArgs(SearchPathOpts, ParsedArgs, Diags, + if (ParseSearchPathArgs(SearchPathOpts, ParsedArgs, Diags, LangOpts.Target, CASOpts, FrontendOpts, workingDirectory)) { return true; } From cdfeadf259be1e2dcfe882d6eb82bdc42b376c30 Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Mon, 2 Jun 2025 16:45:09 +0530 Subject: [PATCH 2/4] Fix tests on linux CI --- .../apinotes => ClangImporter/Inputs}/cfuncs.apinotes | 0 test/ClangImporter/sdk-apinotes.swift | 8 +++++++- .../swift_build_sdk_interfaces/check-only-mode.swift | 2 ++ test/Serialization/module_defining_interface.swift | 5 +++-- .../module_defining_interface_client.swift | 5 +++-- test/Serialization/runtime-import-from-sdk.swift | 10 ++++------ 6 files changed, 19 insertions(+), 11 deletions(-) rename test/{Inputs/clang-importer-sdk/usr/lib/swift/apinotes => ClangImporter/Inputs}/cfuncs.apinotes (100%) diff --git a/test/Inputs/clang-importer-sdk/usr/lib/swift/apinotes/cfuncs.apinotes b/test/ClangImporter/Inputs/cfuncs.apinotes similarity index 100% rename from test/Inputs/clang-importer-sdk/usr/lib/swift/apinotes/cfuncs.apinotes rename to test/ClangImporter/Inputs/cfuncs.apinotes diff --git a/test/ClangImporter/sdk-apinotes.swift b/test/ClangImporter/sdk-apinotes.swift index 8e53a0564569b..5c47d7781946c 100644 --- a/test/ClangImporter/sdk-apinotes.swift +++ b/test/ClangImporter/sdk-apinotes.swift @@ -1,4 +1,10 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify +// RUN: %empty-directory(%t/sdk/usr/lib/swift/apinotes) +// RUN: %empty-directory(%t/sdk/usr/lib/swift/%target-sdk-name) +// RUN: cp -r %clang-importer-sdk-path/usr/include %t/sdk/usr +// RUN: cp -r %test-resource-dir/shims %t/sdk/usr/lib/swift +// RUN: cp %S/Inputs/cfuncs.apinotes %t/sdk/usr/lib/swift/apinotes +// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/sdk/usr/lib/swift/%target-sdk-name/ +// RUN: %target-swift-frontend(mock-sdk: -sdk %t/sdk) -typecheck %s -verify -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import import cfuncs diff --git a/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift b/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift index 3e499cae7a30e..6dc92a8c7b073 100644 --- a/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift +++ b/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift @@ -6,6 +6,8 @@ // RUN: echo 'public func flat() {}' | %target-swift-frontend - -emit-module-interface-path %t/sdk/usr/lib/swift/Flat.swiftinterface -emit-module -o /dev/null -module-name Flat // RUN: echo 'public func fmwk() {}' | %target-swift-frontend - -emit-module-interface-path %t/sdk/System/Library/Frameworks/FMWK.framework/Modules/FMWK.swiftmodule/%target-swiftinterface-name -emit-module -o /dev/null -module-name FMWK +// RUN: cp -r %test-resource-dir/shims %t/sdk/usr/lib/swift +// RUN: ln -s %platform-module-dir %t/sdk/usr/lib/swift // RUN: %swift_build_sdk_interfaces -sdk %t/sdk -Fsystem %t/sdk/System/Library/Frameworks -v -o %t/prebuilt -check-only // RUN: ls %t/prebuilt | %FileCheck %s // CHECK-DAG: Normal.swiftmodule diff --git a/test/Serialization/module_defining_interface.swift b/test/Serialization/module_defining_interface.swift index fee71bb39c61f..69aaa009857fd 100644 --- a/test/Serialization/module_defining_interface.swift +++ b/test/Serialization/module_defining_interface.swift @@ -1,8 +1,9 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/inputs) // RUN: %empty-directory(%t/test-sdk) -// RUN: %empty-directory(%t/test-sdk/usr/lib/swift) -// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/test-sdk/usr/lib/swift/Swift.swiftmodule +// RUN: %empty-directory(%t/test-sdk/usr/lib/swift/%target-sdk-name) +// RUN: cp -r %test-resource-dir/shims %t/test-sdk/usr/lib/swift +// RUN: cp -r %platform-module-dir/Swift{,OnoneSupport}.swiftmodule %t/test-sdk/usr/lib/swift/%target-sdk-name/ // RUN: %empty-directory(%t/test-sdk/usr/lib/Foo.swiftmodule) // RUN: split-file %s %t diff --git a/test/Serialization/module_defining_interface_client.swift b/test/Serialization/module_defining_interface_client.swift index 6f075677be096..aa5abda30b377 100644 --- a/test/Serialization/module_defining_interface_client.swift +++ b/test/Serialization/module_defining_interface_client.swift @@ -1,12 +1,13 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/inputs) // RUN: %empty-directory(%t/test-sdk) -// RUN: %empty-directory(%t/test-sdk/usr/lib/swift) +// RUN: %empty-directory(%t/test-sdk/usr/lib/swift/%target-sdk-name) // RUN: %empty-directory(%t/test-sdk/usr/lib/Foo.swiftmodule) // RUN: %empty-directory(%t/test-sdk/usr/lib/Bar.swiftmodule) // RUN: %empty-directory(%t/test-sdk/usr/lib/_Foo_Bar.swiftmodule) // RUN: %empty-directory(%t/test-sdk/usr/lib/Foo.swiftcrossimport) -// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/test-sdk/usr/lib/swift/Swift.swiftmodule +// RUN: cp -r %test-resource-dir/shims %t/test-sdk/usr/lib/swift +// RUN: cp -r %platform-module-dir/Swift{,OnoneSupport}.swiftmodule %t/test-sdk/usr/lib/swift/%target-sdk-name/ // RUN: split-file %s %t diff --git a/test/Serialization/runtime-import-from-sdk.swift b/test/Serialization/runtime-import-from-sdk.swift index d57b42501ba1e..ae80402ad052d 100644 --- a/test/Serialization/runtime-import-from-sdk.swift +++ b/test/Serialization/runtime-import-from-sdk.swift @@ -6,13 +6,16 @@ // %t/good-sdk contains a loadable standard library. // RUN: %empty-directory(%t/good-sdk) -// RUN: %empty-directory(%t/good-sdk/usr/lib/swift) +// RUN: %empty-directory(%t/good-sdk/usr/lib/swift/%target-sdk-name) // RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/good-sdk/usr/lib/swift/Swift.swiftmodule +// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/good-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule // %t/bad-sdk contains an invalid standard library that cannot be loaded. // RUN: %empty-directory(%t/bad-sdk) // RUN: %empty-directory(%t/bad-sdk/usr/lib/swift/Swift.swiftmodule) +// RUN: %empty-directory(%t/bad-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule) // RUN: touch %t/bad-sdk/usr/lib/swift/Swift.swiftmodule/garbage-garbage-garbage.swiftmodule +// RUN: touch %t/bad-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule/garbage-garbage-garbage.swiftmodule // %t/empty-toolchain does not contain a standard library. // RUN: %empty-directory(%t/empty-toolchain) @@ -45,11 +48,6 @@ // We also check that ClangImporter noticed SwiftShims in the toolchain and // didn't add a -isystem flag to look in the SDK. -// FIXME: We can't properly test this on a non-Darwin platform because we'll get -// the same error message for "unloadable standard library" and "no standard -// library" (https://github.com/apple/swift/issues/52499). -// REQUIRES: objc_interop - // RUN: %empty-directory(%t/mcp) // RUN: not %target-swift-frontend(mock-sdk: -sdk %t/bad-sdk) -resource-dir %t/empty-toolchain/usr/lib/swift -module-cache-path %t/mcp -typecheck %s -dump-clang-diagnostics -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import 2>&1 | %FileCheck --check-prefix CHECK-EMPTY %s // CHECK-EMPTY-NOT: '-isystem' '{{.*}}/bad-sdk/usr/lib/swift/shims' From 3b489637e6ce72194c4aa7aee2834c6ed1a05b00 Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Mon, 2 Jun 2025 22:35:54 +0530 Subject: [PATCH 3/4] Check if resource directory exists in `-sdk` and fall back to default if not --- include/swift/AST/DiagnosticsFrontend.def | 7 +++++++ lib/Frontend/CompilerInvocation.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 113542b215a9b..250fd5b726e5d 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -24,6 +24,13 @@ WARNING(warning_no_such_sdk,none, "no such SDK: '%0'", (StringRef)) +WARNING(warning_no_resource_dir_in_sdk, none, + " You passed in an external -sdk without a Swift runtime.\n" + " Either specify a directory containing the runtime libraries with\n" + " the -resource-dir flag, or use -sysroot instead to point at a C/C++\n" + " sysroot alone. Falling back to this path for the Swift runtime modules\n" + " and libraries:\n" + " %0", (StringRef)) ERROR(error_no_frontend_args, none, "no arguments provided to '-frontend'", ()) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 6c92cfe84a9a8..c4d662735d6a1 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2421,7 +2421,12 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, llvm::sys::path::append( SDKResourcePath, "usr", "lib", FrontendOpts.UseSharedResourceFolder ? "swift" : "swift_static"); - Opts.RuntimeResourcePath = SDKResourcePath.str(); + // Check for eg /usr/lib/swift/ + if (llvm::sys::fs::exists(SDKResourcePath)) + Opts.RuntimeResourcePath = SDKResourcePath.str(); + else + Diags.diagnose(SourceLoc(), diag::warning_no_resource_dir_in_sdk, + Opts.RuntimeResourcePath); } Opts.SkipAllImplicitImportPaths |= Args.hasArg(OPT_nostdimport); From ef6e9d276646ef79ac4b38e7eef23f982a173cc0 Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Tue, 3 Jun 2025 13:46:58 +0530 Subject: [PATCH 4/4] Only enable `-sdk` changes for non-Darwin and use the right `-sysroot` flag on Windows Also, disable Serialization/runtime-import-from-sdk again and try out a fix for the ModuleInterface/swift_build_sdk_interfaces/check-only-mode errors. --- lib/Frontend/CompilerInvocation.cpp | 16 ++-------------- .../check-only-mode.swift | 5 +++-- test/Serialization/runtime-import-from-sdk.swift | 10 ++++++---- utils/build.ps1 | 2 +- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index c4d662735d6a1..8643c6042b65d 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -270,7 +270,7 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts, RuntimeLibraryImportPaths.push_back(std::string(LibPath.str())); } - if (!SearchPathOpts.SkipSDKImportPaths && !SearchPathOpts.getSDKPath().empty()) { + if (!SearchPathOpts.SkipSDKImportPaths && Triple.isOSDarwin() && !SearchPathOpts.getSDKPath().empty()) { const char *swiftDir = FrontendOpts.UseSharedResourceFolder ? "swift" : "swift_static"; @@ -283,18 +283,6 @@ static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts, LibPath = SearchPathOpts.getSDKPath(); llvm::sys::path::append(LibPath, "usr", "lib", swiftDir); - if (!Triple.isOSDarwin()) { - // Use the non-architecture suffixed form with directory-layout - // swiftmodules. - llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple)); - RuntimeLibraryImportPaths.push_back(std::string(LibPath.str())); - - // Compatibility with older releases - use the architecture suffixed form - // for pre-directory-layout multi-architecture layout. Note that some - // platforms (e.g. Windows) will use this even with directory layout in - // older releases. - llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple)); - } RuntimeLibraryImportPaths.push_back(std::string(LibPath.str())); } SearchPathOpts.setRuntimeLibraryImportPaths(RuntimeLibraryImportPaths); @@ -2416,7 +2404,7 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_resource_dir)) Opts.RuntimeResourcePath = A->getValue(); - else if (Args.hasArg(OPT_sdk)) { + else if (!Triple.isOSDarwin() && Args.hasArg(OPT_sdk)) { llvm::SmallString<128> SDKResourcePath(Opts.getSDKPath()); llvm::sys::path::append( SDKResourcePath, "usr", "lib", diff --git a/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift b/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift index 6dc92a8c7b073..09ccddedaf8a3 100644 --- a/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift +++ b/test/ModuleInterface/swift_build_sdk_interfaces/check-only-mode.swift @@ -1,4 +1,7 @@ // RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/sdk/usr/lib) +// RUN: cp -r %test-resource-dir %t/sdk/usr/lib +// RUN: rm -rf %t/sdk/usr/lib/swift/host // RUN: mkdir -p %t/sdk/usr/lib/swift/Normal.swiftmodule // RUN: mkdir -p %t/sdk/System/Library/Frameworks/FMWK.framework/Modules/FMWK.swiftmodule @@ -6,8 +9,6 @@ // RUN: echo 'public func flat() {}' | %target-swift-frontend - -emit-module-interface-path %t/sdk/usr/lib/swift/Flat.swiftinterface -emit-module -o /dev/null -module-name Flat // RUN: echo 'public func fmwk() {}' | %target-swift-frontend - -emit-module-interface-path %t/sdk/System/Library/Frameworks/FMWK.framework/Modules/FMWK.swiftmodule/%target-swiftinterface-name -emit-module -o /dev/null -module-name FMWK -// RUN: cp -r %test-resource-dir/shims %t/sdk/usr/lib/swift -// RUN: ln -s %platform-module-dir %t/sdk/usr/lib/swift // RUN: %swift_build_sdk_interfaces -sdk %t/sdk -Fsystem %t/sdk/System/Library/Frameworks -v -o %t/prebuilt -check-only // RUN: ls %t/prebuilt | %FileCheck %s // CHECK-DAG: Normal.swiftmodule diff --git a/test/Serialization/runtime-import-from-sdk.swift b/test/Serialization/runtime-import-from-sdk.swift index ae80402ad052d..d57b42501ba1e 100644 --- a/test/Serialization/runtime-import-from-sdk.swift +++ b/test/Serialization/runtime-import-from-sdk.swift @@ -6,16 +6,13 @@ // %t/good-sdk contains a loadable standard library. // RUN: %empty-directory(%t/good-sdk) -// RUN: %empty-directory(%t/good-sdk/usr/lib/swift/%target-sdk-name) +// RUN: %empty-directory(%t/good-sdk/usr/lib/swift) // RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/good-sdk/usr/lib/swift/Swift.swiftmodule -// RUN: cp -r %platform-module-dir/Swift.swiftmodule %t/good-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule // %t/bad-sdk contains an invalid standard library that cannot be loaded. // RUN: %empty-directory(%t/bad-sdk) // RUN: %empty-directory(%t/bad-sdk/usr/lib/swift/Swift.swiftmodule) -// RUN: %empty-directory(%t/bad-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule) // RUN: touch %t/bad-sdk/usr/lib/swift/Swift.swiftmodule/garbage-garbage-garbage.swiftmodule -// RUN: touch %t/bad-sdk/usr/lib/swift/%target-sdk-name/Swift.swiftmodule/garbage-garbage-garbage.swiftmodule // %t/empty-toolchain does not contain a standard library. // RUN: %empty-directory(%t/empty-toolchain) @@ -48,6 +45,11 @@ // We also check that ClangImporter noticed SwiftShims in the toolchain and // didn't add a -isystem flag to look in the SDK. +// FIXME: We can't properly test this on a non-Darwin platform because we'll get +// the same error message for "unloadable standard library" and "no standard +// library" (https://github.com/apple/swift/issues/52499). +// REQUIRES: objc_interop + // RUN: %empty-directory(%t/mcp) // RUN: not %target-swift-frontend(mock-sdk: -sdk %t/bad-sdk) -resource-dir %t/empty-toolchain/usr/lib/swift -module-cache-path %t/mcp -typecheck %s -dump-clang-diagnostics -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import 2>&1 | %FileCheck --check-prefix CHECK-EMPTY %s // CHECK-EMPTY-NOT: '-isystem' '{{.*}}/bad-sdk/usr/lib/swift/shims' diff --git a/utils/build.ps1 b/utils/build.ps1 index 0592a4b362e4b..c4a7caf247d52 100644 --- a/utils/build.ps1 +++ b/utils/build.ps1 @@ -1422,7 +1422,7 @@ function Build-CMakeProject { switch ($Platform.OS) { Windows { if ($SwiftSDK -ne "") { - $SwiftArgs += @("-sdk", $SwiftSDK) + $SwiftArgs += @("-sysroot", $SwiftSDK) } else { $SwiftArgs += @( "-vfsoverlay", "$RuntimeBinaryCache\stdlib\windows-vfs-overlay.yaml",