Skip to content

[Unix] Go back to checking the runtime resource path for swiftrt.o if -sysroot unspecified#1822

Open
finagolfin wants to merge 2 commits intoswiftlang:mainfrom
finagolfin:sdk
Open

[Unix] Go back to checking the runtime resource path for swiftrt.o if -sysroot unspecified#1822
finagolfin wants to merge 2 commits intoswiftlang:mainfrom
finagolfin:sdk

Conversation

@finagolfin
Copy link
Member

This is made possible by the swift-frontend now setting this instead in swiftlang/swift#79621. More changes incoming...

@finagolfin
Copy link
Member Author

Ready for review along with the required linked frontend pull, which passed the linux CI when tested with this pull (this pull has no effect on Darwin and Windows). Comments should mostly go there, since this is just a consequence of that pull.

@finagolfin
Copy link
Member Author

@swift-ci please test

@finagolfin
Copy link
Member Author

Alright, this is ready to go, a partial revert of #1667, independent of the linked changes in swiftlang/swift#79621. This pull alone passed CI, along with a full Windows toolchain build. I'd like to get this into 6.1 also next.

Some background: the prior change checked the -sdk alone for swiftrt.o, which sometimes works if the -sdk has one and it isn't too different, but usually doesn't. Under the planned new cross-compilation model, all Swift runtime resources like libswiftCore.so will be looked for in -sdk/usr/lib/swift/<os>, but this reverted code only looks for the single file swiftrt.o, which means the runtime libraries are not looked for in the same -sdk directory! This mixing of Swift runtime resources from two different resource directories in the new model may sometimes work, but will often break.

As for the original cross-compilation model referenced in that doc, which is still the one commonly used, this change I'm reverting often breaks builds because -sdk refers to a C/C++ sysroot alone, like the Android NDK, which usually contains no Swift resources. Since the prior change is broken in both cross-compilation models, I'm reverting it and proposing swiftlang/swift#79621 instead to implement it properly for both the original and new model.

@artemcm, please review.

@compnerd, let us know what you think.

@finagolfin
Copy link
Member Author

Ping @artemcm, mind approving this? I'd like to get it into 6.1 next and I don't think Saleem will respond.

Ever since I argued against this change in the linked pull last year, I have occasionally raised the problems that this caused, eg swiftlang/swift#76381, and got no response. I think they were probably experimenting with new SDK layouts at the time, tried this hack, then moved on to other things.

Let's fix this now, otherwise it is going to start breaking 6.1 SDK bundles and toolchain builds on Unix, ie the two main scenarios where an -sdk is now explicitly specified.

@finagolfin
Copy link
Member Author

@etcwilde, mind reviewing this? I suspect I'm not going to get a response from those above, since they approved the original pull that broke this, and I'd like to get this fixed before it finally ships in 6.1.

Copy link
Member

@etcwilde etcwilde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swiftrt.o is associated with the SDK content though so that the sections are set up correctly for the implementation of swift_addNewDSOImage coming from the stdlib.

During the hybrid phase, this means that we should be grabbing swiftrt from the same place that we found libswiftCore (either via the sdk or resource-dir), though for expedience I'm fine with not hooking that exact logic up today.

As a compromise, can we continue to search the SDK first, and if it's not found there, fall back on the resource-dir?

@finagolfin
Copy link
Member Author

"SDK" can mean different things under the different cross-compilation models, so I try to be more specific.

Most compilation does not set the -sdk flag explicitly, so this code is ignored. We primarily set it explicitly in two scenarios:

  1. cross-compilation
  2. Building the Swift compiler and stdlib itself from source

The problem with this previous Unix change for most cross-compilation SDK bundles is that they use the old model of -sdk having a C/C++ sysroot alone and a separate -resource-dir containing Swift modules/libraries. Despite the bundle pitch doc saying otherwise, both flags are required, because of a separate bug in this swift-driver. This code I'm changing then fails as the -sdk contains only C/C++ files and no swiftrt.o, see swiftlang/swift#76381 for a concrete example.

As for searching both, the problem is it might find a swiftrt.o in -sdk and still fail because it's the wrong version. I'm trying to fix all this more comprehensively for Swift 6.2 in swiftlang/swift#79621, but I'd like to revert this broken swift-driver code first for 6.1, as we probably won't want to rush swiftlang/swift#79621 into 6.1.

@finagolfin
Copy link
Member Author

Ping @etcwilde or @artemcm, I think this should be merged before the 6.1 release, as SDK bundles and building the Swift toolchain itself with Swift 6.1 is going to start breaking on non-Darwin Unix otherwise, as shown in swiftlang/swift#76381. I get these runtime resources from an external -sdk properly in the frontend pull swiftlang/swift#79621 instead, and intend to implement this more completely that way instead.

@finagolfin
Copy link
Member Author

finagolfin commented Mar 28, 2025

@shahmishal, could you take a look at this, as it's been a couple weeks and I haven't really been able to get a review here? I tried building the 6.1 compiler with a prebuilt 6.1 on linux to see if the change this is reverting broke anything and it didn't, as the compiler build is careful to use clang for linking Swift executables instead of swift-driver, but the moment that changes, this previous change that I'm reverting will break the compiler build. It has already broken cross-compiling with SDKs on my Android CI with the -sdk/-resource-dir flags.

I'm asking you since you're the review manager for linux and I'd like to get this into 6.1 next.

@etcwilde
Copy link
Member

@al45tair, I know that this will affect the static linux SDK, do you have feedback?
@compnerd, do you have feedback here? Does this break your SDKs?

As for searching both, the problem is it might find a swiftrt.o in -sdk and still fail because it's the wrong version.

This is true. But we are also moving away from the model where the SDK content is shoved in the compiler resource directory.

@compnerd, you were driving the push to split the system C sysroot flag from the SDK flag. What is missing in
swiftlang/swift#76381? At least at first glance, the compiler invocation is only using the -sdk flag and not the -sysroot flag. I would expect the situation where you're using the C runtimes from the system and a custom runtime to look something like this swiftc -sdk <path to Swift runtimes> -sysroot /.

@finagolfin
Copy link
Member Author

finagolfin commented Mar 28, 2025

But we are also moving away from the model where the SDK content is shoved in the compiler resource directory.

Essentially nothing has been done to make that move, other than this change looking for a single file alone, which means currently under your new model, the 6.1 compiler always looks in two different directories for Swift runtime resources like swiftrt.o or Swift.swiftmodule when a -sdk is specified, which is a recipe for compilation failures when they don't match versions.

At least at first glance, the compiler invocation is only using the -sdk flag and not the -sysroot flag. I would expect the situation where you're using the C runtimes from the system and a custom runtime to look something like this swiftc -sdk -sysroot /.

Yes, the invocation in swiftlang/swift#76381 is using the current -sdk/-resource-dir model, because the planned new -sdk/-sysroot model doesn't work yet. Particularly, a glaring hole in the new model with the current compiler implementation is that the frontend will not look in -sdk or -sysroot for the Swift stdlib modules! I detailed that for you here a couple weeks ago.

@finagolfin
Copy link
Member Author

Sigh, with all the delays in reviewing this, 6.1 has now shipped with this regression, so we'll have to fix it in a patch release.

@finagolfin
Copy link
Member Author

@swift-ci test

@finagolfin
Copy link
Member Author

@swift-ci test windows

@finagolfin
Copy link
Member Author

Forced another Windows CI run because the prior one was not registering with github, which means it would have been useless for the merge.

@finagolfin
Copy link
Member Author

@etcwilde and @compnerd, this previous change I'm reverting broke compiling Unix SDK bundles using external platform C/C++ SDKs with the -sdk flag, because such platform C/C++ SDKs do not contain a swiftrt.o. Of course, SDK bundle support for using external C/C++ SDKs is half-baked- see swiftlang/swift-package-manager#8584 and the second blocker from this comment by @marcprux- but Marc is in the process of fixing those, and this is the only other major issue he found.

Can we go ahead and get this in now?

@marcprux
Copy link
Contributor

This is the final blocker for being able to have the Swift Android SDK use a completely external NDK sysroot without any gruesome hacks.

Is there hope for getting this PR in? Or, at least, are there any objections or concerns that we can assuage? There were no responses from @al45tair or @compnerd to @etcwilde's inquiry about whether this might affect the existing SDKs — perhaps they could take another look and offer their thoughts?

@finagolfin
Copy link
Member Author

@swift-ci test

@finagolfin
Copy link
Member Author

This issue is breaking tests on the community Android CI:

/home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/bin/swiftc -target aarch64-unknown-linux-android -sdk /home/swiftci/android/ndk/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Xclang-linker --target=aarch64-unknown-linux-android21 -tools-directory /home/swiftci/android/ndk/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin -resource-dir /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/lib/swift -module-cache-path /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/swift-test-results/aarch64-unknown-linux-android/clang-module-cache -swift-version 4 -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 9999:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 9999:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.0:macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.0:macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.1:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.1:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.2:macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.2:macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.3:macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.3:macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.4:macOS 11.3, iOS 14.5, watchOS 7.4, tvOS 14.5' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.4:macOS 11.3, iOS 14.5, watchOS 7.4, tvOS 14.5' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.5:macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.5:macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.6:macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.6:macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.7:macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.7:macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.8:macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.8:macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.9:macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.9:macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.10:macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.1' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 5.10:macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.1' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 6.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 6.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 6.1:macOS 15.4, iOS 18.4, watchOS 11.4, tvOS 18.4, visionOS 2.4' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 6.1:macOS 15.4, iOS 18.4, watchOS 11.4, tvOS 18.4, visionOS 2.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 6.2:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 6.2:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 6.3:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999' -Xfrontend -define-availability -Xfrontend 'StdlibDeploymentTarget 6.3:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999' -Xfrontend -define-availability -Xfrontend 'SwiftCompatibilitySpan 5.0:macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2, visionOS 1.1' -Xfrontend -define-availability -Xfrontend 'SwiftCompatibilitySpan 6.2:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0' /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/test-android-aarch64/Interop/Cxx/function/Output/default-arguments-multifile.swift.tmp/main.swift /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/test-android-aarch64/Interop/Cxx/function/Output/default-arguments-multifile.swift.tmp/b.swift /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/test-android-aarch64/Interop/Cxx/function/Output/default-arguments-multifile.swift.tmp/c.swift -cxx-interoperability-mode=upcoming-swift -I /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/swift/test/Interop/Cxx/function/Inputs -o /home/swiftci/jenkins/workspace/oss-swift-RA-linux-ubuntu-24.04-android-arm64/buildbot_linux/swift-linux-x86_64/test-android-aarch64/Interop/Cxx/function/Output/default-arguments-multifile.swift.tmp/artifacts/out
error: link command failed with exit code 1 (use -v to see invocation)
clang++: error: no such file or directory: '/home/swiftci/android/ndk/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/swift/android/aarch64/swiftrt.o

@compnerd, if you think you need this change being reverted for the Android SDKs in your Windows toolchain, can you apply this patch and let us know what error you're seeing?

@etcwilde, there is a bug in this new swift-driver, where it does not detect Swift runtime libraries and this swiftrt.o object file in a -sdk path. The way most remedy this long-standing bug is to explicitly specify the -resource-dir as sdkPath/usr/lib/swift/, but it appears Saleem does not want to do that, whether because he wants to stop using that flag or they have some other new organizational layout in their TBC SDKs.

But by hacking this in explicitly here, he has broken the build of those who do specify both -sdk/-resource-dir flags when cross-compiling to Unix platforms, particularly when done for external C/C++ SDKs that contain no Swift files, eg the Android NDK.

It may be possible to reconcile all this with additional info, as I just asked from Saleem, but we've gotten silence on the matter since it was merged last summer in #1667, despite my repeatedly raising the issue since then.

If someone needs that change, they should be able to explain why. If they cannot or just aren't using these Android SDKs anymore, we should merge this and go back to the way things were.

Pinging @shahmishal too, as this is breaking the upcoming Android SDK bundle with an external NDK, and this pull has received no real review for the last four months.

@finagolfin
Copy link
Member Author

Ping @compnerd, this should resolve this regression for now, just need your review.

@swift-ci test

@finagolfin
Copy link
Member Author

@nkcsgexi, could you take a look at this simple pull? It does essentially the same as the workaround suggested by Artem and others here, but I haven't been able to get them to review it.

@finagolfin
Copy link
Member Author

@jakepetroules, no response from potential reviewers on this simple pull for the last month, since I switched it up to follow the approach you and others put forth for Marc's similar pull earlier. Would you take a look?

@finagolfin
Copy link
Member Author

@owenv, haven't been able to get review from the others who proposed a similar approach months ago, could you take a look at this pull?

@finagolfin
Copy link
Member Author

@compnerd, new year, been a couple months since I put together this new workaround: let us know if you can review this small pull. If not, please nominate someone else to take a look.

@swift-ci test

@compnerd
Copy link
Member

compnerd commented Jan 8, 2026

Our CI is currently experiencing some trouble due to changes in main. Once that is restored, I think that we should be able to try a run with this. I still don't think that this is the right approach - we should be splitting out the resource dir and the SDK content and this is going backwards.

@finagolfin
Copy link
Member Author

I still don't think that this is the right approach - we should be splitting out the resource dir and the SDK content and this is going backwards.

So far, zero work has been done on splitting out compiler-specific resource directory content and those modules/libraries that belong in a target-specific SDK, so that the Swift compiler expects them in different places: that is a separate concern.

This pull merely addresses the work you did to add the C -sysroot flag, which breaks the currently more commonly used -resource-dir flag when cross-compiling to Unix platforms. This workaround allows both to keep working, based on whether -sysroot or -resource-dir was passed in, since the two approaches are mutually exclusive.

@Steelskin
Copy link

I started a build with this PR on the BCNY CI.

@Steelskin
Copy link

I started a build with this PR on the BCNY CI.

With these changes, the build failed to build the Android SDK with the following:

error: link command failed with exit code 1 (use -v to see invocation)
clang: error: no such file or directory: 'D:r_workswift-buildswift-buildBinaryCacheLibraryDeveloperPlatformsAndroid.platformDeveloperSDKsAndroid.sdkusrlibswiftandroidaarch64swiftrt.o'

clang: error: no such file or directory: 'swiftFoundationEssentials.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dir_ThreadLocal.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirBundle+Stub.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirCodable.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirCodableUtilities.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirCodableWithConfiguration.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirComparisonResult.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirDate.swift.o'
clang: error: no such file or directory: '_depsswiftfoundation-buildSourcesFoundationEssentialsCMakeFilesFoundationEssentials.dirDateInterval.swift.o'
[...]

It goes on for quite a bit. I am not certain whether the lack of path separators are an artifact of the display output or the source of the issue.

@finagolfin
Copy link
Member Author

Huh, that's very strange: is there a full build log we can look at? This pull passed all official CI last week and changes nothing for your -sysroot approach, so the failure you pasted seems completely unrelated.

@Steelskin
Copy link

I do not think you can access our logs, but here is the build. The relevant failing job has this CMake invocation:

cmake `
  -B  D:\r\_work\swift-build\swift-build/BinaryCache/foundation `
  -S  D:\r\_work\swift-build\swift-build/SourceCache/swift-corelibs-foundation `
  -G  Ninja `
  -D  _SwiftCollections_SourceDIR=D:/r/_work/swift-build/swift-build/SourceCache/swift-collections `
  -D  _SwiftFoundation_SourceDIR=D:/r/_work/swift-build/swift-build/SourceCache/swift-foundation `
  -D  _SwiftFoundationICU_SourceDIR=D:/r/_work/swift-build/swift-build/SourceCache/swift-foundation-icu `
  -D  BUILD_SHARED_LIBS=YES `
  -D  CMAKE_ANDROID_API=28 `
  -D  CMAKE_ANDROID_ARCH_ABI=arm64-v8a `
  -D  CMAKE_ANDROID_NDK=C:/Users/runner/.setup-ndk/r27c `
  -D  CMAKE_BUILD_TYPE=Release `
  -D  CMAKE_C_COMPILER_TARGET=aarch64-unknown-linux-android28 `
  -D  'CMAKE_C_FLAGS=--sysroot=C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -ffunction-sections -fdata-sections -g -gsplit-dwarf' `
  -D  CMAKE_CXX_COMPILER_TARGET=aarch64-unknown-linux-android28 `
  -D  'CMAKE_CXX_FLAGS=--sysroot=C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -ffunction-sections -fdata-sections -g -gsplit-dwarf' `
  -D  CMAKE_EXE_LINKER_FLAGS=--ld-path=D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Toolchains/0.0.0+Asserts/usr/bin/ld.lld `
  -D  CMAKE_EXECUTABLE_FORMAT=ELF `
  -D  CMAKE_FIND_PACKAGE_PREFER_CONFIG=YES `
  -D  CMAKE_INSTALL_PREFIX=D:/r/_work/swift-build/swift-build/BuildRoot/Library/Developer/Platforms/Android.platform/Developer/SDKs/Android.sdk/usr `
  -D  CMAKE_SHARED_LINKER_FLAGS=--ld-path=D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Toolchains/0.0.0+Asserts/usr/bin/ld.lld `
  -D  CMAKE_STATIC_LIBRARY_PREFIX_Swift=lib `
  -D  CMAKE_Swift_COMPILER=D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Toolchains/0.0.0+Asserts/usr/bin/swiftc.exe `
  -D  CMAKE_Swift_COMPILER_TARGET=aarch64-unknown-linux-android28 `
  -D  CMAKE_Swift_COMPILER_WORKS=YES `
  -D  'CMAKE_Swift_FLAGS=-sdk D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Platforms/Android.platform/Developer/SDKs/Android.sdk -sysroot C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Xclang-linker -target -Xclang-linker aarch64-unknown-linux-android28 -Xclang-linker --sysroot -Xclang-linker C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Xclang-linker -resource-dir -Xclang-linker C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/lib/clang/18 -g' `
  -D  CMAKE_Swift_FLAGS_RELEASE=-O `
  -D  CMAKE_Swift_FLAGS_RELWITHDEBINFO=-O `
  -D  CMAKE_SYSTEM_NAME=Android `
  -D  CMAKE_SYSTEM_PROCESSOR=aarch64 `
  -D  CURL_DIR=D:/r/_work/swift-build/swift-build/BuildRoot/Library/curl-8.9.1/usr/lib/cmake/CURL `
  -D  dispatch_DIR=D:/r/_work/swift-build/swift-build/BinaryCache/libdispatch/cmake/modules `
  -D  FOUNDATION_BUILD_TOOLS=NO `
  -D  LibXml2_DIR=D:/r/_work/swift-build/swift-build/BuildRoot/Library/libxml2-2.11.5/usr/lib/cmake/libxml2-2.11.5 `
  -D  SWIFT_ANDROID_NDK_PATH=C:/Users/runner/.setup-ndk/r27c `
  -D  SwiftFoundation_MACRO=D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Toolchains/0.0.0+Asserts/usr/bin `
  -D  ZLIB_INCLUDE_DIR=D:/r/_work/swift-build/swift-build/BuildRoot/Library/zlib-1.3/usr/include `
  -D  ZLIB_LIBRARY=D:/r/_work/swift-build/swift-build/BuildRoot/Library/zlib-1.3/usr/lib/libz.a

And here is the swiftc invocation that eventually fails:

C:\Windows\system32\cmd.exe /C "cd . && D:\r\_work\swift-build\swift-build\BinaryCache\Library\Developer\Toolchains\0.0.0+Asserts\usr\bin\swiftc.exe -target aarch64-unknown-linux-android28 -j 16 -num-threads 16 -emit-library -o lib\libFoundationEssentials.so -module-name FoundationEssentials -module-link-name FoundationEssentials -emit-module -emit-module-path swift\FoundationEssentials.swiftmodule -emit-dependencies -DFoundationEssentials_EXPORTS -sdk D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Platforms/Android.platform/Developer/SDKs/Android.sdk -sysroot C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Xclang-linker -target -Xclang-linker aarch64-unknown-linux-android28 -Xclang-linker --sysroot -Xclang-linker C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Xclang-linker -resource-dir -Xclang-linker C:/Users/runner/.setup-ndk/r27c/toolchains/llvm/prebuilt/windows-x86_64/lib/clang/18 -g -O -plugin-path D:/r/_work/swift-build/swift-build/BinaryCache/Library/Developer/Toolchains/0.0.0+Asserts/usr/bin -Xfrontend -Xcc -Xfrontend -D_GNU_SOURCE -Xfrontend -enable-experimental-feature -Xfrontend VariadicGenerics -Xfrontend -enable-experimental-feature -Xfrontend LifetimeDependence -Xfrontend -enable-experimental-feature -Xfrontend AddressableTypes -Xfrontend -enable-experimental-feature -Xfrontend BuiltinModule -Xfrontend -enable-experimental-feature -Xfrontend AccessLevelOnImport -Xfrontend -enable-experimental-feature -Xfrontend StrictConcurrency -Xfrontend -enable-upcoming-feature -Xfrontend InferSendableFromCaptures -Xfrontend -enable-upcoming-feature -Xfrontend MemberImportVisibility -Xfrontend -enable-experimental-feature -Xfrontend "AvailabilityMacro=FoundationPreview 6.0.2:macOS 15, iOS 18, tvOS 18, watchOS 11" -Xfrontend -enable-experimental-feature -Xfrontend "AvailabilityMacro=FoundationPreview 6.1:macOS 15, iOS 18, tvOS 18, watchOS 11" -Xfrontend -enable-experimental-feature -Xfrontend "AvailabilityMacro=FoundationPreview 6.2:macOS 15, iOS 18, tvOS 18, watchOS 11" -Xfrontend -enable-experimental-feature -Xfrontend "AvailabilityMacro=FoundationPreview 6.3:macOS 15, iOS 18, tvOS 18, watchOS 11" -Xfrontend -enable-experimental-feature -Xfrontend "AvailabilityMacro=FoundationPreview 6.4:macOS 15, iOS 18, tvOS 18, watchOS 11" -package-name SwiftFoundation -Xcc -fmodule-map-file=D:/r/_work/swift-build/swift-build/SourceCache/swift-foundation/Sources/_FoundationCShims/include/module.modulemap -output-file-map _deps\swiftfoundation-build\Sources\FoundationEssentials\CMakeFiles\FoundationEssentials.dir\Release\output-file-map.json -I D:/r/_work/swift-build/swift-build/BinaryCache/foundation/swift -I D:/r/_work/swift-build/swift-build/SourceCache/swift-foundation/Sources/_FoundationCShims/include @CMakeFiles\FoundationEssentials.rsp  -Xlinker -soname -Xlinker libFoundationEssentials.so  && cd ."

@finagolfin
Copy link
Member Author

Huh, that build log appears to download a prebuilt Swift compiler from somewhere else, whereas you will have to apply this swift-driver pull to a fresh build of the Swift compiler itself, then use that freshly-built, modified toolchain to either cross-compile an Android SDK or cross-compile a package for Android, in order to test this pull.

In any case, it looks like you're having a CMake path separator issue with Foundation object files, which this pull cannot cause, so even if this pull was applied properly, probably something else went wrong with that test run, eg some upstream issue.

@Steelskin
Copy link

Huh, that build log appears to download a prebuilt Swift compiler from somewhere else, whereas you will have to apply this swift-driver pull to a fresh build of the Swift compiler itself, then use that freshly-built, modified toolchain to either cross-compile an Android SDK or cross-compile a package for Android, in order to test this pull.

Our build runs across multiple jobs, each of them builds a part of the toolchain/SDK. In this case, the compiler comes out of the compilers job, which includes the early swift-driver, built with these changes applied.

In any case, it looks like you're having a CMake path separator issue with Foundation object files, which this pull cannot cause, so even if this pull was applied properly, probably something else went wrong with that test run, eg some upstream issue.

The only difference between the build I linked and the build on main (which is green) in thebrowsercompany/swift-build is that this patch was applied in the swift-driver repository. This includes the early swift-driver build, which is in use when Foundation is being built. I wonder if the changes in this PR could be causing something in swift-driver to believe it is handling Unix paths rather than Windows paths, resulting in the \ separators being improperly escaped.

@finagolfin
Copy link
Member Author

In this case, the compiler comes out of the compilers job, which includes the early swift-driver, built with these changes applied.

Does it also build the swift-driver later? I ask because the mac/unix build-script builds swift-driver twice, once as early-swift-driver with the prebuilt host Swift toolchain, then again with the fresh trunk toolchain, only installing and shipping the latter. I'm unsure if Windows does all that.

I wonder if the changes in this PR could be causing something in swift-driver to believe it is handling Unix paths rather than Windows paths, resulting in the \ separators being improperly escaped.

This change only affects the path to a single stdlib object file and it tries to keep everything the same when -sysroot is passed in as you showed, ie nothing changes. Even if the swift-driver check I added here isn't working, there is basically no way path separators for arbitrary object files would be affected.

I think you should run this through your CI again, and make sure any other outside patches aren't being inadvertently applied also.

@Steelskin
Copy link

@finagolfin I rebased your branch in my fork and started a new build based on that. I'll let you know how it goes. There are no other changes to the repository, other than the swift-driver revision used to build the early and final swift-driver.

@Steelskin
Copy link

@finagolfin I rebased your branch in my fork and started a new build based on that. I'll let you know how it goes. There are no other changes to the repository, other than the swift-driver revision used to build the early and final swift-driver.

@finagolfin This passed after I did that. I believe your branch is too far behind, so it was probably missing a few fixes from the main branch.

@finagolfin
Copy link
Member Author

Alright, this passed all CI again once rebased, just as it did in November, before winter break.

@compnerd, this small measure fixes the semantic break from how the -sdk flag is used with the new -sysroot flag versus the -resource-dir flag, since each approach looks for swiftrt.o in different places.

Whatever plans you and Evan may have that "we should be splitting out the resource dir and the SDK content," that work has not been done and the -sysroot approach also still has compiler-specific resource directory content in the -sdk.

More importantly, the SDK bundle JSON format has no support for passing in a -sysroot flag, only a -resource-dir flag, so that is the only approach used by the current official SDK bundles like the Android SDK and the static linux SDK. The only reason that we were able to get that to work with the Android SDK is by putting in a handful of workarounds for this issue, where this incorrect swiftrt.o path meant for the -sysroot approach is being jammed into the -resource-dir approach.

Let's get this in and fix this for the upcoming 6.3 release, and you can keep working on the new -sysroot approach and the splitting work you want, then once that is ready, we can switch over. There is no reason to break the currently popular -resource-dir approach with these new -sysroot-based changes.

@finagolfin
Copy link
Member Author

@shahmishal, not getting a meaningful response here: can you ask Xi Ge or Doug or somebody who knows these cross-compilation matters well to judge the best path forward? Otherwise, this cross-compilation has been broken for all Unix platforms, including linux, since Swift 6.1 last year, which I'd like to get fixed before the upcoming 6.3 release.

We have been working around this long-standing bug by @marcprux sticking a bunch of symlinks in to the Android SDK bundle, among other measures, but the workaround in this swift-driver pull is a better way to separate the currently popular -sdk/-resource-dir approach from the new but incomplete -sdk/-sysroot approach that Saleem and Evan are pushing.

@finagolfin
Copy link
Member Author

Simply rebased this one-line pull

@swift-ci test

@finagolfin finagolfin changed the title [Unix] Go back to only checking the runtime resource path for swiftrt.o [Unix] Go back to checking the runtime resource path for swiftrt.o if -sysroot unspecified Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants