Skip to content

Commit 9962c58

Browse files
committed
Allow the use of the new Android ndk paths
Looks for the ndk under the `ndk` folder (which allows for multiple parallel ndk versions installed), then in the obsolete `ndk-bundle` folder if not found. If multiple ndk versions are found, the most recent is automatically chosen and a compilation warning is issued. A specific NDK version can be chosen with the `ANDROID_NDK_VERSION` env var. The `JAVA_HOME` env var has been removed because it's not used.
1 parent 685db31 commit 9962c58

File tree

3 files changed

+82
-72
lines changed

3 files changed

+82
-72
lines changed

.github/workflows/full-ci.yml

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -195,35 +195,18 @@ jobs:
195195
# rust: ${{ matrix.rust.toolchain }}
196196
- name: "Install Java + NDK"
197197
run: |
198-
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64;
199-
export ANDROID_SDK_ROOT=/opt/ndk/android-ndk-r21d;
200198
# aarch64 and armv7 cover most Android phones & tablets.;
201199
rustup target add aarch64-linux-android armv7-linux-androideabi;
202200
sudo apt-get update;
203-
sudo apt-get install openjdk-8-jdk;
204201
sudo apt-get install llvm-dev libclang-dev clang g++-multilib gcc-multilib libc6-dev libc6-dev-arm64-cross;
205-
# Downloading NDK. This file is huge (1Gb) maybe extract only what's needed and repackage.;
206-
# See https://developer.android.com/ndk/downloads for updates.;
207-
# The Android SDK which comes with Android Studio is not required. Only Java + NDK are.;
208-
mkdir /opt/ndk
209-
install -d /opt/ndk;
210-
cd /opt/ndk && wget -nc -nv https://dl.google.com/android/repository/android-ndk-r21d-linux-x86_64.zip && cd $GITHUB_WORKSPACE;
211-
echo "bcf4023eb8cb6976a4c7cff0a8a8f145f162bf4d /opt/ndk/android-ndk-r21d-linux-x86_64.zip" >> /opt/ndk/SHA1SUM.txt;
212-
sha1sum --check /opt/ndk/SHA1SUM.txt;
213-
cd /opt/ndk && unzip -q android-ndk-r21d-linux-x86_64.zip && cd $GITHUB_WORKSPACE;
214-
# Using clang linker from NDK when building Android programs.;
215-
install -d $HOME/.cargo;
216-
echo >> $HOME/.cargo/config;
217-
echo "[target.aarch64-linux-android]" >> $HOME/.cargo/config;
218-
find /opt/ndk -name aarch64-linux-android21-clang++ -printf 'linker = "%p"\n' >> $HOME/.cargo/config;
219-
echo >> $HOME/.cargo/config;
220-
echo "[target.armv7-linux-androideabi]" >> $HOME/.cargo/config;
221-
find /opt/ndk -name armv7a-linux-androideabi21-clang++ -printf 'linker = "%p"\n' >> $HOME/.cargo/config;
222-
echo >> $HOME/.cargo/config;
223202
- name: "Build Rust for targets: aarch64-linux-android, armv7-linux-androideabi"
224203
run: |
204+
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++
205+
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang++
225206
cargo build --target aarch64-linux-android --release;
226207
cargo build --target armv7-linux-androideabi --release;
208+
env:
209+
ANDROID_NDK_VERSION: 21.4.7075529
227210

228211
integration-test-godot:
229212
name: itest-godot-${{ matrix.godot }}${{ matrix.postfix }}

gdnative-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ bindgen = { version = "0.59.1", default-features = false, features = ["runtime"]
1919
proc-macro2 = "1.0.30"
2020
quote = "1.0.10"
2121
miniserde = "0.1.15"
22+
semver = "1.0.4"

gdnative-sys/build.rs

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,8 @@ mod header_binding {
5252

5353
assert_eq!("android", &target_os);
5454

55-
let java_home =
56-
std::env::var("JAVA_HOME").expect("JAVA_HOME and ANDROID_SDK_ROOT must be set");
57-
let java_home = Path::new(&java_home).to_path_buf();
5855
let android_sdk_root =
59-
std::env::var("ANDROID_SDK_ROOT").expect("JAVA_HOME and ANDROID_SDK_ROOT must be set");
56+
std::env::var("ANDROID_SDK_ROOT").expect("ANDROID_SDK_ROOT must be set");
6057
let android_sdk_root = Path::new(&android_sdk_root).to_path_buf();
6158

6259
// Note: cfg!(target_os) and cfg!(target_arch) refer to the target of the build script:
@@ -69,51 +66,83 @@ mod header_binding {
6966
"unsupported host architecture: build from x86_64 instead"
7067
);
7168

72-
builder = builder
73-
.clang_arg("-I")
74-
.clang_arg(Path::join(&java_home, "include/").to_string_lossy());
75-
76-
builder = builder.clang_arg("-I").clang_arg(
77-
Path::join(
78-
&java_home,
79-
format!("include/{}/", {
80-
if cfg!(target_os = "windows") {
81-
"win32"
82-
} else if cfg!(target_os = "macos") {
83-
"darwin"
84-
} else if cfg!(target_os = "linux") {
85-
"linux"
69+
let mut android_ndk_root: Option<PathBuf> = None;
70+
71+
let android_ndk_folder = Path::join(&android_sdk_root, "ndk");
72+
if android_ndk_folder.exists() {
73+
// New NDK
74+
let available_ndk_versions: Vec<_> = std::fs::read_dir(android_ndk_folder.clone())
75+
.unwrap()
76+
.into_iter()
77+
.map(|dir| dir.unwrap().path())
78+
.collect();
79+
80+
if !available_ndk_versions.is_empty() {
81+
let ndk_version = std::env::var("ANDROID_NDK_VERSION");
82+
83+
if let Ok(ndk_version) = ndk_version {
84+
if available_ndk_versions
85+
.iter()
86+
.map(|p| p.file_name())
87+
.any(|p| {
88+
p.is_some() && p.unwrap().to_string_lossy().eq(ndk_version.as_str())
89+
})
90+
{
91+
// Asked version is available
92+
android_ndk_root = Some(Path::join(&android_ndk_folder, ndk_version))
8693
} else {
87-
panic!("unsupported host OS: build from Windows, MacOS, or Linux instead");
94+
panic!(
95+
"no available android ndk versions matches {}. Available versions: {:?}",
96+
ndk_version, available_ndk_versions
97+
)
8898
}
89-
}),
90-
)
91-
.to_string_lossy(),
92-
);
99+
} else {
100+
// No NDK version chosen, chose the most recent one and issue a warning
101+
println!("cargo:warning=Multiple android ndk versions have been detected.");
102+
println!("cargo:warning=You should chose one using ANDROID_NDK_VERSION environment variable to have reproducible builds.");
103+
println!(
104+
"cargo:warning=Available versions: {:?}",
105+
available_ndk_versions
106+
);
107+
108+
let ndk_version = available_ndk_versions
109+
.iter()
110+
.filter_map(|p| p.file_name())
111+
.filter_map(|v| semver::Version::parse(v.to_string_lossy().as_ref()).ok())
112+
.max()
113+
.unwrap();
114+
115+
println!(
116+
"cargo:warning=Automatically chosen version: {} (latest)",
117+
ndk_version
118+
);
119+
120+
android_ndk_root =
121+
Some(Path::join(&android_ndk_folder, ndk_version.to_string()));
122+
}
123+
}
124+
}
93125

126+
let android_ndk_bundle_folder = Path::join(&android_sdk_root, "ndk-bundle");
127+
if android_ndk_root.is_none() && android_ndk_bundle_folder.exists() {
128+
// Old NDK
129+
android_ndk_root = Some(android_ndk_bundle_folder);
130+
}
131+
132+
let android_ndk_root = android_ndk_root.expect("Android ndk needs to be installed");
133+
134+
builder = builder
135+
.clang_arg("-I")
136+
.clang_arg(Path::join(&android_ndk_root, "sysroot/usr/include").to_string_lossy());
94137
builder = builder.clang_arg("-I").clang_arg(
95-
Path::join(&android_sdk_root, "ndk-bundle/sysroot/usr/include").to_string_lossy(),
96-
);
97-
builder = builder.clang_arg("-I").clang_arg(
98-
Path::join(
99-
&android_sdk_root,
100-
"ndk-bundle/sources/cxx-stl/llvm-libc++/include",
101-
)
102-
.to_string_lossy(),
138+
Path::join(&android_ndk_root, "sources/cxx-stl/llvm-libc++/include").to_string_lossy(),
103139
);
104140
builder = builder.clang_arg("-I").clang_arg(
105-
Path::join(
106-
&android_sdk_root,
107-
"ndk-bundle/sources/cxx-stl/llvm-libc++abi/include",
108-
)
109-
.to_string_lossy(),
141+
Path::join(&android_ndk_root, "sources/cxx-stl/llvm-libc++abi/include")
142+
.to_string_lossy(),
110143
);
111144
builder = builder.clang_arg("-I").clang_arg(
112-
Path::join(
113-
&android_sdk_root,
114-
"ndk-bundle/sources/android/support/include",
115-
)
116-
.to_string_lossy(),
145+
Path::join(&android_ndk_root, "sources/android/support/include").to_string_lossy(),
117146
);
118147

119148
let host_tag = {
@@ -130,23 +159,20 @@ mod header_binding {
130159

131160
builder = builder.clang_arg("-I").clang_arg(
132161
Path::join(
133-
&android_sdk_root,
134-
format!(
135-
"ndk-bundle/toolchains/llvm/prebuilt/{}/sysroot/usr/include",
136-
&host_tag
137-
),
162+
&android_ndk_root,
163+
format!("toolchains/llvm/prebuilt/{}/sysroot/usr/include", &host_tag),
138164
)
139165
.to_string_lossy(),
140166
);
141167

142168
builder = builder.clang_arg("-I").clang_arg(
143169
Path::join(
144-
&android_sdk_root,
170+
&android_ndk_root,
145171
format!(
146-
"ndk-bundle/toolchains/llvm/prebuilt/{host}/sysroot/usr/include/{target_triple}",
147-
host = &host_tag,
148-
target_triple = &target_triple,
149-
),
172+
"toolchains/llvm/prebuilt/{host}/sysroot/usr/include/{target_triple}",
173+
host = &host_tag,
174+
target_triple = &target_triple,
175+
),
150176
)
151177
.to_string_lossy(),
152178
);

0 commit comments

Comments
 (0)