Skip to content

Commit 42a6e76

Browse files
bors[bot]orion78fr
andauthored
Merge #754
754: Allow the use of the new Android ndk paths r=Bromeon a=orion78fr Hi, As said in #345 comments, ndk is now installed in the `ndk` folder and the `ndk-bundle` folder installation is obsolete (as shown in the SDK Manager of Android studio). ![image](https://user-images.githubusercontent.com/8122888/123173493-fbc6a700-d47e-11eb-9528-20b49f30b0e9.png) The new way allow multiple ndk to be installed in parallel. If there is only one available, the build script pick this one. If multiple NDK versions are installed, you can specify one with the `ANDROID_NDK_VERSION` env var. It still fallbacks to the `ndk-bundle` folder just to maintain old behaviour. I added a check that the ndk is present too, and panic if absent, as it's needed for the headers. Feel free to ask for any modifications, I'm clearly not a rust expert. I manually tested all the code paths on my install, but I don't know where the tests for this are written (as they are not present in #345 PR). Co-authored-by: Guillaume Turchini <[email protected]>
2 parents 2c685ab + 9962c58 commit 42a6e76

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
@@ -211,35 +211,18 @@ jobs:
211211
# rust: ${{ matrix.rust.toolchain }}
212212
- name: "Install Java + NDK"
213213
run: |
214-
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64;
215-
export ANDROID_SDK_ROOT=/opt/ndk/android-ndk-r21d;
216214
# aarch64 and armv7 cover most Android phones & tablets.;
217215
rustup target add aarch64-linux-android armv7-linux-androideabi;
218216
sudo apt-get update;
219-
sudo apt-get install openjdk-8-jdk;
220217
sudo apt-get install llvm-dev libclang-dev clang g++-multilib gcc-multilib libc6-dev libc6-dev-arm64-cross;
221-
# Downloading NDK. This file is huge (1Gb) maybe extract only what's needed and repackage.;
222-
# See https://developer.android.com/ndk/downloads for updates.;
223-
# The Android SDK which comes with Android Studio is not required. Only Java + NDK are.;
224-
mkdir /opt/ndk
225-
install -d /opt/ndk;
226-
cd /opt/ndk && wget -nc -nv https://dl.google.com/android/repository/android-ndk-r21d-linux-x86_64.zip && cd $GITHUB_WORKSPACE;
227-
echo "bcf4023eb8cb6976a4c7cff0a8a8f145f162bf4d /opt/ndk/android-ndk-r21d-linux-x86_64.zip" >> /opt/ndk/SHA1SUM.txt;
228-
sha1sum --check /opt/ndk/SHA1SUM.txt;
229-
cd /opt/ndk && unzip -q android-ndk-r21d-linux-x86_64.zip && cd $GITHUB_WORKSPACE;
230-
# Using clang linker from NDK when building Android programs.;
231-
install -d $HOME/.cargo;
232-
echo >> $HOME/.cargo/config;
233-
echo "[target.aarch64-linux-android]" >> $HOME/.cargo/config;
234-
find /opt/ndk -name aarch64-linux-android21-clang++ -printf 'linker = "%p"\n' >> $HOME/.cargo/config;
235-
echo >> $HOME/.cargo/config;
236-
echo "[target.armv7-linux-androideabi]" >> $HOME/.cargo/config;
237-
find /opt/ndk -name armv7a-linux-androideabi21-clang++ -printf 'linker = "%p"\n' >> $HOME/.cargo/config;
238-
echo >> $HOME/.cargo/config;
239218
- name: "Build Rust for targets: aarch64-linux-android, armv7-linux-androideabi"
240219
run: |
220+
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++
221+
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++
241222
cargo build --target aarch64-linux-android --release;
242223
cargo build --target armv7-linux-androideabi --release;
224+
env:
225+
ANDROID_NDK_VERSION: 21.4.7075529
243226

244227
integration-test-godot:
245228
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)