Go 编译 Android c类型的共享库(动态库)
#!/bin/bash
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/23.1.7779620
# 获取当前脚本所在目录
current_dir=$(cd $(dirname $1); pwd)
foldername=${current_dir##*/}
// 传一个 .go 文件
gofile=$1
funBuildSO(){
# -ldflags 'flag list'
# '-s -w': 压缩编译后的体积
# -s: 去掉符号表
# -w: 去掉调试信息,不能gdb调试了
echo "保存在 output/android/armeabi/$1.so !"
# echo "第二个参数为 $2 !"
export GOARCH=arm
export GOOS=android
export CGO_ENABLED=1
export CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang
go build -ldflags "-w -s" -buildmode=c-shared -o output/android/armeabi-v7a/lib$1.so $2
echo "Build armeabi-v7a 完成"
export GOARCH=arm64
export GOOS=android
export CGO_ENABLED=1
export CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang
go build -ldflags "-w -s" -buildmode=c-shared -o output/android/arm64-v8a/lib$1.so $2
echo "Build arm64-v8a 完成"
export GOARCH=386
export GOOS=android
export CGO_ENABLED=1
export CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang
go build -ldflags "-w -s" -buildmode=c-shared -o output/android/x86/lib$1.so $2
echo "Build x86( 模拟器)完成"
}
if [ -f $1 ]; then
# echo "$1 is a 文件"
funBuildSO $foldername $gofile
fi

# GOARCH=CPU 类型
# GOOS=设备类型
# CGO_ENABLED=1
# CC=ndk 里的 clang,需要是对应 CPU 版本的, API 呢建议是最低
# 这里单独说明一下, 高版本的 ndk 用的是 clang, 低版本用的是 gcc, 这个根据你情况来, 个人建议直接用 21.0.6113669版本, 这个我测试过, 没有问题, ndk20 我也试过, 也是 ok 的
# go build 命令
# -buildmode=c-shared 构建类型, 使用 go help buildmode查看, 安卓一般用c-shared就可以了, 意思就是 c 类型的共享库(动态库)
# -o 后面跟输出的位置, 一般建议使用 libxxx.so 的格式, 相对的, 头文件也会被生成在同一目录下, xxx 就是库的名字, 对应到 Java 里加载库的方法就是System.loadLibrary("xxx") 而不是~~System.loadLibrary("libxxx")~~
# 最后一个就是需要编译的 go 文件了
# CPU 类型和设备类型可以使用go tool dist list查看
# 我这里 1.20.4 包含的 android 对应的是:
# $ go tool dist list|grep android
# android/386 # x86 模拟器
# android/amd64 # 基本没有
# android/arm # v7 老手机
# android/arm64 # v8 新手机