Skip to content

Commit

Permalink
cargo-apk: Reimplement NDK r23 -lgcc workaround using RUSTFLAGS (#…
Browse files Browse the repository at this point in the history
…270)

Any flags passed directly to `cargo rustc` will only be passed _to the
final compiler invocation_.  However `cdylib` library targets in
transitive (dependency) crates will still be built (despite not being
used in the final binary, that's what `rlib`s are for), but our NDK r23
workaround flags will not reach these compiler invocations rendering
b912a6b ("cargo-apk: Work around missing libgcc on NDK r23 with linker
script (#189)") ineffective.

[The same page] that documents this discrepancy suggests to resort to
`RUSTFLAGS` if arguments are intended for all compiler invocations,
which is our intended use-case and unblocks builds with transitive
`cdylib` dependencies such as `hyper` in [#265].

[The same page]: https://doc.rust-lang.org/cargo/commands/cargo-rustc.html#description
[#265]: #265
  • Loading branch information
MarijnS95 authored May 12, 2022
1 parent 16ae6bc commit b3b9a95
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
2 changes: 2 additions & 0 deletions cargo-apk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Reimplement NDK r23 `-lgcc` workaround using `RUSTFLAGS`, to apply to transitive `cdylib` compilations (#270)

# 0.9.0 (2022-05-07)

- **Breaking:** Use `min_sdk_version` to select compiler target instead of `target_sdk_version`. ([#197](https://github.com/rust-windowing/android-ndk-rs/pull/197))
Expand Down
24 changes: 19 additions & 5 deletions cargo-apk/src/apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl<'a> ApkBuilder<'a> {
.join(artifact.file_name(CrateType::Cdylib, triple));

let mut cargo = cargo_ndk(&config.ndk, *target, self.min_sdk_version())?;
cargo.arg("rustc");
cargo.arg("build");
if self.cmd.target().is_none() {
cargo.arg("--target").arg(triple);
}
Expand All @@ -188,17 +188,31 @@ impl<'a> ApkBuilder<'a> {
// 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);

// cdylibs in transitive dependencies still get built and also need this
// workaround linker flag, yet arguments passed to `cargo rustc` are only
// forwarded to the final compiler invocation rendering our workaround ineffective.
// The cargo page documenting this discrepancy (https://doc.rust-lang.org/cargo/commands/cargo-rustc.html)
// suggests to resort to RUSTFLAGS, which are updated below:
let mut rustflags = match std::env::var("RUSTFLAGS") {
Ok(val) => val,
Err(std::env::VarError::NotPresent) => "".to_string(),
Err(std::env::VarError::NotUnicode(_)) => {
panic!("RUSTFLAGS environment variable contains non-unicode characters")
}
};
rustflags += " -L ";
rustflags += cargo_apk_link_dir
.to_str()
.expect("Target dir must be valid UTF-8");
cargo.env("RUSTFLAGS", rustflags);
}

if !cargo.status()?.success() {
Expand Down

0 comments on commit b3b9a95

Please sign in to comment.