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

cargo-apk: Work around missing libgcc on NDK r23 with linker script #189

Merged
merged 1 commit into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ Branch | Version | Status | Working
r18 | 18.1.5063045 | _Deprecated_ | :x:
r19 | 19.2.5345600 | _Deprecated_ | :heavy_check_mark:
r20 | 20.1.5948944 | _Deprecated_ | :heavy_check_mark:
r21 | 21.4.7075529 | LTS | :heavy_check_mark:
r22 | 22.1.7171670 | Rolling Release | :heavy_check_mark:
r23 beta 1/2 | | Beta | :heavy_check_mark:
r23 beta 3 and beyond | | Beta | :x: Breaking on [#149](https://github.com/rust-windowing/android-ndk-rs/issues/149) :x:
r21 | 21.4.7075529 | _Deprecated_ | :heavy_check_mark:
r22 | 22.1.7171670 | _Deprecated_ | :heavy_check_mark:
r23 | beta 1/2 | _Deprecated_ | :heavy_check_mark:
r23 | 23.0.7272597-beta3 | _Deprecated_ | :heavy_check_mark: Workaround in [#189](https://github.com/rust-windowing/android-ndk-rs/pull/189)
r23 | 23.1.7779620 | LTS | :heavy_check_mark: Workaround in [#189](https://github.com/rust-windowing/android-ndk-rs/pull/189)
r24 | 24.0.7856742-beta1 | Rolling Release | :heavy_check_mark: Workaround in [#189](https://github.com/rust-windowing/android-ndk-rs/pull/189)


## Hello world

Expand Down
2 changes: 2 additions & 0 deletions cargo-apk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Unreleased

- Fixed the library name in case of multiple build artifacts in the Android manifest.
- Work around missing `libgcc` on NDK r23 beta 3 and above, by providing linker script that "redirects" to `libunwind`.
See https://github.com/rust-windowing/android-ndk-rs/issues/149 and https://github.com/rust-lang/rust/pull/85806 for more details.

# 0.8.1 (2021-08-06)

Expand Down
23 changes: 22 additions & 1 deletion cargo-apk/src/apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,32 @@ impl<'a> ApkBuilder<'a> {
let target_sdk_version = config.manifest.sdk.target_sdk_version.unwrap();

let mut cargo = cargo_ndk(&config.ndk, *target, target_sdk_version)?;
cargo.arg("build");
cargo.arg("rustc");
if self.cmd.target().is_none() {
cargo.arg("--target").arg(triple);
}
cargo.args(self.cmd.args());

// Workaround for https://github.com/rust-windowing/android-ndk-rs/issues/149:
// Rust (1.56 as of writing) still requires libgcc during linking, but this does
// not ship with the NDK anymore since NDK r23 beta 3.
// See https://github.com/rust-lang/rust/pull/85806 for a discussion on why libgcc
// is still required even after replacing it with libunwind in the source.
// XXX: Add an upper-bound on the Rust version whenever this is not necessary anymore.
if self.ndk.build_tag() > 7272597 {
if !self.cmd.args().contains(&"--".to_owned()) {
cargo.arg("--");
}
let cargo_apk_link_dir = self
.cmd
.target_dir()
.join("cargo-apk-temp-extra-link-libraries");
std::fs::create_dir_all(&cargo_apk_link_dir)?;
std::fs::write(cargo_apk_link_dir.join("libgcc.a"), "INPUT(-lunwind)")
.expect("Failed to write");
cargo.arg("-L").arg(cargo_apk_link_dir);
}

if !cargo.status()?.success() {
return Err(NdkError::CmdFailed(cargo).into());
}
Expand Down
2 changes: 2 additions & 0 deletions ndk-build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Provide NDK `build_tag` version from `source.properties` in the NDK root.

# 0.4.2 (2021-08-06)

- Pass UNIX path separators to `aapt` on non-UNIX systems, ensuring the resulting separator is compatible with the target device instead of the host platform.
Expand Down
31 changes: 31 additions & 0 deletions ndk-build/src/ndk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct Ndk {
sdk_path: PathBuf,
ndk_path: PathBuf,
build_tools_version: String,
build_tag: u32,
platforms: Vec<u32>,
}

Expand Down Expand Up @@ -54,6 +55,31 @@ impl Ndk {
.max()
.ok_or(NdkError::BuildToolsNotFound)?;

let build_tag = std::fs::read_to_string(ndk_path.join("source.properties"))
.expect("Failed to read source.properties");

let build_tag = build_tag
.split('\n')
.find_map(|line| {
let (key, value) = line
.split_once('=')
.expect("Failed to parse `key = value` from source.properties");
if key.trim() == "Pkg.Revision" {
// AOSP writes a constantly-incrementing build version to the patch field.
// This number is incrementing across NDK releases.
let mut parts = value.trim().split('.');
let _major = parts.next().unwrap();
let _minor = parts.next().unwrap();
let patch = parts.next().unwrap();
// Can have an optional `XXX-beta1`
let patch = patch.split_once('-').map_or(patch, |(patch, _beta)| patch);
Some(patch.parse().expect("Failed to parse patch field"))
} else {
None
}
})
.expect("No `Pkg.Revision` in source.properties");

let ndk_platforms = std::fs::read_to_string(ndk_path.join("build/core/platforms.mk"))?;
let ndk_platforms = ndk_platforms
.split('\n')
Expand Down Expand Up @@ -88,6 +114,7 @@ impl Ndk {
sdk_path,
ndk_path,
build_tools_version,
build_tag,
platforms,
})
}
Expand All @@ -104,6 +131,10 @@ impl Ndk {
&self.build_tools_version
}

pub fn build_tag(&self) -> u32 {
self.build_tag
}

pub fn platforms(&self) -> &[u32] {
&self.platforms
}
Expand Down