Build Android and iOS/macOS libraries on CI

This commit is contained in:
eric
2023-03-31 03:33:11 +08:00
parent 1de877aeae
commit 4e6117b376
8 changed files with 237 additions and 73 deletions

View File

@@ -9,7 +9,7 @@ jobs:
os:
- macos-latest
- ubuntu-latest
- windows-latest
# - windows-latest
runs-on: ${{ matrix.os }}
steps:
- name: checkout
@@ -20,7 +20,7 @@ jobs:
- name: install rust toolchain
uses: hecrj/setup-rust-action@v1
with:
rust-version: nightly
rust-version: stable
- name: test leaf
run: cargo test -p leaf
@@ -32,12 +32,12 @@ jobs:
matrix:
target:
- mips-unknown-linux-musl
# - mipsel-unknown-linux-musl
- mipsel-unknown-linux-musl
- x86_64-unknown-linux-musl
# - i686-unknown-linux-musl
- i686-unknown-linux-musl
- aarch64-unknown-linux-musl
# - arm-unknown-linux-musleabi
# - armv7-unknown-linux-musleabihf
- arm-unknown-linux-musleabi
- armv7-unknown-linux-musleabihf
- x86_64-pc-windows-gnu
steps:
- name: checkout
@@ -48,7 +48,7 @@ jobs:
- name: install rust toolchain
uses: hecrj/setup-rust-action@v1
with:
rust-version: nightly
rust-version: stable
- name: install deps
run: |
@@ -62,7 +62,7 @@ jobs:
run: |
export CFG_COMMIT_HASH=`git log --pretty=format:'%h' -n 1`
export CFG_COMMIT_DATE=`git log --format="%ci" -n 1`
./misc/build_cross.sh ${{ matrix.target }}
./scripts/build_cross.sh ${{ matrix.target }}
- name: rename and compress artifacts
if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }}
@@ -109,7 +109,7 @@ jobs:
- name: install rust toolchain
uses: hecrj/setup-rust-action@v1
with:
rust-version: nightly
rust-version: stable
- name: install llvm
if: ${{ matrix.os == 'macos-latest' }}
@@ -132,38 +132,80 @@ jobs:
name: leaf-${{ matrix.target }}
path: leaf-${{ matrix.target }}
# build-lib-ios:
# runs-on: macos-latest
# steps:
# - name: checkout
# uses: actions/checkout@v2
# with:
# submodules: true
#
# - name: install rust
# uses: hecrj/setup-rust-action@v1
# with:
# rust-version: nightly
#
# - name: install toolchain
# run: |
# rustup target add aarch64-apple-ios
# cargo install cargo-lipo
# cargo install cbindgen
# brew update && brew install llvm unzip protobuf
#
# - name: build
# run: |
# make ios
#
# - name: zip artifacts
# run: |
# mv target/universal/release/libleaf.a .
# mv target/universal/release/leaf.h .
# zip libleaf-ios.zip leaf.h libleaf.a
#
# - name: upload assets
# uses: actions/upload-artifact@v2
# with:
# name: libleaf-ios.zip
# path: libleaf-ios.zip
build-apple:
runs-on: macos-latest
steps:
- name: checkout
uses: actions/checkout@v2
with:
submodules: true
- name: install rust
uses: hecrj/setup-rust-action@v1
with:
rust-version: stable
- name: install toolchain
run: |
cargo install cbindgen
brew update && brew install llvm unzip protobuf
- name: build
run: |
./scripts/build_apple_xcframework.sh
- name: zip artifacts
run: |
mv target/apple/release/leaf.xcframework .
zip -r leaf.xcframework.zip leaf.xcframework
- name: upload assets
uses: actions/upload-artifact@v2
with:
name: leaf.xcframework.zip
path: leaf.xcframework.zip
build-android:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
with:
submodules: true
- name: install rust
uses: hecrj/setup-rust-action@v1
with:
rust-version: stable
- name: install toolchain
run: |
cargo install cbindgen
apt update && apt install -y make llvm-dev libclang-dev clang pkg-config unzip curl default-jdk build-essential
export ANDROID_HOME=/tmp/Android/sdk
export NDK_HOME=/tmp/Android/sdk/ndk/25.2.9519653
export PATH=$ANDROID_HOME/cmdline-tools/bin:$PATH
cd /tmp/
curl -OL https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip
unzip commandlinetools-linux-6858069_latest.zip
mkdir -p $ANDROID_HOME
mv cmdline-tools $ANDROID_HOME
yes | sdkmanager --sdk_root=$ANDROID_HOME --licenses
sdkmanager --sdk_root=$ANDROID_HOME "ndk;25.2.9519653" "platforms;android-21"
- name: build
run: |
export ANDROID_HOME=/tmp/Android/sdk
export NDK_HOME=/tmp/Android/sdk/ndk/25.2.9519653
./scripts/build_android.sh
- name: zip artifacts
run: |
mv target/leaf-android-libs .
zip -r leaf-android-libs.zip leaf-android-libs
- name: upload assets
uses: actions/upload-artifact@v2
with:
name: leaf-android-libs.zip
path: leaf-android-libs.zip

2
.gitignore vendored
View File

@@ -1,5 +1,3 @@
/scripts
/target
# Generated by Cargo
# will have compiled files and executables

View File

@@ -1,14 +1,4 @@
ios:
cargo build --release --target aarch64-apple-ios --manifest-path leaf-ffi/Cargo.toml --no-default-features --features "default-openssl"
cbindgen --config leaf-ffi/cbindgen.toml leaf-ffi/src/lib.rs > target/aarch64-apple-ios/release/leaf.h
lib:
cargo build -p leaf-ffi --release
cbindgen --config leaf-ffi/cbindgen.toml leaf-ffi/src/lib.rs > target/release/leaf.h
lib-dev:
cargo build -p leaf-ffi
cbindgen --config leaf-ffi/cbindgen.toml leaf-ffi/src/lib.rs > target/debug/leaf.h
.PHONY: local local-dev test proto-gen
local:
cargo build -p leaf-bin --release
@@ -16,16 +6,8 @@ local:
local-dev:
cargo build -p leaf-bin
mipsel:
./misc/build_cross.sh mipsel-unknown-linux-musl
mips:
./misc/build_cross.sh mips-unknown-linux-musl
test:
cargo test -p leaf -- --nocapture
# Force a re-generation of protobuf files.
proto-gen:
touch leaf/build.rs
PROTO_GEN=1 cargo build -p leaf
./scripts/regenerate_proto_files.sh

View File

@@ -2,12 +2,12 @@
name = "leaf-ffi"
version = "0.1.0"
authors = ["eycorsican <eric.y.corsican@gmail.com>"]
edition = "2021"
edition = "2018"
[lib]
name = "leaf"
path = "src/lib.rs"
crate-type = ["staticlib"]
crate-type = ["staticlib", "dylib"]
[features]
default = [
@@ -26,8 +26,3 @@ auto-reload = ["leaf/auto-reload"]
[dependencies]
leaf = { path = "../leaf", default-features = false, optional = true }
tokio = { version = "1", features = ["rt"] }
futures = "0.3"
[build-dependencies]
bindgen = "0.57"

73
scripts/build_android.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env sh
set -x
name=leaf
package=leaf-ffi
manifest=android/Cargo.toml
mode=--release
targets=
if [ ! -z "$2" ]; then
targets="$2"
else
targets="aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android"
fi
for target in $targets; do
rustup target add $target
done
if [ "$1" = "debug" ]; then
mode=
fi
BASE=`dirname "$0"`
HOST_OS=`uname -s | tr "[:upper:]" "[:lower:]"`
HOST_ARCH=`uname -m | tr "[:upper:]" "[:lower:]"`
export PATH="$NDK_HOME/toolchains/llvm/prebuilt/$HOST_OS-$HOST_ARCH/bin/":$PATH
android_tools="$NDK_HOME/toolchains/llvm/prebuilt/$HOST_OS-$HOST_ARCH/bin"
api=21
# See also: https://github.com/briansmith/ring/blob/main/mk/cargo.sh
for target in $targets; do
case $target in
'armv7-linux-androideabi')
export CC_armv7_linux_androideabi="$android_tools/armv7a-linux-androideabi${api}-clang"
export AR_armv7_linux_androideabi="$android_tools/llvm-ar"
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="$android_tools/armv7a-linux-androideabi${api}-clang"
;;
'x86_64-linux-android')
export CC_x86_64_linux_android="$android_tools/${target}${api}-clang"
export AR_x86_64_linux_android="$android_tools/llvm-ar"
export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="$android_tools/${target}${api}-clang"
;;
'aarch64-linux-android')
export CC_aarch64_linux_android="$android_tools/${target}${api}-clang"
export AR_aarch64_linux_android="$android_tools/llvm-ar"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$android_tools/${target}${api}-clang"
;;
'i686-linux-android')
export CC_i686_linux_android="$android_tools/${target}${api}-clang"
export AR_i686_linux_android="$android_tools/llvm-ar"
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="$android_tools/${target}${api}-clang"
;;
*)
echo "Unknown target $target"
;;
esac
cargo build -p $package --target $target $mode
done
android_libs=$BASE/../target/leaf-android-libs
mkdir -p $android_libs
for target in $targets; do
mv $BASE/../target/$target/release/libleaf.so $android_libs/libleaf-$target.so
done
cbindgen \
--config $BASE/../$package/cbindgen.toml \
$BASE/../$package/src/lib.rs > $android_libs/$name.h

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env sh
set -x
mode=release
release_flag=--release
package=leaf-ffi
name=leaf
lib=lib$name.a
# The script is assumed to run in the root of the workspace
base=$(dirname "$0")
# Debug or release build?
if [ "$1" = "debug" ]; then
mode=debug
release_flag=
fi
# Build for all desired targets
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
rustup target add aarch64-apple-ios
cargo build -p $package $release_flag --no-default-features --features "default-openssl" --target x86_64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-openssl" --target aarch64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-openssl" --target aarch64-apple-ios
# Directories to put the libraries.
rm -rf target/apple/$mode
mkdir -p target/apple/$mode/include
mkdir -p target/apple/$mode/ios
mkdir -p target/apple/$mode/macos
# Put built libraries to folders where we can find them easier later
cp target/aarch64-apple-ios/$mode/$lib target/apple/$mode/ios/
# Create a single library for multiple archs
lipo -create \
-arch x86_64 target/x86_64-apple-darwin/$mode/$lib \
-arch arm64 target/aarch64-apple-darwin/$mode/$lib \
-output target/apple/$mode/macos/$lib
# Generate the header file
cbindgen \
--config $package/cbindgen.toml \
$package/src/lib.rs > target/apple/$mode/include/$name.h
wd="$base/../target/apple/$mode"
# Remove existing artifact
rm -rf "$wd/$name.xcframework"
# A modulemap is required for the compiler to find the module when using Swift
cat << EOF > "$wd/include/module.modulemap"
module $name {
header "$name.h"
export *
}
EOF
# Create the XCFramework packaging both iOS and macOS static libraries, so we can
# use a single XCFramework for both platforms.
xcodebuild -create-xcframework \
-library "$wd/ios/$lib" \
-headers "$wd/include" \
-library "$wd/macos/$lib" \
-headers "$wd/include" \
-output "$wd/$name.xcframework"
ls $wd/$name.xcframework

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env sh
set -x
touch leaf/build.rs
PROTO_GEN=1 cargo build -p leaf