Skip to content

Commit

Permalink
For #970 & #1303 : Enable build for aarch64-linux-android & x86_64-li…
Browse files Browse the repository at this point in the history
…nux-android (#1468)
  • Loading branch information
Taknok committed Apr 22, 2024
1 parent 20b2989 commit d11b720
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 28 deletions.
5 changes: 4 additions & 1 deletion .cargo/config.toml
@@ -1,2 +1,5 @@
[target.aarch64-linux-android]
linker = "./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++"
linker = "./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++"

[target.x86_64-linux-android]
linker = "./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++"
41 changes: 39 additions & 2 deletions .github/workflows/ci.yml
Expand Up @@ -30,42 +30,72 @@ jobs:
- os: macOS-latest
target: x86_64-apple-darwin
variant: debug
cargo: cargo

- os: macOS-latest
target: x86_64-apple-darwin
variant: release
cargo: cargo

- os: macos-14
target: aarch64-apple-darwin
variant: asan
cargo: cargo

- os: macos-14
target: aarch64-apple-darwin
variant: debug
cargo: cargo

- os: macos-14
target: aarch64-apple-darwin
variant: release
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: x86_64-unknown-linux-gnu
variant: debug
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: x86_64-unknown-linux-gnu
variant: release
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'windows-2019-xxl' || 'windows-2019' }}
target: x86_64-pc-windows-msvc
variant: release # Note: we do not support windows debug builds.
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: aarch64-unknown-linux-gnu
variant: debug
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: aarch64-unknown-linux-gnu
variant: release
cargo: cargo

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: aarch64-linux-android
variant: debug
cargo: cross

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: aarch64-linux-android
variant: release
cargo: cross

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: x86_64-linux-android
variant: debug
cargo: cross

- os: ${{ github.repository == 'denoland/rusty_v8' && 'ubuntu-22.04-xl' || 'ubuntu-22.04' }}
target: x86_64-linux-android
variant: release
cargo: cross

env:
V8_FROM_SOURCE: true
Expand Down Expand Up @@ -113,6 +143,13 @@ jobs:
- name: Write git_submodule_status.txt
run: git submodule status --recursive > git_submodule_status.txt

- name: Install cross and build custom image
if: contains(matrix.config.target, 'linux-android')
run: |
mkdir -p /home/runner/.local/bin
curl -qL https://github.com/cross-rs/cross/releases/download/v0.2.5/cross-x86_64-unknown-linux-musl.tar.gz | tar xz -C /home/runner/.local/bin
sudo docker build --build-arg CROSS_BASE_IMAGE=ghcr.io/cross-rs/${{ matrix.config.target }}:0.2.5 -t cross-rusty_v8:${{ matrix.config.target }} .
- name: Cache
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -175,12 +212,12 @@ jobs:
SCCACHE_IDLE_TIMEOUT: 0
if: matrix.config.variant == 'debug' || matrix.config.variant == 'release'
run:
cargo test -vv --all-targets --locked ${{ env.CARGO_VARIANT_FLAG }}
${{ matrix.config.cargo }} test -vv --all-targets --locked ${{ env.CARGO_VARIANT_FLAG }}
--target ${{ matrix.config.target }}

- name: Clippy
run:
cargo clippy --all-targets --locked ${{ env.CARGO_VARIANT_FLAG }}
${{ matrix.config.cargo }} clippy --all-targets --locked ${{ env.CARGO_VARIANT_FLAG }}
--target ${{ matrix.config.target }} -- -D clippy::all

- name: Rustfmt
Expand Down
19 changes: 16 additions & 3 deletions Cross.toml
@@ -1,6 +1,3 @@
[target.aarch64-linux-android]
image = "cross:aarch64-linux-android-0.2.1"

[build.env]
passthrough = [
"V8_FROM_SOURCE",
Expand All @@ -9,3 +6,19 @@ passthrough = [
"SCCACHE_DIR",
"SCCACHE_IDLE_TIMEOUT"
]

[target.aarch64-linux-android]
image = "cross-rusty_v8:aarch64-linux-android"

[target.aarch64-linux-android.env]
passthrough = [
"CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++"
]

[target.x86_64-linux-android]
image = "cross-rusty_v8:x86_64-linux-android"

[target.x86_64-linux-android.env]
passthrough = [
"CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++"
]
12 changes: 7 additions & 5 deletions Dockerfile
@@ -1,20 +1,22 @@
FROM rustembedded/cross:aarch64-linux-android-0.2.1
ARG CROSS_BASE_IMAGE
FROM $CROSS_BASE_IMAGE

RUN apt update && \
apt install -y curl && \
curl -L https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xzf -
curl -L https://github.com/mozilla/sccache/releases/download/v0.7.7/sccache-v0.7.7-x86_64-unknown-linux-musl.tar.gz | tar xzf -

ENV TZ=Etc/UTC
COPY ./build/*.sh /chromium_build/
RUN \
DEBIAN_FRONTEND=noninteractive \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& apt-get update && apt-get install -y lsb-release sudo \
&& /chromium_build/install-build-deps-android.sh \
&& sed -i 's/snapcraft/snapcraftnoinstall/g' /chromium_build/install-build-deps.sh \
&& /chromium_build/install-build-deps.sh --no-prompt --no-chromeos-fonts \
&& rm -rf /chromium_build \
&& rm -rf /var/lib/apt/lists/*

RUN chmod +x /sccache-v0.2.15-x86_64-unknown-linux-musl/sccache
RUN chmod +x /sccache-v0.7.7-x86_64-unknown-linux-musl/sccache

ENV SCCACHE=/sccache-v0.2.15-x86_64-unknown-linux-musl/sccache
ENV SCCACHE=/sccache-v0.7.7-x86_64-unknown-linux-musl/sccache
ENV SCCACHE_DIR=./target/sccache
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -115,6 +115,15 @@ For Mac builds: You'll need Xcode and Xcode CLT installed. Recent macOS versions
will also require you to pass PYTHON=python3 because macOS no longer ships with
`python` simlinked to Python 3.

For Android builds: You'll need to cross compile from a x86_64 host to the aarch64 or x64 android. You can use the following commands:
```bash
rustup target add aarch64-linux-android # or x86_64-linux-android
V8_FROM_SOURCE=1 cargo build -vv --target aarch64-linux-android
# or with cross
docker build --build-arg CROSS_BASE_IMAGE=ghcr.io/cross-rs/aarch64-linux-android:0.2.5 -t cross-rusty_v8:aarch64-linux-android .
V8_FROM_SOURCE=1 cross build -vv --target aarch64-linux-android
```

The build depends on several binary tools: `gn`, `ninja` and `clang`. The tools
will automatically be downloaded, if they are not detected in the environment.

Expand Down
47 changes: 40 additions & 7 deletions build.rs
Expand Up @@ -208,18 +208,51 @@ fn build_v8(is_asan: bool) {
maybe_install_sysroot("amd64");
};

if target_triple == "aarch64-linux-android" {
gn_args.push(r#"v8_target_cpu="arm64""#.to_string());
gn_args.push(r#"target_os="android""#.to_string());
let t_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let t_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();

if t_os == "android" {
let arch = if t_arch == "x86_64" {
"x64"
} else if t_arch == "aarch64" {
"arm64"
} else {
"unknown"
};

if t_arch == "x86_64" {
maybe_install_sysroot("amd64");
}

gn_args.push(format!(r#"v8_target_cpu="{}""#, arch).to_string());
gn_args.push(format!(r#"target_cpu="{}""#, arch).to_string());
gn_args.push(r#"target_os="android""#.to_string());
gn_args.push("treat_warnings_as_errors=false".to_string());
gn_args.push("use_sysroot=true".to_string());

// NDK 23 and above removes libgcc entirely.
// https://github.com/rust-lang/rust/pull/85806
maybe_clone_repo(
"./third_party/android_ndk",
"https://github.com/denoland/android_ndk.git",
);
if !Path::new("./third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++").exists() {
assert!(Command::new("curl")
.arg("-L")
.arg("-o").arg("./third_party/android-ndk-r26c-linux.zip")
.arg("https://dl.google.com/android/repository/android-ndk-r26c-linux.zip")
.status()
.unwrap()
.success());

assert!(Command::new("unzip")
.arg("-d").arg("./third_party/")
.arg("-o")
.arg("-q")
.arg("./third_party/android-ndk-r26c-linux.zip")
.status()
.unwrap()
.success());

fs::rename("./third_party/android-ndk-r26c", "./third_party/android_ndk").unwrap();
fs::remove_file("./third_party/android-ndk-r26c-linux.zip").unwrap();
}

static CHROMIUM_URI: &str = "https://chromium.googlesource.com";

Expand Down
31 changes: 21 additions & 10 deletions tests/test_api.rs
Expand Up @@ -7456,11 +7456,13 @@ fn module_snapshot() {
}
}

#[cfg(not(all(target_os = "android", target_arch = "x86_64")))]
#[derive(Default)]
struct TestHeapLimitState {
near_heap_limit_callback_calls: u64,
}

#[cfg(not(all(target_os = "android", target_arch = "x86_64")))]
extern "C" fn heap_limit_callback(
data: *mut c_void,
current_heap_limit: usize,
Expand All @@ -7473,6 +7475,7 @@ extern "C" fn heap_limit_callback(

// This test might fail due to a bug in V8. The upstream bug report is at
// https://bugs.chromium.org/p/v8/issues/detail?id=10843.
#[cfg(not(all(target_os = "android", target_arch = "x86_64")))]
#[test]
fn heap_limits() {
let _setup_guard = setup::parallel_test();
Expand Down Expand Up @@ -7508,6 +7511,8 @@ fn heap_limits() {
assert_eq!(1, test_state.near_heap_limit_callback_calls);
}

// Same as heap_limits()
#[cfg(not(all(target_os = "android", target_arch = "x86_64")))]
#[test]
fn heap_statistics() {
let _setup_guard = setup::parallel_test();
Expand Down Expand Up @@ -8583,6 +8588,8 @@ fn run_with_rust_allocator() {
assert_eq!(count_loaded, 0);
}

// Same as heap_limits()
#[cfg(not(all(target_os = "android", target_arch = "x86_64")))]
#[test]
fn oom_callback() {
extern "C" fn oom_handler(
Expand Down Expand Up @@ -9028,6 +9035,7 @@ fn compile_function() {
assert_eq!(42 * 1337, result.int32_value(scope).unwrap());
}

#[cfg(not(target_os = "android"))]
static EXAMPLE_STRING: v8::OneByteConst =
v8::String::create_external_onebyte_const(b"const static");

Expand Down Expand Up @@ -9099,16 +9107,19 @@ fn external_strings() {
assert!(latin1.contains_only_onebyte());

// one-byte "const" test
assert_eq!(EXAMPLE_STRING.as_bytes(), b"const static");
let const_ref_string =
v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap();
assert!(const_ref_string.is_external());
assert!(const_ref_string.is_external_onebyte());
assert!(!const_ref_string.is_external_twobyte());
assert!(const_ref_string.is_onebyte());
assert!(const_ref_string.contains_only_onebyte());
assert!(const_ref_string
.strict_equals(v8::String::new(scope, "const static").unwrap().into()));
#[cfg(not(target_os = "android"))]
{
assert_eq!(EXAMPLE_STRING.as_bytes(), b"const static");
let const_ref_string =
v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap();
assert!(const_ref_string.is_external());
assert!(const_ref_string.is_external_onebyte());
assert!(!const_ref_string.is_external_twobyte());
assert!(const_ref_string.is_onebyte());
assert!(const_ref_string.contains_only_onebyte());
assert!(const_ref_string
.strict_equals(v8::String::new(scope, "const static").unwrap().into()));
}
}

#[test]
Expand Down

0 comments on commit d11b720

Please sign in to comment.