为 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选取:

ABITriple
armeabi-v7aarmv7a-linux-androideabi
arm64-v8aaarch64-linux-android
x86i686-linux-android
x86-64x86_64-linux-android

注意: r19 之后 anrdoid 仅提供 clang 交叉编译工具,需要统一使用目录下的 llvm 工具
我们r21编译器位于 $NDK/toolchains/llvm/prebuilt/linux-x86_64/bin,再就是需要确认支持的最小的API等级,一般21就行了

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

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

先编译一个arm64-v8a的试试 ,我们要使用
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-androideabi21-clang, 完整的脚本 :

NDK=你的ND根目录API=21
NDKTRIPLE=aarch64-linux-android
NDKBIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/binmake 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加在脚本里:

NDK=你的ND根目录make cleanAPI=21
NDKTRIPLE=aarch64-linux-android
NDKBIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/binmake 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命名的规则跟其他的不太一样:

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" ]; thenmkdir -p "$1"fi
}makedir $BUILD_PATH#移动lib到build目录下
putto() {makedir $1if [ -f $CUR_PATH/src/libluajit.a ]; thenmv $CUR_PATH/src/libluajit.a $1/libluajit.afi
}# 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssm 学习 ---(spring)

一、spring框架 1、基本框架 2、Beanfactory快速入门 配置清单:xml文件 (1) 导入jar包或者maven坐标 (2) 定义UserService接口以及UserService实现类 (3) 创建bean.xml配置文件,将UserService信息配置到该xml文件中; (4)编写测试代码,创…

ubuntu lxqt触摸屏旋转校准(usb触摸屏、lxqt、ubuntu23.10)

参考文章:https://www.codetd.com/article/5651388 1.查看触摸屏驱动 rootxyy:~# xinput list ⎡ Virtual core pointer id2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id4 [slave pointer (2)…

JVM 在什么情况下会触发垃圾回收?

垃圾回收在JVM中自动进行,通常在以下几种情况下触发: 1. 年轻代满了(Young Generation Full) 当年轻代的Eden区满了时,会触发Minor GC(也称为Young GC)。这是因为新创建的对象首先分配在Eden区…

【音视频】AAC编码器与ffmpeg生成AAC数据

文章目录 前言为什么使用AAC?AAC规格常见的AAC规格规格之间的区别 ffmpeg生成AAC数据 总结 前言 在音频压缩技术不断发展的过程中,AAC(Advanced Audio Coding)编码器因其出色的音质和压缩效率,逐渐成为数字音频领域的…

牛客周赛51:小红走矩阵(二分+bfs)

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 给定nnn \times nnn的矩阵,矩阵中的每个元素都是正整数,小红能当前位于左上角(1,1)(1,1)(1,1),每次可以从 (x,y)(x, y)(x,y) 走到 (x1,y)(x1, y)(…

为了实现接口缓存,专门写了个缓存库 f-cache-memory

问题起因 起因是某次发版之后,服务器接口压力过大,当场宕机,排查之后发现有个接口在首页被调十来次(六七年的老项目了,都是泪呀),后端反馈这个接口的sql很复杂,很耗性能&#xff0c…

如何根据同一行的ID利用R语言对值进行求和

需求:将属于同一分组的对应的值进行求和或者求平均值 #设置工作目录 > getwd() [1] "C:/Users/86150/Documents" > setwd("C:/Users/86150/Desktop/AA2024/RUF") > list.files() #读取文件 >install.packages("readxl")…

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS 1. RoMe1.1 Mesh Initialization / Waypoint Sampling1.2 Optimization1.3 Experiments 2. EMIE-MAP2.1 Road Surface Representation based on Explicit mesh and Implicit Encoding2.2 Optimizing Strategies2.3 Experimen…

python报错RuntimeError: Numpy is not available

–> 141 audio torch.from_numpy(audio) 143 if device is not None: 144 audio audio.to(device) RuntimeError: Numpy is not available 使用python3.9和torch时,自动安装了Numpy2.0,一直报错, 解决方法:pip install nump…

如何在 Linux 中解压 ZIP 文件

ZIP 是一种常用的压缩文件格式,用于存储和传输多个文件。在 Linux 系统中,解压 ZIP 文件非常简单。 使用 unzip 命令 unzip 是一个专用于解压 ZIP 文件的命令行工具。要使用它,请打开终端并输入以下命令: 例如,要解…

SpringBoot整合ElasticSearch的elasticsearch-java出现jakarta.json.spi.JsonProvider报错问题

一、原因 报错内容如下 org.springframework.beans.factory.BeanCreationException: Error creating bean with name esClient defined in class path resource [com/elasticsearch/config/ElasticSearchConfig.class]: Bean instantiation via factory method failed; nes…

springboot怎么使用rides 缓存方法的返回值 完整例子

好的,下面是一个使用Spring Boot和Redis缓存方法返回值的完整示例: 添加依赖:在pom.xml中添加Spring Boot Redis依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> <…

在 CI/CD Pipeline 中实施持续测试的最佳实践!

随着软件开发周期的不断加快&#xff0c;持续集成&#xff08;CI&#xff09;和持续交付/部署&#xff08;CD&#xff09;已经成为现代软件开发的重要组成部分。在这一过程中&#xff0c;持续测试的实施对于确保代码质量、提高发布效率至关重要。本文将详细介绍在CI/CD流水线中…

JVM:JavaAgent技术

文章目录 一、Java工具的介绍二、Java Agent技术1、介绍2、静态加载模式3、动态加载模式 三、搭建java agent静态加载模式环境1、创建maven项目2、编写类和premain方法3、编写MANIFEST.MF文件4、使用maven-assembly-plugin进行打包5、创建Spring Boot应用 一、Java工具的介绍 …

有关css的题目

css样式来源有哪些&#xff1f; 内联样式&#xff1a; <a style"color: red"> </a> 内部样式&#xff1a;<style></style> 外部样式&#xff1a;写在独立的 .css文件中的 浏览器的默认样式 display有哪些属性 none - 不展示 block - 块类型…

基于深度学习的医疗数据分析

基于深度学习的医疗数据分析是将深度学习技术应用于医疗数据处理和分析&#xff0c;以提高疾病诊断、治疗规划、患者监护等方面的效率和准确性。这一领域涵盖了广泛的应用&#xff0c;包括影像分析、电子健康记录&#xff08;EHR&#xff09;处理、基因组数据分析等。以下是对这…

mac数据恢复软件哪个好用 macbook数据恢复专业软件下载 mac数据恢复概率大吗 苹果电脑数据恢复软件哪个好

作为办公的必需品&#xff0c;mac的普及率虽然比不上其他品牌的windows操作系统&#xff0c;但是使用人群也一致居高不下&#xff0c;因此&#xff0c;mac数据丢失的问题也时常发生。当数据丢失以后&#xff0c;如何找回数据成了一大难题。 一、Mac数据恢复概率大吗 一般情况下…

配置mysql8.0.21版本docker-compose启动容器

1. 总览 2 docker-compose.xml配置 version: 3 services:mysql:image: 192.168.188.131:8000/mysqlrestart: alwaysvolumes:- ./data:/var/lib/mysql- ./my.cnf:/etc/mysql/my.cnf- ./mysql-files:/var/lib/mysql-files- ./log/mysql:/var/log/mysqlenvironment:MYSQL_ROOT_PA…

掌握Perl的魔法:深入探索钩子(Hook)机制

掌握Perl的魔法&#xff1a;深入探索钩子&#xff08;Hook&#xff09;机制 在Perl编程语言中&#xff0c;钩子&#xff08;Hook&#xff09;是一种特殊的变量或函数&#xff0c;它们在特定的操作发生时自动触发。钩子可以被视为一种拦截器&#xff0c;允许程序员在程序执行的…

python中使用openpyxl库写一个简单的表格

如果你只需要写一个简单的表格并保存到Excel文件中&#xff0c;那么openpyxl或pandas都是很好的选择。这两个库都支持创建和保存Excel文件&#xff0c;并且使用起来相对简单。 以下是使用openpyxl库创建一个简单表格并保存到Excel文件的示例&#xff1a; from openpyxl impor…