为 android编译 luajit库、 交叉编译

时间:20200719

本机环境:iMac2017 macOS11.4

参考:

官方的文档:Use the NDK with other build systems

写在前边:交叉编译跟普通编译类似,无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Makefie 中的规则来编译源码,编译遇到问题多去里边找找线索

使用Docker + ubuntu镜像 编译

1.安装docker

2.拉取ubuntu 镜像, docker pull ubuntu:20.04

3.挂载一个本地目录 用于与Host共享

4.进入容器命令行 切换shell脚本 /bin/bash

5.更新apt: apt update,安装wget : apt install wget

6.选择一个NDK版本,旧版NDK 下载,这里 我下载的是 r21 ,wget https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip

7.安装unzip: apt install unzip

8.解压ndk: unzip android-ndk-r21e-linux-x86_64.zip 默认是解压到 ./android-ndk-r21e

9.保存一下ndk的路径,使用pwd可以查看当前路径 记好ndk 的路径 【当前路径/android-ndk-r21e】

10.下载luajit并解压,我选择的是v2.1.ROLLING这个Tag, wget https://github.com/LuaJIT/LuaJIT/archive/refs/tags/v2.1.ROLLING.zipunzip v2.1.ROLLING.zip

11.进入到v2.1.ROLLING目录:cd v2.1.ROLLING,使用ls -l查看文件列表,可以看到有Makefile,打开稍微看一下可以发现它是$(MAKE) -C src 来编译src目录下的源码,打开src目录,里边也有Makefile,这里就是编译的细节,可以看到 STATIC_CC = $(CROSS)$(CC) ,这里我们可以通过设置CROSS、CC 的值来指定编译工具,接下来我们写个脚本来执行编译

12.新建脚本:touch build_android.sh, 添加执行权限:chmod +x build_android.sh ,

13.安装vim: apt install vim, 编辑脚本:vim build_android.sh

首先要了解一下编译的工具链的选择,位于 $NDK/toolchains/ 目录下,稍后的CROSS 变量设置就是根据这里的三元组(Triple)来指定的,需要根据目标ABI选取:

ABI Triple
armeabi-v7a armv7a-linux-androideabi
arm64-v8a aarch64-linux-android
x86 i686-linux-android
x86-64 x86_64-linux-android

注意: r19 之后 anrdoid 仅提供 clang 交叉编译工具,需要统一使用目录下的 llvm 工具

我们r21编译器位于 $NDK/toolchains/llvm/prebuilt/linux-x86_64/bin,再就是需要确认支持的最小的API等级,一般21就行了

注意:运行要先去 src/Makefile里 把CC= $(DEFAULT_CC)这里修改一下,让它优先使用我们指定的CC:

cpp 复制代码
ifndef CC
CC= $(DEFAULT_CC) #注意这里如果为了美观想要缩进的话不能使用'tab',因为 Makefile里用'tab'缩进会当作是指令来运行 
endif

先编译一个arm64-v8a的试试 ,我们要使用

$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-androideabi21-clang, 完整的脚本 :

cpp 复制代码
NDK=你的ND根目录

API=21
NDKTRIPLE=aarch64-linux-android
NDKBIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin

make CC=clang CROSS=$NDKBIN/$NDKTRIPLE$API-

运行脚本,报错:

网上搜了一下说Error 127 是找不到ar工具,去NDKBIN里边看了一下,除了 clang/clang++ 其它工具的命名都是不带API的,所以Makefile 中所有的 非$(CROSS)$(CC) 格式的变量都要手动指定,先修改Makefile:

TARGET_AR= $(CROSS)ar rcus

TARGET_STRIP= $(CROSS)strip

改为:

ifndef TARGET_AR

TARGET_AR= $(CROSS)ar rcus

endif

ifndef TARGET_STRIP

TARGET_STRIP= $(CROSS)strip

endif

再来是脚本文件,通常Makefile 中都会提供clean命令,用来清理编译的中间文件之类的,我们也把make clean加在脚本里:

bash 复制代码
NDK=你的ND根目录

make clean

API=21
NDKTRIPLE=aarch64-linux-android
NDKBIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin

make CC=clang CROSS=$NDKBIN/$NDKTRIPLE$API- TARGET_AR="$NDKBIN/$NDKTRIPLE-ar rcus" TARGET_STRIP=$NDKBIN/$NDKTRIPLE-strip

运行脚本,成功!

一般来说4个ABI版本的库都是需要的,我们稍微改造一下脚本,把每种都编译出来然后统一放到 build 目录下,有一点需要注意,armeabi-v7a 和 x86 是32位,需要带上 "-m32"参数 ,还有就是 armeabi-v7a 的TARGET_AR/TARGET_STRIP命名的规则跟其他的不太一样:

bash 复制代码
NDK=$NDK_r21_ROOT
NDKBIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
API=21

#当前目录
CUR_PATH=$(
  cd "$(dirname $0)"
  pwd
)

#build目录
BUILD_PATH=$CUR_PATH/build
#每次生成前清理 build目录
rm -rf $BUILD_PATH

#创建目录
makedir() {
  if [ ! -x "$1" ]; then
    mkdir -p "$1"
  fi
}

makedir $BUILD_PATH

#移动lib到build目录下
putto() {
  makedir $1

  if [ -f $CUR_PATH/src/libluajit.a ]; then
    mv $CUR_PATH/src/libluajit.a $1/libluajit.a
  fi
}

# armeabi-v7a
NDKTRIPLE=armv7a-linux-androideabi
make clean
make CC="clang -m32" CROSS=$NDKBIN/$NDKTRIPLE$API- TARGET_AR="$NDKBIN/arm-linux-androideabi-ar rcus" TARGET_STRIP=$NDKBIN/arm-linux-androideabi-strip
putto $BUILD_PATH/armeabi-v7a

# arm64-v8a
NDKTRIPLE=aarch64-linux-android
make clean
make CC=clang CROSS=$NDKBIN/$NDKTRIPLE$API- TARGET_AR="$NDKBIN/$NDKTRIPLE-ar rcus" TARGET_STRIP=$NDKBIN/$NDKTRIPLE-strip
putto $BUILD_PATH/arm64-v8a

# x86
NDKTRIPLE=i686-linux-android
make clean
make CC="clang -m32" CROSS=$NDKBIN/$NDKTRIPLE$API- TARGET_AR="$NDKBIN/$NDKTRIPLE-ar rcus" TARGET_STRIP=$NDKBIN/$NDKTRIPLE-strip
putto $BUILD_PATH/x86

# x86_64
NDKTRIPLE=x86_64-linux-android
make clean
make CC=clang CROSS=$NDKBIN/$NDKTRIPLE$API- TARGET_AR="$NDKBIN/$NDKTRIPLE-ar rcus" TARGET_STRIP=$NDKBIN/$NDKTRIPLE-strip
putto $BUILD_PATH/x86_64
相关推荐
烬奇小云2 小时前
认识一下Unicorn
android·python·安全·系统安全
顾北川_野14 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO14 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他14 小时前
Android ANR分析总结
android
PenguinLetsGo16 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博19 小时前
音频格式转换
android·音视频
音视频牛哥21 小时前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.21 小时前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda
二流小码农21 小时前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos
夏非夏1 天前
Android 生成并加载PDF文件
android