From e639c70d78d0620e59c0b7d65daa76a95029ada7 Mon Sep 17 00:00:00 2001 From: Fangjun Kuang Date: Sat, 14 Dec 2024 09:53:44 +0800 Subject: [PATCH] Support linking onnxruntime statically for Android (#1619) --- .github/workflows/android-static.yaml | 298 ++++++++++++++++++++++++++ CMakeLists.txt | 7 +- build-android-arm64-v8a.sh | 70 ++++-- build-android-armv7-eabi.sh | 71 ++++-- build-android-x86-64.sh | 71 ++++-- build-android-x86.sh | 6 + sherpa-onnx/jni/CMakeLists.txt | 2 +- 7 files changed, 479 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/android-static.yaml diff --git a/.github/workflows/android-static.yaml b/.github/workflows/android-static.yaml new file mode 100644 index 000000000..84c05d153 --- /dev/null +++ b/.github/workflows/android-static.yaml @@ -0,0 +1,298 @@ +# static means we link onnxruntime statically +# but we still have libsherpa-onnx-jni.so +name: android-static + +on: + push: + branches: + - master + - android-link-onnxruntime-statically + paths: + - '.github/workflows/android-static.yaml' + - 'CMakeLists.txt' + - 'cmake/**' + - 'sherpa-onnx/csrc/*' + - 'sherpa-onnx/jni/*' + - 'build-android*.sh' + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + pull_request: + branches: + - master + paths: + - '.github/workflows/android-static.yaml' + - 'CMakeLists.txt' + - 'cmake/**' + - 'sherpa-onnx/csrc/*' + - 'sherpa-onnx/jni/*' + - 'build-android*.sh' + + workflow_dispatch: + +concurrency: + group: android-static-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-android-static-libs: + name: Android static libs + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ matrix.os }}-android-jni-static + + - name: Display NDK HOME + shell: bash + run: | + echo "ANDROID_NDK_LATEST_HOME: ${ANDROID_NDK_LATEST_HOME}" + ls -lh ${ANDROID_NDK_LATEST_HOME} + + - name: build android arm64-v8a + shell: bash + run: | + export BUILD_SHARED_LIBS=OFF + + export CMAKE_CXX_COMPILER_LAUNCHER=ccache + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + + export ANDROID_NDK=$ANDROID_NDK_LATEST_HOME + ./build-android-arm64-v8a.sh + mkdir -p jniLibs/arm64-v8a/ + cp -v ./build-android-arm64-v8a-static/install/lib/*.so ./jniLibs/arm64-v8a/ + rm -rf ./build-android-arm64-v8a-static/ + + - name: build android armv7-eabi + shell: bash + run: | + export BUILD_SHARED_LIBS=OFF + + export CMAKE_CXX_COMPILER_LAUNCHER=ccache + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + + export ANDROID_NDK=$ANDROID_NDK_LATEST_HOME + ./build-android-armv7-eabi.sh + mkdir -p ./jniLibs/armeabi-v7a/ + cp -v ./build-android-armv7-eabi-static/install/lib/*.so ./jniLibs/armeabi-v7a/ + rm -rf ./build-android-armv7-eabi-static + + - name: build android x86_64 + shell: bash + run: | + export BUILD_SHARED_LIBS=OFF + + export CMAKE_CXX_COMPILER_LAUNCHER=ccache + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + + export ANDROID_NDK=$ANDROID_NDK_LATEST_HOME + ./build-android-x86-64.sh + mkdir -p ./jniLibs/x86_64 + cp -v ./build-android-x86-64-static/install/lib/*.so ./jniLibs/x86_64 + rm -rf ./build-android-x86-64-static + + - name: build android x86 + shell: bash + run: | + export BUILD_SHARED_LIBS=OFF + + export CMAKE_CXX_COMPILER_LAUNCHER=ccache + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + + export ANDROID_NDK=$ANDROID_NDK_LATEST_HOME + ./build-android-x86.sh + mkdir -p ./jniLibs/x86 + cp -v ./build-android-x86/install/lib/*.so ./jniLibs/x86 + rm -rf ./build-android-x86 + + - name: Copy files + shell: bash + run: | + SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2) + echo "SHERPA_ONNX_VERSION=$SHERPA_ONNX_VERSION" >> "$GITHUB_ENV" + + filename=sherpa-onnx-${SHERPA_ONNX_VERSION}-android-static-link-onnxruntime.tar.bz2 + + tar cjvf $filename ./jniLibs + + ls -lh + + - uses: actions/upload-artifact@v4 + with: + name: sherpa-onnx-android-libs-static + path: ./jniLibs + + # https://huggingface.co/docs/hub/spaces-github-actions + - name: Publish to huggingface + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + uses: nick-fields/retry@v3 + with: + max_attempts: 20 + timeout_seconds: 200 + shell: bash + command: | + git config --global user.email "csukuangfj@gmail.com" + git config --global user.name "Fangjun Kuang" + du -h -d1 . + ls -lh + + rm -rf huggingface + export GIT_CLONE_PROTECTION_ACTIVE=false + GIT_LFS_SKIP_SMUDGE=1 git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-libs huggingface + + cd huggingface + + cp -v ../sherpa-onnx-*-android*.tar.bz2 ./ + + git status + git lfs track "*.bz2" + + git add . + + git commit -m "upload sherpa-onnx-${SHERPA_ONNX_VERSION}-android.tar.bz2" + + git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-libs main + + - name: Release android libs + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') + uses: svenstaro/upload-release-action@v2 + with: + file_glob: true + overwrite: true + file: sherpa-onnx-*-android*.tar.bz2 + + build-android-aar-static: + needs: [build-android-static-libs] + name: Android AAR + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # https://github.com/actions/setup-java + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' # See 'Supported distributions' for available options + java-version: '21' + + - name: Display NDK HOME + shell: bash + run: | + echo "ANDROID_NDK_LATEST_HOME: ${ANDROID_NDK_LATEST_HOME}" + ls -lh ${ANDROID_NDK_LATEST_HOME} + + - name: Retrieve artifact + uses: actions/download-artifact@v4 + with: + name: sherpa-onnx-android-libs-static + path: /tmp/jniLibs + + - name: Show jni libs + shell: bash + run: | + ls -lh /tmp/jniLibs + + # drwxr-xr-x 2 runner docker 4.0K Dec 12 06:56 arm64-v8a + # drwxr-xr-x 2 runner docker 4.0K Dec 12 06:56 armeabi-v7a + # drwxr-xr-x 2 runner docker 4.0K Dec 12 06:56 x86 + # drwxr-xr-x 2 runner docker 4.0K Dec 12 06:56 x86_64 + # + - name: Copy libs + shell: bash + run: | + for arch in arm64-v8a armeabi-v7a x86 x86_64; do + cp -v /tmp/jniLibs/$arch/* android/SherpaOnnxAar/sherpa_onnx/src/main/jniLibs/$arch/ + done + + - name: Check libs + shell: bash + run: | + ls -lh android/SherpaOnnxAar/sherpa_onnx/src/main/jniLibs/* + + - name: Build aar + shell: bash + run: | + cd android/SherpaOnnxAar + + ./gradlew :sherpa_onnx:assembleRelease + + - name: Display aar + shell: bash + run: | + cd android/SherpaOnnxAar + + ls -lh ./sherpa_onnx/build/outputs/aar/sherpa_onnx-release.aar + cp ./sherpa_onnx/build/outputs/aar/sherpa_onnx-release.aar ../../ + + - name: Rename aar + shell: bash + run: | + SHERPA_ONNX_VERSION=$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2) + echo "SHERPA_ONNX_VERSION=$SHERPA_ONNX_VERSION" >> "$GITHUB_ENV" + + mv sherpa_onnx-release.aar sherpa-onnx-static-link-onnxruntime-${SHERPA_ONNX_VERSION}.aar + + - uses: actions/upload-artifact@v4 + with: + name: sherpa-onnx-android-aar-static + path: ./*.aar + + # https://huggingface.co/docs/hub/spaces-github-actions + - name: Publish to huggingface + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + uses: nick-fields/retry@v3 + with: + max_attempts: 20 + timeout_seconds: 200 + shell: bash + command: | + git config --global user.email "csukuangfj@gmail.com" + git config --global user.name "Fangjun Kuang" + du -h -d1 . + ls -lh + + rm -rf huggingface + export GIT_CLONE_PROTECTION_ACTIVE=false + GIT_LFS_SKIP_SMUDGE=1 git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-libs huggingface + + cd huggingface + dst=android/aar + mkdir -p $dst + + cp -v ../*.aar $dst + + git status + git lfs track "*.aar" + + git add . + + git commit -m "upload sherpa-onnx-${SHERPA_ONNX_VERSION}.aar" + + git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-libs main + + - name: Release android aar + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') + uses: svenstaro/upload-release-action@v2 + with: + file_glob: true + overwrite: true + file: ./*.aar diff --git a/CMakeLists.txt b/CMakeLists.txt index f0b8e41ce..f45384d4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,11 +82,6 @@ if(SHERPA_ONNX_ENABLE_PYTHON AND NOT BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) endif() -if(SHERPA_ONNX_ENABLE_JNI AND NOT BUILD_SHARED_LIBS) - message(STATUS "Set BUILD_SHARED_LIBS to ON since SHERPA_ONNX_ENABLE_JNI is ON") - set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) -endif() - if(SHERPA_ONNX_ENABLE_GPU) message(WARNING "\ Compiling for NVIDIA GPU is enabled. Please make sure cudatoolkit @@ -157,7 +152,7 @@ message(STATUS "SHERPA_ONNX_USE_PRE_INSTALLED_ONNXRUNTIME_IF_AVAILABLE ${SHERPA_ message(STATUS "SHERPA_ONNX_ENABLE_SANITIZER: ${SHERPA_ONNX_ENABLE_SANITIZER}") message(STATUS "SHERPA_ONNX_BUILD_C_API_EXAMPLES: ${SHERPA_ONNX_BUILD_C_API_EXAMPLES}") -if(BUILD_SHARED_LIBS) +if(BUILD_SHARED_LIBS OR SHERPA_ONNX_ENABLE_JNI) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/build-android-arm64-v8a.sh b/build-android-arm64-v8a.sh index 7967af018..3d53cc23d 100755 --- a/build-android-arm64-v8a.sh +++ b/build-android-arm64-v8a.sh @@ -1,7 +1,26 @@ #!/usr/bin/env bash set -ex -dir=$PWD/build-android-arm64-v8a +# If BUILD_SHARED_LIBS is ON, we use libonnxruntime.so +# If BUILD_SHARED_LIBS is OFF, we use libonnxruntime.a +# +# In any case, we will have libsherpa-onnx-jni.so +# +# If BUILD_SHARED_LIBS is OFF, then libonnxruntime.a is linked into libsherpa-onnx-jni.so +# and you only need to copy libsherpa-onnx-jni.so to your Android projects. +# +# If BUILD_SHARED_LIBS is ON, then you need to copy both libsherpa-onnx-jni.so +# and libonnxruntime.so to your Android projects +# +if [ -z $BUILD_SHARED_LIBS ]; then + BUILD_SHARED_LIBS=ON +fi + +if [ $BUILD_SHARED_LIBS == ON ]; then + dir=$PWD/build-android-arm64-v8a +else + dir=$PWD/build-android-arm64-v8a-static +fi mkdir -p $dir cd $dir @@ -21,6 +40,9 @@ cd $dir if [ -z $ANDROID_NDK ]; then ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/22.1.7171670 + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/27.0.11718014 + fi # or use # ANDROID_NDK=/star-fj/fangjun/software/android-ndk # @@ -32,6 +54,10 @@ if [ -z $ANDROID_NDK ]; then # Tools -> SDK manager -> Android SDK # and set "Android SDK location" to /Users/fangjun/software/my-android ANDROID_NDK=/Users/fangjun/software/my-android/ndk/22.1.7171670 + + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/Users/fangjun/software/my-android/ndk/27.0.11718014 + fi fi fi @@ -44,17 +70,29 @@ echo "ANDROID_NDK: $ANDROID_NDK" sleep 1 onnxruntime_version=1.17.1 -if [ ! -f $onnxruntime_version/jni/arm64-v8a/libonnxruntime.so ]; then - mkdir -p $onnxruntime_version - pushd $onnxruntime_version - wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip - unzip onnxruntime-android-${onnxruntime_version}.zip - rm onnxruntime-android-${onnxruntime_version}.zip - popd -fi +if [ $BUILD_SHARED_LIBS == ON ]; then + if [ ! -f $onnxruntime_version/jni/arm64-v8a/libonnxruntime.so ]; then + mkdir -p $onnxruntime_version + pushd $onnxruntime_version + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip + unzip onnxruntime-android-${onnxruntime_version}.zip + rm onnxruntime-android-${onnxruntime_version}.zip + popd + fi -export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/arm64-v8a/ -export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/arm64-v8a/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ +else + if [ ! -f ${onnxruntime_version}-static/lib/libonnxruntime.a ]; then + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-arm64-v8a-static_lib-${onnxruntime_version}.zip + unzip onnxruntime-android-arm64-v8a-static_lib-${onnxruntime_version}.zip + rm onnxruntime-android-arm64-v8a-static_lib-${onnxruntime_version}.zip + mv onnxruntime-android-arm64-v8a-static_lib-${onnxruntime_version} ${onnxruntime_version}-static + fi + + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version-static/lib/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version-static/include/ +fi echo "SHERPA_ONNXRUNTIME_LIB_DIR: $SHERPA_ONNXRUNTIME_LIB_DIR" echo "SHERPA_ONNXRUNTIME_INCLUDE_DIR $SHERPA_ONNXRUNTIME_INCLUDE_DIR" @@ -88,24 +126,30 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" -DBUILD_ESPEAK_NG_EXE=OFF \ -DBUILD_ESPEAK_NG_TESTS=OFF \ -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=ON \ + -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \ -DSHERPA_ONNX_ENABLE_PYTHON=OFF \ -DSHERPA_ONNX_ENABLE_TESTS=OFF \ -DSHERPA_ONNX_ENABLE_CHECK=OFF \ -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \ -DSHERPA_ONNX_ENABLE_JNI=$SHERPA_ONNX_ENABLE_JNI \ + -DSHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY=OFF \ -DSHERPA_ONNX_ENABLE_C_API=$SHERPA_ONNX_ENABLE_C_API \ -DCMAKE_INSTALL_PREFIX=./install \ -DANDROID_ABI="arm64-v8a" \ -DANDROID_PLATFORM=android-21 .. + # By default, it links to libc++_static.a + # -DANDROID_STL=c++_shared \ + # Please use -DANDROID_PLATFORM=android-27 if you want to use Android NNAPI # make VERBOSE=1 -j4 make -j4 make install/strip -cp -fv $onnxruntime_version/jni/arm64-v8a/libonnxruntime.so install/lib +cp -fv $onnxruntime_version/jni/arm64-v8a/libonnxruntime.so install/lib 2>/dev/null || true +rm -rf install/share rm -rf install/lib/pkgconfig +rm -rf install/lib/lib*.a # To run the generated binaries on Android, please use the following steps. # diff --git a/build-android-armv7-eabi.sh b/build-android-armv7-eabi.sh index 390f5a844..e9a8487fa 100755 --- a/build-android-armv7-eabi.sh +++ b/build-android-armv7-eabi.sh @@ -1,7 +1,26 @@ #!/usr/bin/env bash set -ex -dir=$PWD/build-android-armv7-eabi +# If BUILD_SHARED_LIBS is ON, we use libonnxruntime.so +# If BUILD_SHARED_LIBS is OFF, we use libonnxruntime.a +# +# In any case, we will have libsherpa-onnx-jni.so +# +# If BUILD_SHARED_LIBS is OFF, then libonnxruntime.a is linked into libsherpa-onnx-jni.so +# and you only need to copy libsherpa-onnx-jni.so to your Android projects. +# +# If BUILD_SHARED_LIBS is ON, then you need to copy both libsherpa-onnx-jni.so +# and libonnxruntime.so to your Android projects +# +if [ -z $BUILD_SHARED_LIBS ]; then + BUILD_SHARED_LIBS=ON +fi + +if [ $BUILD_SHARED_LIBS == ON ]; then + dir=$PWD/build-android-armv7-eabi +else + dir=$PWD/build-android-armv7-eabi-static +fi mkdir -p $dir cd $dir @@ -21,6 +40,9 @@ cd $dir if [ -z $ANDROID_NDK ]; then ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/22.1.7171670 + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/27.0.11718014 + fi # or use # ANDROID_NDK=/star-fj/fangjun/software/android-ndk # @@ -32,6 +54,10 @@ if [ -z $ANDROID_NDK ]; then # Tools -> SDK manager -> Android SDK # and set "Android SDK location" to /Users/fangjun/software/my-android ANDROID_NDK=/Users/fangjun/software/my-android/ndk/22.1.7171670 + + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/Users/fangjun/software/my-android/ndk/27.0.11718014 + fi fi fi @@ -45,17 +71,29 @@ sleep 1 onnxruntime_version=1.17.1 -if [ ! -f $onnxruntime_version/jni/armeabi-v7a/libonnxruntime.so ]; then - mkdir -p $onnxruntime_version - pushd $onnxruntime_version - wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip - unzip onnxruntime-android-${onnxruntime_version}.zip - rm onnxruntime-android-${onnxruntime_version}.zip - popd -fi +if [ $BUILD_SHARED_LIBS == ON ]; then + if [ ! -f $onnxruntime_version/jni/armeabi-v7a/libonnxruntime.so ]; then + mkdir -p $onnxruntime_version + pushd $onnxruntime_version + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip + unzip onnxruntime-android-${onnxruntime_version}.zip + rm onnxruntime-android-${onnxruntime_version}.zip + popd + fi + + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/armeabi-v7a/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ +else + if [ ! -f ${onnxruntime_version}-static/lib/libonnxruntime.a ]; then + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-armeabi-v7a-static_lib-${onnxruntime_version}.zip + unzip onnxruntime-android-armeabi-v7a-static_lib-${onnxruntime_version}.zip + rm onnxruntime-android-armeabi-v7a-static_lib-${onnxruntime_version}.zip + mv onnxruntime-android-armeabi-v7a-static_lib-${onnxruntime_version} ${onnxruntime_version}-static + fi -export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/armeabi-v7a/ -export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version-static/lib/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version-static/include/ +fi echo "SHERPA_ONNXRUNTIME_LIB_DIR: $SHERPA_ONNXRUNTIME_LIB_DIR" echo "SHERPA_ONNXRUNTIME_INCLUDE_DIR $SHERPA_ONNXRUNTIME_INCLUDE_DIR" @@ -89,18 +127,25 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" -DBUILD_ESPEAK_NG_EXE=OFF \ -DBUILD_ESPEAK_NG_TESTS=OFF \ -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=ON \ + -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \ -DSHERPA_ONNX_ENABLE_PYTHON=OFF \ -DSHERPA_ONNX_ENABLE_TESTS=OFF \ -DSHERPA_ONNX_ENABLE_CHECK=OFF \ -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \ -DSHERPA_ONNX_ENABLE_JNI=$SHERPA_ONNX_ENABLE_JNI \ + -DSHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY=OFF \ -DSHERPA_ONNX_ENABLE_C_API=$SHERPA_ONNX_ENABLE_C_API \ -DCMAKE_INSTALL_PREFIX=./install \ -DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \ -DANDROID_PLATFORM=android-21 .. + + # By default, it links to libc++_static.a + # -DANDROID_STL=c++_shared \ + # make VERBOSE=1 -j4 make -j4 make install/strip -cp -fv $onnxruntime_version/jni/armeabi-v7a/libonnxruntime.so install/lib +cp -fv $onnxruntime_version/jni/armeabi-v7a/libonnxruntime.so install/lib 2>/dev/null || true +rm -rf install/share rm -rf install/lib/pkgconfig +rm -rf install/lib/lib*.a diff --git a/build-android-x86-64.sh b/build-android-x86-64.sh index 3743842cc..9422086c9 100755 --- a/build-android-x86-64.sh +++ b/build-android-x86-64.sh @@ -1,7 +1,26 @@ #!/usr/bin/env bash set -ex -dir=$PWD/build-android-x86-64 +# If BUILD_SHARED_LIBS is ON, we use libonnxruntime.so +# If BUILD_SHARED_LIBS is OFF, we use libonnxruntime.a +# +# In any case, we will have libsherpa-onnx-jni.so +# +# If BUILD_SHARED_LIBS is OFF, then libonnxruntime.a is linked into libsherpa-onnx-jni.so +# and you only need to copy libsherpa-onnx-jni.so to your Android projects. +# +# If BUILD_SHARED_LIBS is ON, then you need to copy both libsherpa-onnx-jni.so +# and libonnxruntime.so to your Android projects +# +if [ -z $BUILD_SHARED_LIBS ]; then + BUILD_SHARED_LIBS=ON +fi + +if [ $BUILD_SHARED_LIBS == ON ]; then + dir=$PWD/build-android-x86-64 +else + dir=$PWD/build-android-x86-64-static +fi mkdir -p $dir cd $dir @@ -21,6 +40,9 @@ cd $dir if [ -z $ANDROID_NDK ]; then ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/22.1.7171670 + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/star-fj/fangjun/software/android-sdk/ndk/27.0.11718014 + fi # or use # ANDROID_NDK=/star-fj/fangjun/software/android-ndk # @@ -32,6 +54,10 @@ if [ -z $ANDROID_NDK ]; then # Tools -> SDK manager -> Android SDK # and set "Android SDK location" to /Users/fangjun/software/my-android ANDROID_NDK=/Users/fangjun/software/my-android/ndk/22.1.7171670 + + if [ $BUILD_SHARED_LIBS == OFF ]; then + ANDROID_NDK=/Users/fangjun/software/my-android/ndk/27.0.11718014 + fi fi fi @@ -45,17 +71,29 @@ sleep 1 onnxruntime_version=1.17.1 -if [ ! -f $onnxruntime_version/jni/x86_64/libonnxruntime.so ]; then - mkdir -p $onnxruntime_version - pushd $onnxruntime_version - wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip - unzip onnxruntime-android-${onnxruntime_version}.zip - rm onnxruntime-android-${onnxruntime_version}.zip - popd -fi +if [ $BUILD_SHARED_LIBS == ON ]; then + if [ ! -f $onnxruntime_version/jni/x86_64/libonnxruntime.so ]; then + mkdir -p $onnxruntime_version + pushd $onnxruntime_version + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-${onnxruntime_version}.zip + unzip onnxruntime-android-${onnxruntime_version}.zip + rm onnxruntime-android-${onnxruntime_version}.zip + popd + fi + + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/x86_64/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ +else + if [ ! -f ${onnxruntime_version}-static/lib/libonnxruntime.a ]; then + wget -c -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v${onnxruntime_version}/onnxruntime-android-x86_64-static_lib-${onnxruntime_version}.zip + unzip onnxruntime-android-x86_64-static_lib-${onnxruntime_version}.zip + rm onnxruntime-android-x86_64-static_lib-${onnxruntime_version}.zip + mv onnxruntime-android-x86_64-static_lib-${onnxruntime_version} ${onnxruntime_version}-static + fi -export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version/jni/x86_64/ -export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version/headers/ + export SHERPA_ONNXRUNTIME_LIB_DIR=$dir/$onnxruntime_version-static/lib/ + export SHERPA_ONNXRUNTIME_INCLUDE_DIR=$dir/$onnxruntime_version-static/include/ +fi echo "SHERPA_ONNXRUNTIME_LIB_DIR: $SHERPA_ONNXRUNTIME_LIB_DIR" echo "SHERPA_ONNXRUNTIME_INCLUDE_DIR $SHERPA_ONNXRUNTIME_INCLUDE_DIR" @@ -89,20 +127,27 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" -DBUILD_ESPEAK_NG_EXE=OFF \ -DBUILD_ESPEAK_NG_TESTS=OFF \ -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=ON \ + -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \ -DSHERPA_ONNX_ENABLE_PYTHON=OFF \ -DSHERPA_ONNX_ENABLE_TESTS=OFF \ -DSHERPA_ONNX_ENABLE_CHECK=OFF \ -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \ -DSHERPA_ONNX_ENABLE_JNI=$SHERPA_ONNX_ENABLE_JNI \ + -DSHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY=OFF \ -DCMAKE_INSTALL_PREFIX=./install \ -DANDROID_ABI="x86_64" \ -DSHERPA_ONNX_ENABLE_C_API=$SHERPA_ONNX_ENABLE_C_API \ -DSHERPA_ONNX_ENABLE_WEBSOCKET=OFF \ -DANDROID_PLATFORM=android-21 .. + # By default, it links to libc++_static.a + # -DANDROID_STL=c++_shared \ + # make VERBOSE=1 -j4 make -j4 make install/strip -cp -fv $onnxruntime_version/jni/x86_64/libonnxruntime.so install/lib + +cp -fv $onnxruntime_version/jni/x86_64/libonnxruntime.so install/lib 2>/dev/null || true +rm -rf install/share rm -rf install/lib/pkgconfig +rm -rf install/lib/lib*.a diff --git a/build-android-x86.sh b/build-android-x86.sh index f37f84c4e..bf146352f 100755 --- a/build-android-x86.sh +++ b/build-android-x86.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash set -ex +if [ x$BUILD_SHARED_LIBS == xOFF ]; then + echo "BUILD_SHARED_LIBS=OFF is ignored for Android x86." + echo "Always link with libonnxruntime.so" + sleep 2 +fi + dir=$PWD/build-android-x86 mkdir -p $dir diff --git a/sherpa-onnx/jni/CMakeLists.txt b/sherpa-onnx/jni/CMakeLists.txt index 23544c177..d761bf4e0 100644 --- a/sherpa-onnx/jni/CMakeLists.txt +++ b/sherpa-onnx/jni/CMakeLists.txt @@ -39,7 +39,7 @@ if(SHERPA_ONNX_ENABLE_SPEAKER_DIARIZATION) ) endif() -add_library(sherpa-onnx-jni ${sources}) +add_library(sherpa-onnx-jni SHARED ${sources}) target_compile_definitions(sherpa-onnx-jni PRIVATE SHERPA_ONNX_BUILD_SHARED_LIBS=1) target_compile_definitions(sherpa-onnx-jni PRIVATE SHERPA_ONNX_BUILD_MAIN_LIB=1)