Skip to content

Do not add -sysroot flag when ANDROID_NDK_ROOT environment is set #1879

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

marcprux
Copy link

When the environment ANDROID_NDK_ROOT is set, the driver manually adds it as a --sysroot flag. This breaks building with an Android SDK when this variable is set, with confusing errors. I first saw this at finagolfin/swift-android-sdk#207 (comment), and more recently ran into it again (https://github.com/swift-android-sdk/swift-docker/actions/runs/14584558227/job/40907674425) while working on the official Android SDK build script, where it fails a build with:

<unknown>:0: error: missing required module 'SwiftAndroid'

In both cases, manually un-setting ANDROID_NDK_ROOT (which is set by default in GitHub workflows) resolved the issue.

This flag has some history (#1560, #1681, and #1811), but I feel like it should just be excised altogether since the Android SDK can specify its own sdkRootPath in the swift-sdk.json file. If Windows needs it due to lack of Swift SDK support, then it could be gated inside an #if os(Windows) check.

And BTW, the #if arch(x86_64) check is incorrect: the Android NDK works on both Intel and ARM macOS machines, despite being stored under "darwin-x86_64", as the binaries are universal:

zap ~ % file $ANDROID_HOME/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang
~/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
~/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang (for architecture x86_64):	Mach-O 64-bit executable x86_64
~/Library/Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang (for architecture arm64):	Mach-O 64-bit executable arm64

@marcprux
Copy link
Author

I've marked this ready for review, @jakepetroules, @finagolfin, and @compnerd.

See also the discussion at swiftlang/swift-build#495 (comment)

@finagolfin
Copy link
Member

I agree with getting rid of this. As much as the idea is to automatically set things up and make things automatically work, I think it's better to have the user configure this themselves. For example, this env variable is automatically set on the github CI, so even if the user explicitly configures the sdkRootPath to some other NDK, that will be overridden by this environment variable.

Better to not have such magic and make the setup more explicit, as it would be after this pull.

@compnerd
Copy link
Member

This is going to break all of our builds, please do not commit this as is. We need the ability to be able to pass the -sysroot through. I don't think that this is the right approach.

@marcprux
Copy link
Author

This is going to break all of our builds

Then how about gating it within an #if os(Windows) check? This issue a blocker for Android builds on macOS and Linux, so we need some solution.

@jakepetroules
Copy link
Contributor

This is going to break all of our builds, please do not commit this as is. We need the ability to be able to pass the -sysroot through. I don't think that this is the right approach.

This change isn't removing the ability to do that, right? It's just removing the default fallback. From what I understand, explicitly passing -sysroot is still gonna work, and that's what we want build systems to do anyways. Am I understanding incorrectly?

@marcprux
Copy link
Author

@compnerd Any thoughts on either @jakepetroules's questions or my suggestion? I'd really like to reach some solution so we can un-block the Android SDK work.

@compnerd
Copy link
Member

This is going to break all of our builds, please do not commit this as is. We need the ability to be able to pass the -sysroot through. I don't think that this is the right approach.

This change isn't removing the ability to do that, right? It's just removing the default fallback. From what I understand, explicitly passing -sysroot is still gonna work, and that's what we want build systems to do anyways. Am I understanding incorrectly?

Ah, right; this still will break our builds as we do rely on the default. Can we wire up the default through swift-build before we remove this?

@jakepetroules
Copy link
Contributor

As far as I know, swift-build is already doing the right thing here, e.g. it will always pass a value for -sdk when compiling for Android.

@finagolfin
Copy link
Member

@compnerd or @weliveindetail, could you apply this change to your CI and let us know if it causes any error and what the full output is? Because that may turn up an underlying bug that is better fixed rather than papering over it with this Android default.

marcprux added a commit to swift-android-sdk/swift-android-action that referenced this pull request Jul 3, 2025
@marcprux
Copy link
Author

marcprux commented Jul 3, 2025

This hasn't made it into the swift-6.2 brach, has it? I'm still seeing the build failures when I have ANDROID_NDK_ROOT set, which is especially problematic because the developer needs to set ANDROID_NDK_HOME to run the SDK setup script initially, but needs to un-set ANDROID_NDK_ROOT. These are both set to the same value in GitHub actions.

@finagolfin Can you add this to the project board?

@jakepetroules
Copy link
Contributor

Can we get this updated and landed? @compnerd do you still have concerns?

@compnerd
Copy link
Member

compnerd commented Aug 1, 2025

I think that we should wait until @finagolfin's frontend/driver changes are done and then re-test before merging this. The --sysroot flag is needed to allow us to pull content from the NDK without copying it into the Swift SDK, so I would prefer that we do not merge this change.

@finagolfin
Copy link
Member

My frontend change in swiftlang/swift#79621 only affects -sdk usage, does not affect this -sysroot usage at all.

It is unclear why this env variable detection and -sysroot flag insertion is so important to your builds, as you could just detect it manually in your build scripts and add it in your config yourself. This is really just a convenience method for swift-driver to do that for you, but the problem is that it breaks other build environments that have multiple NDKs and don't use the env variable but manually pass in the NDK path.

Is there some ordering issue or something, on the TBC CI builds with this pull? If you guys would simply try this patch and replace it with manually passing in this flag to your build config, we could determine if this was really necessary to you or not, from the resulting error output, if any.

@finagolfin
Copy link
Member

@marcprux, mind rebasing?

@finagolfin
Copy link
Member

@swift-ci test

@finagolfin
Copy link
Member

@swift-ci test windows

@finagolfin
Copy link
Member

@Steelskin, can you apply this pull to your Windows CI, along with passing in this -sysroot ANDROID_NDK_ROOT flag manually through wherever your Android build config is, similar to how the Powershell script build.ps1 is already doing this, and report any build errors that you see?

The problem with this default is that it forces everyone to use the NDK at ANDROID_NDK_ROOT or have to unset that variable each time, when many have alternate NDKs they want to use through swift sdk configure instead, swiftlang/swift-package-manager#8856.

@Steelskin
Copy link

@Steelskin, can you apply this pull to your Windows CI, along with passing in this -sysroot ANDROID_NDK_ROOT flag manually through wherever your Android build config is, similar to how the Powershell script build.ps1 is already doing this, and report any build errors that you see?

The problem with this default is that it forces everyone to use the NDK at ANDROID_NDK_ROOT or have to unset that variable each time, when many have alternate NDKs they want to use through swift sdk configure instead, swiftlang/swift-package-manager#8856.

I am in the process of changing our build to more closely match what is being done in buid.ps1, but this is still a work in progress. In the meantime, it is going to be a bit challenging to get this to run so bear with me.
We run our smoke android test with the following:

          swift build `
            --package-path ${{ github.workspace }}/SourceCache/cassowary `
            --triple ${{ matrix.arch }}-unknown-linux-android${{ inputs.ANDROID_API_LEVEL }} `
            --sdk "${{ steps.android-swift-env.outputs.sysroot }}" `
            -Xswiftc -sdk -Xswiftc "${{ steps.android-swift-env.outputs.sdkroot }}" `
            -Xswiftc -sysroot -Xswiftc "${{ steps.android-swift-env.outputs.sysroot }}" `
            -Xswiftc -I -Xswiftc "${{ steps.android-swift-env.outputs.sdkroot }}\usr\include" `
            -Xswiftc -Xclang-linker -Xswiftc -resource-dir -Xswiftc -Xclang-linker -Xswiftc ${{ steps.android-swift-env.outputs.clang-resource-dir }}

Does that sound about correct to you or would you like me to edit some of the flags and/or the environment here?

@finagolfin
Copy link
Member

Are you sure you need both --sdk sdk-path and -Xswiftc -sdk -Xswiftc sdk-path? The latter seems redundant, but perhaps there is a bug I'm unaware of.

Other than that, I'd like you to run these flags you've pasted but using a swift-driver with this pull of Marc's applied: see if removing this ANDROID_NDK_ROOT detection causes any problem on your CI when you're passing it in with -Xswiftc -sysroot -Xswiftc ndk-path instead.

@Steelskin
Copy link

Are you sure you need both --sdk sdk-path and -Xswiftc -sdk -Xswiftc sdk-path? The latter seems redundant, but perhaps there is a bug I'm unaware of.

Not sure, this is how the build is configured. I can toy with what arguments we actually need at a later time.

Other than that, I'd like you to run these flags you've pasted but using a swift-driver with this pull of Marc's applied: see if removing this ANDROID_NDK_ROOT detection causes any problem on your CI when you're passing it in with -Xswiftc -sysroot -Xswiftc ndk-path instead.

Alright, got it. All I did was change the swift-driver repo to point to swift-everywhere:main. The build is ongoing, I'll let you know how it goes.

@Steelskin
Copy link

@finagolfin Our CI succeeded with the current swift-everywhere:main branch.

@finagolfin
Copy link
Member

@compnerd, if you would approve or let us know if you need to test anything else, I'd like to get this in.

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