Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macOS toolchain build and test #162

Merged
merged 1 commit into from
Sep 5, 2024
Merged

Conversation

marcprux
Copy link
Contributor

@marcprux marcprux commented Aug 4, 2024

This PR adds a macos-toolchain-tests job to the CI workflow that builds a simple test executable on a macOS runner and runs it in an Android x86_64 emulator. The macOS job uses the SDK artifacts that are built and uploaded by the earlier build-sdk-and-tests job.

The PR also fixes an issue with the recent NDK 27 update where a sed command in the script was expecting a version of the form "release-2.." (e.g., "release-25c", "release-26a"), which wasn't matching "release-27". Additionally, some debugging affordances are added to the workflow as well as the get-packages-and-swift-source.swift script.

An example workflow result can be seen at https://github.com/marcprux/swift-android-sdk/actions/runs/10231920008

@finagolfin
Copy link
Owner

Thanks, have you tried building random Swift packages, say any of those I build and test on the linux CI, using this macOS setup? I wonder if we can start building and testing full packages on macOS using this toolchain setup.

Also, I have had issues cross-compiling packages that use macros using this Android SDK on linux: have you seen the same on macOS?

Finally, you mention porting the Foundation rewrite to Android on the forum: have you started working on this? Other than some patches for nullability annotations in NDK 26, I have not done much with the rewrite yet.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 4, 2024

Thanks, have you tried building random Swift packages, say any of those I build and test on the linux CI, using this macOS setup? I wonder if we can start building and testing full packages on macOS using this toolchain setup.

I have manually built and tested a few packages, but not the full gamut that you are running in the build-sdk-and-tests job. I'd like to have the macos-toolchain-tests run all the same tests, but I didn't want to copy/paste all that YAML config. I was going to suggest that we might move them out of the workflow into a separate set of shell scripts that could then be run from both the Ubuntu and macOS jobs.

Also, I have had issues cross-compiling packages that use macros using this Android SDK on linux: have you seen the same on macOS?

I haven't experimented with macros yet. I know there have been some hairy issues with macros and cross-compilation in general.

Finally, you mention porting the Foundation rewrite to Android on the forum: have you started working on this? Other than some patches for nullability annotations in NDK 26, I have not done much with the rewrite yet.

I haven't started anything other than thinking about it. Perhaps a first step would be to see if we can get swift-foundation building for Android as part of the CI?

@finagolfin
Copy link
Owner

I have manually built and tested a few packages

Great, good to hear it works.

I'd like to have the macos-toolchain-tests run all the same tests

Do you mind if I just take the macOS toolchain download portion of this pull, commands that I was not familar with because I don't use macOS, and try to build all these packages in macOS runners too, in a separate pull?

I know there have been some hairy issues with macros and cross-compilation in general.

Yep, I wonder if that works with new versions of the destination schema, that are used in the new SDK bundles.

Perhaps a first step would be to see if we can get swift-foundation building for Android as part of the CI?

It would be easier to do so locally, which I plan to try natively on Android in the coming week.

@finagolfin
Copy link
Owner

What I had in mind is to simply add macOS runners to the build matrix, then make sure I can cross-compile all these packages on macOS too. If you would like to change this pull to do that, go for it, but you don't have to either.

@@ -164,7 +166,7 @@ for termuxPackage in termuxPackages {
print("Checking for \(packageName)")
if !fmd.fileExists(atPath: termuxArchive.appendingPathComponent(String(packageName))) {
print("Downloading \(packageName)")
_ = runCommand("curl", with: ["-o", "termux/\(packageName)",
_ = runCommand("curl", with: ["-f", "-o", "termux/\(packageName)",
Copy link
Owner

Choose a reason for hiding this comment

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

What does adding this flag help with?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there is an HTTP error (e.g., 404), then the curl command will fail when the "-f" flag is set. Otherwise it will output a blank file, and the subsequent tar x command will fail will an unhelpful error. I added it because I had previously made a typo in a package name, which was causing the download to fail.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 4, 2024

What I had in mind is to simply add macOS runners to the build matrix, then make sure I can cross-compile all these packages on macOS too. If you would like to change this pull to do that, go for it, but you don't have to either.

Do you mean something like this?

  build-sdk-and-tests:
    runs-on: ${{ matrix.os }}
    needs: get-latest-toolchain
    strategy:
      fail-fast: false
      matrix:
        version: [release-25c, release-27, devel, trunk]
        arch: [aarch64, x86_64, armv7]
        os: [ubuntu-latest, macos-13]

I think that would be ideal, but the macos-toolchain-tests job doesn't build the Android SDK, but instead uses the uploaded output of the build-sdk-and-tests job, and so they can't be run in parallel. The macOS job probably could build the SDK, but there's a fair amount of other platform-specific logic in the macOS job.

I've gone ahead and copied over your package builds from Ubuntu to macOS in this PR. There's now a lot of duplicated logic between the two jobs, but we can tackle ways to de-dupe in the future. Other than changing the build arguments for the different toolchain setups, the only other change is a tweak to the sed commands (since macOS requires an argument to the "-i" flag).

Most packages build fine, with the following exceptions (which I've disabled so the build will pass):

swift-argument-parser

swift-argument-parser/Examples/count-lines/CountLines.swift:62:46: error: value of type 'FileHandle' has no member 'bytes'
        let lineCount = try await fileHandle.bytes.lines.reduce(0) { count, line in
                                  ~~~~~~~~~~ ^~~~~

swift-nio-http2 and swift-nio-ssl

swift-nio/Sources/NIOPosix/System.swift:128:97: error: cannot convert value of type '(Int32, UnsafeMutablePointer<msghdr>, Int32) -> Int' to specified type '@convention(c) (CInt, UnsafeMutablePointer<msghdr>?, CInt) -> ssize_t' (aka '@convention(c) (Int32, Optional<UnsafeMutablePointer<msghdr>>, Int32) -> Int')
private let sysRecvMsg: @convention(c) (CInt, UnsafeMutablePointer<msghdr>?, CInt) -> ssize_t = recvmsg
                                                                                                ^

Let me know if this looks OK to you, or if you'd like to see some cleanup before merging. And feel free to make any changes, either in this PR or in a new one. I'm here to help with any follow-up work (especially figuring our ways to de-duplicate the build logic).

@finagolfin
Copy link
Owner

Do you mean something like this?

Yep, exactly.

the macos-toolchain-tests job doesn't build the Android SDK, but instead uses the uploaded output of the build-sdk-and-tests job, and so they can't be run in parallel.

Since we are currently not updating the SDK snapshot tags or versions, cross-compiling packages should work fine in parallel, as I think you can use the previously cached copy of the SDK on macOS. Once that is working, I'd look into cross-compiling the SDK for Android in the macOS runner too.

Feel free to work on any part of that you'd like, or none of it, up to you. I will come back to this in a couple days and either merge your work, or use it as a basis for attempting the above.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 5, 2024

Since we are currently not updating the SDK snapshot tags or versions, cross-compiling packages should work fine in parallel, as I think you can use the previously cached copy of the SDK on macOS. Once that is working, I'd look into cross-compiling the SDK for Android in the macOS runner too.

Good idea to re-use the cached copy!

Feel free to work on any part of that you'd like, or none of it, up to you. I will come back to this in a couple days and either merge your work, or use it as a basis for attempting the above.

I've merged all the logic into a single job that runs on both macOS and Ubuntu, using the cached SDK from the Ubuntu build, which gets around the build-script error on macOS (which is something I have gotten around before in my local builds, I just don't remember exactly how).

Hopefully it is good enough to merge, but I'm happy to do any further cleanup or refactoring that you think might be needed.

@@ -3,6 +3,9 @@ on:
pull_request:
schedule:
- cron: '0 9 * * *'
push:
branches: '*'
Copy link
Owner

Choose a reason for hiding this comment

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

I prefer to have the CI run once daily instead, please remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mind if I add workflow_dispatch? That way we can manually trigger the action to run.

Copy link
Owner

Choose a reason for hiding this comment

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

What is the use case for that? I submit a pull if I want to make a change, and all direct pushes are tested by the daily CI run.

When would you want to randomly trigger a CI run with no changes to this repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking for cases where there is a new devel or trunk release and we want to immediately test it (once the toolchain check goes back to tracking the latest changes).

Copy link
Owner

Choose a reason for hiding this comment

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

I just wait for the next daily CI run, but you can add it if you like.

@finagolfin
Copy link
Owner

I've merged all the logic into a single job that runs on both macOS and Ubuntu, using the cached SDK from the Ubuntu build

Thanks for all the work you put into this, macOS support is long overdue. 😄

Hopefully it is good enough to merge, but I'm happy to do any further cleanup or refactoring that you think might be needed.

I'm going to go through this long pull and list some nits. Once you've fixed all that and squashed into a single commit, I will experiment a bit with the failing packages and merge.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 7, 2024

I'm going to go through this long pull and list some nits. Once you've fixed all that and squashed into a single commit,

Can't you just do "Squash and merge" when merging the PR?

I will experiment a bit with the failing packages and merge.

I just figured out the NIO problems are likely due to a macOS-incompatible regex where the local dependency replacement in the Package.swift wasn't being applied, and so the nio patch wasn't being used. I'm testing out a fix for that now: https://github.com/marcprux/swift-android-sdk/actions/runs/10287306294

Still not sure about the swift-argument-parser linker error, though.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 7, 2024

I just figured out the NIO problems are likely due to a macOS-incompatible regex where the local dependency replacement in the Package.swift wasn't being applied, and so the nio patch wasn't being used. I'm testing out a fix for that now: https://github.com/marcprux/swift-android-sdk/actions/runs/10287306294

Yes, that was the problem. The differences in sed syntax are annoying, because there is no indication when they fail.

I've merged in the fix, so the NIO packages are now being built and tested on macOS.

@finagolfin
Copy link
Owner

Can't you just do "Squash and merge" when merging the PR?

I think that would also squash my commit into yours, whereas I'd like this to consist finally of two commits: your changes and mine.

Still not sure about the swift-argument-parser linker error, though.

Yes, especially since it's built first because it's one of the simpler packages to build.

You mentioned that you have an Android SDK bundle working locally: does cross-compiling code with Macros work with the bundle? You can try cross-compiling the swift-syntax examples, as shown here but using the bundle command instead (make sure you build the tests too, as that's where that failed), and see if that works.

@marcprux
Copy link
Contributor Author

I think that would also squash my commit into yours, whereas I'd like this to consist finally of two commits: your changes and mine.

OK. I fear I may need to make a new branch and open a new PR, since I'm not sure how to rebase to selectively squash my own commits while retaining yours.

You mentioned that you have an Android SDK bundle working locally: does cross-compiling code with Macros work with the bundle? You can try cross-compiling the swift-syntax examples, as shown here but using the bundle command instead (make sure you build the tests too, as that's where that failed), and see if that works.

Not with 5.10 (as expected), where it incorrectly cross-compiles the macro (it incorrectly builds an ELF ./.build/aarch64-unknown-linux-android24/debug/MacroExamplesImplementation executable and tries to run it on the host). But they do work with the 6.0 toolchain:

zap swift-syntax/Examples % ~/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swift build --destination destination.json --build-tests
…
[522/522] Linking ExamplesPackageTests
Build complete! (59.83s)

zap swift-syntax/Examples % file ./.build/arm64-apple-macosx/debug/MacroExamplesImplementation-tool
./.build/arm64-apple-macosx/debug/MacroExamplesImplementation-tool: Mach-O 64-bit executable arm64

Thanks for swiftlang/swift-package-manager#7118 @MaxDesiatov!

I can add a CI test for macros in another PR, either by running against swift-syntax/Examples, or against a fresh swift package init --type=macro package.

@finagolfin
Copy link
Owner

I'm not sure how to rebase to selectively squash my own commits while retaining yours.

Right now, I have no commits in this pull, so if there's a git command to just squash the last 145 commits, you can use that.

they do work with the 6.0 toolchain

This is using your SDK bundle or just my CI-generated 6.0 SDK? That SwiftPM pull you linked didn't fix the latter for me, but maybe subsequent work has.

@marcprux
Copy link
Contributor Author

marcprux commented Aug 10, 2024

Right now, I have no commits in this pull, so if there's a git command to just squash the last 145 commits, you can use that.

I just reset my branch and made a new one with a single commit. It seemed to automatically close the PR, which I then re-opened. Let me know if it looks OK to you.

they do work with the 6.0 toolchain

This is using your SDK bundle or just my CI-generated 6.0 SDK? That SwiftPM pull you linked didn't fix the latter for me, but maybe subsequent work has.

Using your CI-generated 6.0 SDK and the swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain.

@finagolfin
Copy link
Owner

Using your CI-generated 6.0 SDK and the swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain.

Huh, I just tried it with that 6.0 SDK from my CI on linux, still getting the same error:

error: Failed opening '/home/finagolfin/swift-syntax/Examples/.build/aarch64-unknown-linux-android24/debug/index/store/v5/units/AddAsyncMacroTests.swift.o-20XPE2PQ2J7J7': No such file or directory

That would explain why my bug report was ignored, if it worked on macOS but only failed on linux. Looks like this is some incompatibility between a linux and mac host toolchain, same error with the trunk July 15 SDK too.

Your single commit looks fine, I will go through it today and list some nits.

@marcprux
Copy link
Contributor Author

still getting the same error

Oops, it turns out I'm also seeing the same error (or nearly: MacroExamplesPluginTest instead of AddAsyncMacroTests):

/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-08-01-a.xctoolchain/usr/bin/swift build --destination aarch64-unknown-linux-android24.json --build-tests --verbose
…
error: Failed opening '/opt/src/github/swiftlang/swift-syntax/Examples/.build/aarch64-unknown-linux-android24/debug/index/store/v5/units/MacroExamplesPluginTest.swift.o-XXSTVL13ZZXY': No such file or directory

TBH, I'm not quite sure why I was thinking that it was working. I had definitely seen it build when I reported success, but I may have accidentally just been using the host toolchain w/ the host destination or something like that. I can dig further, but this might be worthy of a separate issue thread.

@finagolfin
Copy link
Owner

OK, good to hear it's not just linux, as that would have been very unusual. Can you try with the SDK bundle you created, as I asked initially? I wonder if that makes a difference.

@marcprux
Copy link
Contributor Author

Can you try with the SDK bundle you created, as I asked initially? I wonder if that makes a difference.

Same result with the bundle I created. 😞

@marcprux
Copy link
Contributor Author

Perhaps a first step would be to see if we can get swift-foundation building for Android as part of the CI?

It would be easier to do so locally, which I plan to try natively on Android in the coming week.

I was planning on taking a run at swift-foundation in the coming week. Have you started looking at it? Do you have a sense of what hurdles there might be to overcome?

@finagolfin
Copy link
Owner

Same result with the bundle I created

Sigh, I was hoping that might fix it. What destination config file schema version are you using in your bundle?

Have you started looking at it? Do you have a sense of what hurdles there might be to overcome?

Funny you ask now, 😄 as I just got all the swift-foundation tests passing natively on Android AArch64. I will submit a pull to that repo soon.

@marcprux
Copy link
Contributor Author

Same result with the bundle I created

Sigh, I was hoping that might fix it. What destination config file schema version are you using in your bundle?

v1. Do you think that the more recent version might work differently?

Have you started looking at it? Do you have a sense of what hurdles there might be to overcome?

Funny you ask now, 😄 as I just got all the swift-foundation tests passing natively on Android AArch64. I will submit a pull to that repo soon.

Fabulous! I can't wait to see it.

@finagolfin
Copy link
Owner

Do you think that the more recent version might work differently?

I was hoping it might fix this issue, else these SDK bundles are completely busted if you still can't cross-compile packages with Macros.

I can't wait to see it.

Surprisingly, most of the tests passed on Android already, I just fixed and enabled a few more, swiftlang/swift-foundation#871.

@marcprux
Copy link
Contributor Author

Just a head's up that I removed the release build with NDK 25c, so you'll need to rebase.

OK, thanks for letting me know.

Also, I'm close to running all the tests for the Foundation rewrite natively on Android again, and work to get that cross-compiled properly is ongoing upstream, so I hope to start cross-compiling the latest Swift 6 snapshots on this CI again soon.

Nice!

In between, I will try to fully review this in the coming week. Have you had a chance to take a look at the failing SDK builds on macOS? Would be nice to fix that if I start building the latest snapshot tags again.

I did take another run at it, and I've gotten the build a bit further along, but it is still failing. FTR, the main issue seems to be the cmake scripts that use checks like CMAKE_SYSTEM_NAME STREQUAL "Darwin", and then just assume that the target is going to be macOS rather than the cross-compilation target (Android). So things like linker flags are assuming Apple's linker, rather than the NDK linker.

I plan to put together a branch with CI that tries to build against the macOS target, and then we can see if we can inch forward with failures there. But for the record, here's what I've needed to do so far just to get the basics building:

# macOS specific fixes

# LIBDISPATCH_RUNTIME_DIR=lib needed or libdispatch copy fails
EXTRA_CMAKE_OPTIONS="-DLIBDISPATCH_RUNTIME_DIR=lib -DSWIFT_STDLIB_HAS_ASL=FALSE -DLLVM_NO_DEAD_STRIP=TRUE -DSWIFT_DISABLE_DEAD_STRIPPING=TRUE"

# LLVM_LINKER_IS_APPLE is often set to TRUE when CMAKE_SYSTEM_NAME STREQUAL "Darwin", irregardless of whether we are using a non-Apple linker
# disable set(shared_cache_link_flags "LINKER:-not_for_dyld_shared_cache")
sed -i ${SEDINPLACE} 's;LLVM_LINKER_IS_APPLE AND;LLVM_LINKER_IS_APPLE AND NOT "ANDROID" IN_LIST SWIFT_SDKS AND;g' swift/stdlib/public/CMakeLists.txt

# needed to disable list(APPEND result "-Wl,-dead_strip")
sed -i ${SEDINPLACE} 's;CMAKE_SYSTEM_NAME MATCHES "Darwin";CMAKE_SYSTEM_NAME MATCHES "Darwin" AND NOT "ANDROID" IN_LIST SWIFT_SDKS;g' swift/stdlib/cmake/modules/AddSwiftStdlib.cmake

# needed to prevent ObjectiveC import in swift/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift
sed -i ${SEDINPLACE} 's;CMAKE_SYSTEM_NAME STREQUAL "Darwin";CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT "ANDROID" IN_LIST SWIFT_SDKS;g' swift/stdlib/private/CMakeLists.txt

sed -i ${SEDINPLACE} 's;NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin";NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR "ANDROID" IN_LIST SWIFT_SDKS;g' swift/cmake/modules/Libdispatch.cmake

# fix the ndk_toolchain_path so it points to ~/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64 and not ~/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/macosx-arm64
sed -i ${SEDINPLACE} "s;StdlibDeploymentTarget.host_target().name;'darwin-x86_64';g" swift/utils/swift_build_support/swift_build_support/targets.py

# TODO: need to patch swift/utils/swift_build_support/swift_build_support/targets.py to add swift_flags:
# flags += ' -Xlinker -L/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift/android/aarch64/'

# FIXME: seem to need -Ddispatch_DIR=${PWD}/./build/Ninja-Release/swift-android-aarch64/libdispatch-android-aarch64-prefix/src/libdispatch-android-aarch64-build/cmake/modules/ to avoid CMake Error at CMakeLists.txt:20 (find_package): Could not find a package configuration file provided by "dispatch" with any of the following names

This gets the build as far as llbuild, where it is failing with:

-- Found PythonInterp: /opt/homebrew/bin/python3.12 (found version "3.12.4")
-- Performing Test CXX_SUPPORTS_UNREACHABLE_CODE_FLAG
-- Performing Test CXX_SUPPORTS_UNREACHABLE_CODE_FLAG - Success
-- The Swift compiler identification is Apple 6.0
warning: Could not read SDKSettings.json for SDK at: /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
-- Check for working Swift compiler: /Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc
-- Check for working Swift compiler: /Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc - broken
CMake Error at /opt/homebrew/Cellar/cmake/3.30.2/share/cmake/Modules/CMakeTestSwiftCompiler.cmake:43 (message):
  The Swift compiler

    "/Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/CMakeFiles/CMakeScratch/TryCompile-eYVQ5z'
    
    Run Build Command(s): /opt/homebrew/bin/ninja -v cmTC_e3da5
    [1/2][ 50%][0.156s] /Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc -j 10 -num-threads 10 -c  -module-name cmTC_e3da5 -target aarch64-unknown-linux-android24 -resource-dir /opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift -sdk /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -tools-directory /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin -Xlinker -L/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift/android/aarch64/ -Xlinker -L/Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/24/  -module-cache-path "/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/module-cache"  -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -incremental -output-file-map CMakeFiles/cmTC_e3da5.dir//output-file-map.json  /opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/CMakeFiles/CMakeScratch/TryCompile-eYVQ5z/main.swift
    [2/2][100%][0.313s] : && /Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc -j 10 -num-threads 10 -emit-executable -o cmTC_e3da5 -target aarch64-unknown-linux-android24 -resource-dir /opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift -sdk /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -tools-directory /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin -Xlinker -L/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift/android/aarch64/ -Xlinker -L/Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/24/  -module-cache-path "/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/module-cache"  -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk CMakeFiles/cmTC_e3da5.dir/main.swift.o    && :
    FAILED: cmTC_e3da5 
    : && /Users/marc/Library/Developer/Toolchains/swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-19-a.xctoolchain/usr/bin/swiftc -j 10 -num-threads 10 -emit-executable -o cmTC_e3da5 -target aarch64-unknown-linux-android24 -resource-dir /opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift -sdk /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -tools-directory /Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin -Xlinker -L/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/swift-android-aarch64/lib/swift/android/aarch64/ -Xlinker -L/Users/marc/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/24/  -module-cache-path "/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/module-cache"  -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk CMakeFiles/cmTC_e3da5.dir/main.swift.o    && :
    error: link command failed with exit code 1 (use -v to see invocation)
    ld.lld: error: cannot open crtbegin_dynamic.o: No such file or directory
    ld.lld: error: cannot open crtend_android.o: No such file or directory
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.
    

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  products/CMakeLists.txt:8 (enable_language)


./swift/utils/build-script -RA --skip-build-cmark --build-llvm=0 --android --android-ndk $ANDROID_NDK --android-arch ${{ matrix.arch }} --android-api-level $ANDROID_API_LEVEL --build-swift-tools=0 --native-swift-tools-path=`pwd`/$SWIFT_TAG-ubuntu22.04/usr/bin --native-clang-tools-path=`pwd`/$SWIFT_TAG-ubuntu22.04/usr/bin --cross-compile-hosts=android-${{ matrix.arch }} --cross-compile-deps-path=$SDK --skip-local-build --build-swift-static-stdlib --xctest --skip-early-swift-driver --install-swift --install-libdispatch --install-foundation --install-xctest --install-destdir=$SDK --swift-install-components='clang-resource-dir-symlink;license;stdlib;sdk-overlay' --cross-compile-append-host-target-to-destdir=False -b -p --install-llbuild --sourcekit-lsp --skip-early-swiftsyntax
./swift/utils/build-script -RA --skip-build-cmark --build-llvm=0 --android --android-ndk $NDK --android-arch ${{ matrix.arch }} --android-api-level $ANDROID_API_LEVEL --build-swift-tools=0 --native-swift-tools-path=${TOOLCHAIN}/bin --native-clang-tools-path=${TOOLCHAIN}/bin --cross-compile-hosts=android-${{ matrix.arch }} --cross-compile-deps-path=$SDK --skip-local-build --build-swift-static-stdlib --xctest --skip-early-swift-driver --install-swift --install-libdispatch --install-foundation --install-xctest --install-destdir=$SDK --swift-install-components='clang-resource-dir-symlink;license;stdlib;sdk-overlay' --cross-compile-append-host-target-to-destdir=False -b -p --install-llbuild --sourcekit-lsp --skip-early-swiftsyntax
Copy link
Owner

Choose a reason for hiding this comment

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

You reverted $ANDROID_NDK to $NDK by mistake here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops! Fixed in f35d681

@finagolfin
Copy link
Owner

the main issue seems to be the cmake scripts that use checks like CMAKE_SYSTEM_NAME STREQUAL "Darwin", and then just assume that the target is going to be macOS rather than the cross-compilation target (Android). So things like linker flags are assuming Apple's linker, rather than the NDK linker.

Sounds good, can you turn this into a patch instead and add it to this pull? I only use sed for small tweaks in rapidly-updated files that probably won't be upstreamed, but you could clean up and upstream this patch, as it will affect cross-compilation for all non-Darwin platforms on macOS.

Then, don't set BUILD_SWIFT_PM=1 on macOS, set SPM_FLAGS="-b -p --install-llbuild --sourcekit-lsp" and only add it to the build-script command on linux, so only the main corelibs are built on macOS.

I only set that variable and those build flags on the CI as a test if the freshly-built SDK is working well: their build output is not actually used. As you said, we can try to get those working in a separate pull later.

Finally, use your freshly-built SDK to build the packages on macOS on this CI and we can remove the dependency on the linux-built SDK.

@finagolfin
Copy link
Owner

Alright, got all the Foundation tests running natively on Android: pretty good shape with 12 tests that had been failing before the Swift rewrite now fixed by upstream, 5 tests still failing, and 3 tests newly failing, mostly small stuff that doesn't matter. I will upstream a few more local tweaks and need to look into an issue with the latest trunk toolchain requiring more import Androids than a month ago, despite both using almost the same module map, then I can start trying to get the latest Swift 6 snapshots cross-compiled on this CI, by using in-progress pulls like this.

In between, I will review this pull; would be good to get the SDK building on macOS too, as I described in my last comment.

@marcprux
Copy link
Contributor Author

would be good to get the SDK building on macOS too, as I described in my last comment.

I'm still banging my head against the wall with this. There are endless errors on the macOS build – I've figured out and fixed a bunch of them, but they keep coming. I'd recommend against gating this PR on getting the macOS build working, and instead we can work through that in #164.

@finagolfin
Copy link
Owner

I don't understand: the last error you listed was when building llbuild, Change Dir: '/opt/src/github/swift-android-sdk/swift-android-sdk/build/Ninja-Release/llbuild-android-aarch64/CMakeFiles/CMakeScratch/TryCompile-eYVQ5z', which as I noted above is unnecessary to build the SDK. I only build llbuild and SwiftPM onwards to test the Android SDK, which consists of the stdlib and three corelibs, libdispatch, foundation, and XCTest.

Is one of those SDK libraries failing to build again?

${TOOLCHAIN}/bin/swift --version
BUILD_SWIFT_PM=1 ${TOOLCHAIN}/bin/swift get-packages-and-swift-source.swift

SDK_NAME=$(ls | grep swift-$(echo ${{ matrix.version }} | sed "s/-2[5-9][a-e]*//")-android-${{ matrix.arch }})
Copy link
Owner

Choose a reason for hiding this comment

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

You need to rebase, this sed is no longer required.

"-resource-dir", "${SDK_PATH}/usr/lib/swift",
"-tools-directory", "${NDK_PREBUILT}/bin",
"-L", "${SDK_PATH}/usr/lib",
"-L", "${SDK_PATH}/usr/lib/swift/android"
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think this flag is necessary, as the compiler should automatically add it.


# need to free up some space or else the emulator fails to launch:
# ERROR | Not enough space to create userdata partition. Available: 6086.191406 MB at /home/runner/.android/avd/../avd/test.avd, need 7372.800000 MB.
rm -rf */.build
Copy link
Owner

Choose a reason for hiding this comment

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

Move this up and combine it with my last rm -rf line above, and move this comment above that too.

@finagolfin
Copy link
Owner

Thanks for all your work on this pull, really appreciate it and will be sure to attribute you when I announce the next SDK 6 release on the forum.

I think if you rebase and address this last handful of nits, we can get this in.

@marcprux
Copy link
Contributor Author

marcprux commented Sep 3, 2024

OK, I've rebased and addressed the recent batch of issues. Let me know if there is anything else I can do for this.

@finagolfin
Copy link
Owner

Rebase and fix the one-line merge conflict, then go ahead and squash all your commits. Once it passes CI, I will look this over one last time tomorrow and merge.

@marcprux marcprux force-pushed the main branch 2 times, most recently from 00489dd to e7784c7 Compare September 3, 2024 22:25
@marcprux
Copy link
Contributor Author

marcprux commented Sep 3, 2024

Rebase and fix the one-line merge conflict, then go ahead and squash all your commits. Once it passes CI, I will look this over one last time tomorrow and merge.

I rebased and fixed, but now I'm having a hard time squashing everything, because there are merge commits interleaved in the commit history, and it is leading to a lot of conflicts.

If you want just one single commit, I could simply make a new PR, since there are only a couple of files that were changed.

@finagolfin
Copy link
Owner

finagolfin commented Sep 4, 2024

Hmm, you could try something like git diff upstream/main > mac.patch to dump this patch, assuming you have my repo at upstream then upstream/main is my main branch. Then, simply delete this branch locally and recreate it, before pushing it here again with a single commit applied:

git checkout upstream/main
git branch -D main
git checkout -b main
git apply mac.patch
git commit .github get-packages-and-swift-source.swift -m"new commit message"
git push -f origin main

@marcprux
Copy link
Contributor Author

marcprux commented Sep 4, 2024

That seemed to work! Brilliant solution!

@finagolfin
Copy link
Owner

Thanks, that should do it.

I plan to try building the latest devel/trunk snapshots on this CI next, ie with the Foundation rewrite, so we'll have to get the SDK building on macOS too after that, or stagger the macOS package-building runs to keep using the linux-built SDKs initially.

Anyway, that depends on my getting the Foundation rewrite cross-compiling on linux for Android first, so I will let you know.

@finagolfin
Copy link
Owner

Heh, github is still complaining, I think because you missed a single commit of mine when you recreated this branch initially.

Try repeating the above commands, but run git fetch upstream first, or whatever you named my upstream repo in git remote -v. That should sync your local upstream/main to the tip of my main branch first.

@marcprux
Copy link
Contributor Author

marcprux commented Sep 4, 2024

Heh, github is still complaining, I think because you missed a single commit of mine when you recreated this branch initially.

Try repeating the above commands, but run git fetch upstream first, or whatever you named my upstream repo in git remote -v. That should sync your local upstream/main to the tip of my main branch first.

You're right. I've run through it again, and now we're back to 1 commit with no conflicts.

@marcprux
Copy link
Contributor Author

marcprux commented Sep 4, 2024

I plan to try building the latest devel/trunk snapshots on this CI next, ie with the Foundation rewrite, so we'll have to get the SDK building on macOS too after that, or stagger the macOS package-building runs to keep using the linux-built SDKs initially.

Yeah, I plan on working on that next. In the meantime, it probably just means running the CI a second time after the Linux builds pass, so that the macOS builds can grab the cached SDK.

@finagolfin finagolfin merged commit e1fe285 into finagolfin:main Sep 5, 2024
21 checks passed
@finagolfin
Copy link
Owner

Thanks for all your work on this! 🥳 I had a vague goal of doing this someday, but given that I don't use macOS, would probably have given up considering how much work it took you.

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.

2 participants