From da9a8fdd3fc8cbfc62c3d319c01449a595f69e16 Mon Sep 17 00:00:00 2001 From: David Braden Date: Wed, 20 Sep 2023 18:29:49 -0600 Subject: [PATCH] android ci (#52) * android ci * on * arm names * can't shutdown * no arm for now * google_apis * try 29 * additional setup * another cflags * asm in arch dir * woops * fixes * cache? * target cc * cleanup --- .github/workflows/android.yml | 76 ++++++++++++++++++++++++++++ .gitignore | 1 + Cargo.lock | 12 +++++ Cargo.toml | 4 ++ Makefile | 2 +- android-build-tests.bash | 47 +++++++++++++++++ android-run-tests.bash | 8 +++ crates/tx5-demo/Cargo.toml | 1 + crates/tx5-go-pion-sys/build.rs | 87 +++++++++++++++++++++++++------- crates/tx5-go-pion-turn/build.rs | 64 ++++++++++++++++++++--- crates/tx5/Cargo.toml | 1 + 11 files changed, 275 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/android.yml create mode 100755 android-build-tests.bash create mode 100755 android-run-tests.bash diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 00000000..6730b690 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,76 @@ +name: Android Test +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + test: + runs-on: macos-latest + strategy: + matrix: + #android-arch: ["arm64-v8a", "x86_64"] + android-arch: ["x86_64"] + android-api-level: [29] + android-ndk-version: ["26.0.10792818"] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Go Toolchain + uses: actions/setup-go@v3 + with: + go-version: '=1.18.0' + + - name: Rust Toolchain + run: | + rustup toolchain install stable --profile minimal --no-self-update + #rustup target add aarch64-linux-android + rustup target add x86_64-linux-android + + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + + - name: Avd Cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.android-api-level }} + + - name: Avd Snapshot + if: steps.avd-cache.outputs.cache-hit != 'true' + env: + ANDROID_API_LEVEL: ${{ matrix.android-api-level }} + ANDROID_NDK_VERSION: ${{ matrix.android-ndk-version }} + ANDROID_ARCH: ${{ matrix.android-arch }} + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.android-api-level }} + ndk: ${{ matrix.android-ndk-version }} + arch: ${{ matrix.android-arch }} + target: google_apis + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + script: echo "Generated AVD snapshot for caching." + + - name: Build and Run Tests + env: + ANDROID_API_LEVEL: ${{ matrix.android-api-level }} + ANDROID_NDK_VERSION: ${{ matrix.android-ndk-version }} + ANDROID_ARCH: ${{ matrix.android-arch }} + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.android-api-level }} + ndk: ${{ matrix.android-ndk-version }} + arch: ${{ matrix.android-arch }} + target: google_apis + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: ./android-build-tests.bash && ./android-run-tests.bash diff --git a/.gitignore b/.gitignore index ea8c4bf7..104baaa8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/output-* diff --git a/Cargo.lock b/Cargo.lock index b0858b73..43f02552 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2212,6 +2212,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "111.28.0+1.1.1w" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ce95ee1f6f999dfb95b8afd43ebe442758ea2104d1ccb99a94c30db22ae701f" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.90" @@ -2220,6 +2229,7 @@ checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -3788,6 +3798,7 @@ dependencies = [ "influxive-child-svc", "influxive-otel-atomic-obs", "once_cell", + "openssl-sys", "parking_lot", "rand", "rand-utf8", @@ -3832,6 +3843,7 @@ dependencies = [ "clap", "futures", "influxive", + "openssl-sys", "rand", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index dcf7b65f..9bdebfcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,9 @@ members = [ "crates/tx5-go-pion-turn", ] +[profile.release] +strip = true + [workspace.dependencies] base64 = "0.13.0" bytes = "1.4.0" @@ -28,6 +31,7 @@ lair_keystore_api = "0.3.0" libc = "0.2.141" libloading = "0.8.0" once_cell = "1.17.1" +openssl-sys = { version = "0.9.90", features = [ "vendored" ] } opentelemetry_api = { version = "=0.20.0-beta.1", features = [ "metrics" ], package = "ts_opentelemetry_api" } ouroboros = "0.15.6" parking_lot = "0.12.1" diff --git a/Makefile b/Makefile index e1693d00..4ac83f20 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ tool_clippy: tool_rust tool_readme: tool_rust @if ! (cargo rdme --version); \ then \ - cargo install cargo-rdme --version 1.4.0; \ + cargo install cargo-rdme --version 1.4.0 --locked; \ else \ echo "# Makefile # readme ok"; \ fi; diff --git a/android-build-tests.bash b/android-build-tests.bash new file mode 100755 index 00000000..6d1c4d0b --- /dev/null +++ b/android-build-tests.bash @@ -0,0 +1,47 @@ +#!/bin/bash + +set -eEuxo pipefail + +if [[ "${ANDROID_API_LEVEL:-x}" == "x" ]]; then + echo "ANDROID_API_LEVEL required" + exit 127 +fi + +if [[ "${ANDROID_NDK_VERSION:-x}" == "x" ]]; then + echo "ANDROID_NDK_VERSION required" + exit 127 +fi + +if [[ "${ANDROID_ARCH:-x}" == "x" ]]; then + echo "ANDROID_ARCH required" + exit 127 +else + if [[ "${ANDROID_ARCH}" == "arm64-v8a" ]]; then + export ANDROID_ARCH="aarch64" + fi +fi + + +if [[ "${ANDROID_SDK_ROOT:-x}" == "x" ]]; then + echo "ANDROID_SDK_ROOT required" + exit 127 +fi + +_ndk_root=(${ANDROID_SDK_ROOT}/ndk/${ANDROID_NDK_VERSION}/toolchains/llvm/prebuilt/*) + +# This workaround may be needed if upgrading android api level +#cat << EOF > ${_ndk_root}/lib/clang/17/lib/linux/${ANDROID_ARCH}/libgcc.a +#INPUT(-lunwind) +#EOF + +export PKG_CONFIG_SYSROOT_DIR="${_ndk_root}/sysroot" +export TARGET_CC="${_ndk_root}/bin/${ANDROID_ARCH}-linux-android${ANDROID_API_LEVEL}-clang" +export TARGET_CFLAGS="-I${_ndk_root}/sysroot/usr/include -I${_ndk_root}/sysroot/usr/include/${ANDROID_ARCH}-linux-android" +export TARGET_AR="${_ndk_root}/bin/llvm-ar" +export TARGET_RANLIB="${_ndk_root}/bin/llvm-ranlib" +export CGO_CFLAGS="-I${_ndk_root}/sysroot/usr/include -I${_ndk_root}/sysroot/usr/include/${ANDROID_ARCH}-linux-android" + +cargo test --no-run --release --target ${ANDROID_ARCH}-linux-android --config target.${ANDROID_ARCH}-linux-android.linker="\"${_ndk_root}/bin/${ANDROID_ARCH}-linux-android34-clang\"" --config target.${ANDROID_ARCH}-linux-android.ar="\"${_ndk_root}/bin/llvm-ar\"" 2>&1 | tee output-cargo-test +cat output-cargo-test | grep Executable | sed -E 's/[^(]*\(([^)]*)\)/\1/' > output-test-executables +echo "BUILD TESTS:" +cat output-test-executables diff --git a/android-run-tests.bash b/android-run-tests.bash new file mode 100755 index 00000000..94d65656 --- /dev/null +++ b/android-run-tests.bash @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eEuxo pipefail + +for i in $(cat output-test-executables); do + adb push $i /data/local/tmp/$(basename $i) + adb shell /data/local/tmp/$(basename $i) +done diff --git a/crates/tx5-demo/Cargo.toml b/crates/tx5-demo/Cargo.toml index cd17b6fc..019aaf76 100644 --- a/crates/tx5-demo/Cargo.toml +++ b/crates/tx5-demo/Cargo.toml @@ -16,6 +16,7 @@ bytes = { workspace = true } clap = { workspace = true } futures = { workspace = true } influxive = { workspace = true } +openssl-sys = { workspace = true } opentelemetry_api = { workspace = true } rand = { workspace = true } serde = { workspace = true } diff --git a/crates/tx5-go-pion-sys/build.rs b/crates/tx5-go-pion-sys/build.rs index 45aeb0b4..feefe8b1 100644 --- a/crates/tx5-go-pion-sys/build.rs +++ b/crates/tx5-go-pion-sys/build.rs @@ -63,17 +63,19 @@ fn go_build() { let mut lib_path = out_dir.clone(); - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))] - lib_path.push("go-pion-webrtc.dylib"); - #[cfg(target_os = "windows")] - lib_path.push("go-pion-webrtc.dll"); - #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "windows" - )))] - lib_path.push("go-pion-webrtc.so"); + let tgt_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + + match tgt_os.as_str() { + "macos" | "ios" | "tvos" => { + lib_path.push("go-pion-webrtc.dylib"); + } + "windows" => { + lib_path.push("go-pion-webrtc.dll"); + } + _ => { + lib_path.push("go-pion-webrtc.so"); + } + } let mut cache = out_dir.clone(); cache.push("go-build"); @@ -101,14 +103,61 @@ fn go_build() { let mut cmd = Command::new("go"); // add some cross-compilation translators: - #[cfg(target_arch = "arm")] - cmd.env("GOARCH", "arm"); - #[cfg(target_arch = "aarch64")] - cmd.env("GOARCH", "arm64"); - #[cfg(target_arch = "x86_64")] - cmd.env("GOARCH", "amd64"); - #[cfg(target_arch = "x86")] - cmd.env("GOARCH", "386"); + match std::env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() { + "arm" => { + cmd.env("GOARCH", "arm"); + } + "aarch64" => { + cmd.env("GOARCH", "arm64"); + } + "x86_64" => { + cmd.env("GOARCH", "amd64"); + } + "x86" => { + cmd.env("GOARCH", "386"); + } + _ => (), + } + + // and for the os + match tgt_os.as_str() { + "windows" => { + cmd.env("GOOS", "windows"); + } + "macos" => { + cmd.env("GOOS", "darwin"); + } + "ios" => { + cmd.env("GOOS", "ios"); + } + "linux" => { + cmd.env("GOOS", "linux"); + } + "android" => { + cmd.env("GOOS", "android"); + } + "dragonfly" => { + cmd.env("GOOS", "dragonfly"); + } + "freebsd" => { + cmd.env("GOOS", "freebsd"); + } + "openbsd" => { + cmd.env("GOOS", "openbsd"); + } + "netbsd" => { + cmd.env("GOOS", "netbsd"); + } + _ => (), + } + + if tgt_os == "android" { + let linker = std::env::var("RUSTC_LINKER").unwrap(); + println!("cargo:warning=LINKER: {linker:?}"); + cmd.env("CC_FOR_TARGET", &linker); + cmd.env("CC", &linker); + cmd.env("CGO_ENABLED", "1"); + } // grr, clippy, the debug symbols belong in one arg #[allow(clippy::suspicious_command_arg_space)] diff --git a/crates/tx5-go-pion-turn/build.rs b/crates/tx5-go-pion-turn/build.rs index 6282dc50..499d1535 100644 --- a/crates/tx5-go-pion-turn/build.rs +++ b/crates/tx5-go-pion-turn/build.rs @@ -77,14 +77,62 @@ fn go_build(path: &std::path::Path) { let mut cmd = Command::new("go"); // add some cross-compilation translators: - #[cfg(target_arch = "arm")] - cmd.env("GOARCH", "arm"); - #[cfg(target_arch = "aarch64")] - cmd.env("GOARCH", "arm64"); - #[cfg(target_arch = "x86_64")] - cmd.env("GOARCH", "amd64"); - #[cfg(target_arch = "x86")] - cmd.env("GOARCH", "386"); + match std::env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() { + "arm" => { + cmd.env("GOARCH", "arm"); + } + "aarch64" => { + cmd.env("GOARCH", "arm64"); + } + "x86_64" => { + cmd.env("GOARCH", "amd64"); + } + "x86" => { + cmd.env("GOARCH", "386"); + } + _ => (), + } + + // and for the os + let tgt_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + match tgt_os.as_str() { + "windows" => { + cmd.env("GOOS", "windows"); + } + "macos" => { + cmd.env("GOOS", "darwin"); + } + "ios" => { + cmd.env("GOOS", "ios"); + } + "linux" => { + cmd.env("GOOS", "linux"); + } + "android" => { + cmd.env("GOOS", "android"); + } + "dragonfly" => { + cmd.env("GOOS", "dragonfly"); + } + "freebsd" => { + cmd.env("GOOS", "freebsd"); + } + "openbsd" => { + cmd.env("GOOS", "openbsd"); + } + "netbsd" => { + cmd.env("GOOS", "netbsd"); + } + _ => (), + } + + if tgt_os == "android" { + let linker = std::env::var("RUSTC_LINKER").unwrap(); + println!("cargo:warning=LINKER: {linker:?}"); + cmd.env("CC_FOR_TARGET", &linker); + cmd.env("CC", &linker); + cmd.env("CGO_ENABLED", "1"); + } // grr, clippy, the debug symbols belong in one arg #[allow(clippy::suspicious_command_arg_space)] diff --git a/crates/tx5/Cargo.toml b/crates/tx5/Cargo.toml index 1b401141..56590e36 100644 --- a/crates/tx5/Cargo.toml +++ b/crates/tx5/Cargo.toml @@ -42,6 +42,7 @@ webrtc = { workspace = true, optional = true } criterion = { workspace = true } influxive-child-svc = { workspace = true } influxive = { workspace = true } +openssl-sys = { workspace = true } tempfile = { workspace = true } tokio = { workspace = true, features = [ "macros", "rt", "rt-multi-thread", "sync" ] } tracing-subscriber = { workspace = true }