概述
Termux-app是一个Android上的Linux虚拟机工具,它拥有自己的包管理工具和软件源,可以实现很多Linux上的功能。源码地址:https://github.com/termux/termux-app
。
Termux在初始化安装时会从远端下载一个对应系统架构的bootstraps-arch.zip文件,它是一个Linux的基本环境,其目录结构如下:
1 | bootstraps-arch/ |
bootstraps文件跟app的包名所绑定,如果需要将该功能集成到自己的Android项目中,则需要修改包名参数为自己的app包名,指定自定义的软件仓库,然后重新编译bootstraps.zip文件,在Termux-app项目中替换引入。
Compiling packages(termux-packages)
需要在机器上安装docker环境,由于编译termux-packages需要一些系统环境,因此使用docker来完成这个编译过程无疑是一个比较省时间的做法。docker的镜像名为:termux/package-builder
。
获取
https://github.com/termux/termux-packages
仓库修改
termux-packages/scripts/build/termux_step_setup_variables.sh
(最好修改所有的package_name):1
2"${TERMUX_PREFIX:="/data/data/$package_name/files/usr"}"
"${TERMUX_ANDROID_HOME:="/data/data/$package_name/files/home"}"运行docker脚本进入docker容器:
./scripts/run-docker.sh
在容器中开始编译过程:
./build-package.sh -a arch $lib_name
,会在debs目录下生成对应的deb包。我在编译时使用的是
-a
参数值是all
,必需的package可以在编译脚本中看到(下文会提到)。在build的过程中可能会出现依赖包下载失败的问题,可以在网上查找对应的依赖包下载之后放置到某个地方,然后修改对应packages的build.sh脚本参数,使之从自己定义的url出下载依赖包,build.sh的位置在:termux-packages/packages/$package/build.sh
。
Create apt repository
概述
由于termux软件源中的deb包是与包名绑定的,因此如果需要使用软件源则需要自己修改包名后重新编译对应的package包,然后将生成的deb包上传到自己的软件仓库上,本节主要介绍如何搭建一个apt repository
。具体的指引可以参考https://wiki.debian.org/DebianRepository/Setup
中的文档。
以下是我搭建的软件源目录结构:
1 | hearing/ |
- bootstraps目录下放的是最终编译成功的zip文件
- repository是自己制作的软件仓库
- tmp放置的是上一步编译中下载失败的一些依赖
引用
根据https://wiki.debian.org/DebianRepository/Setup
中的说法,仓库分为两种,一种比较简单的是trivial archive,而另外一种复杂的仓库称为official archive。在一个official archive中,典型特征是顶层有个 dists 目录和 pool 目录。这样的好处是:
- 将所有类型CPU的包列表(Packages或者Packages.gz文件)放在一个文件里面,这样每个机器要获取的包列表就比较小。
- 不同套件/不同CPU可共用的deb包(主要是那些 _all.deb)和源代码包,也只在 pool/all目录下存放一份。
- 源代码包(.dsc,orig.tar.xz)有路径存放,这样 dget / apt source 可以取到源代码包。
对应的/etc/apt/sources.list
配置如下:
1 | deb http://192.168.56.47:80/hearing/repository stable main |
配置软件源的格式为:
1 | deb|deb-src uri distribution [component1] [component2] [...] |
生成Packages
Packages文件包括每个deb包的位置,描述,版本等信息,生成命令:
1 | dpkg-scanpackages all/ /dev/null| gzip -9c > dists/stable/main/binary-all/Packages.gz |
生成Release
Release文件里面包含了 Packages 等文件的大小和校验和(包含MD5/SHA1/SHA256/SHA512 多种值),如果这个文件里面所描述的 Packages 大小与校验和与实际读取到的文件不一致,apt 会拒绝这个仓库。生成命令:
1 | apt-ftparchive release $dir > Release |
生成Release.gpg 和 InRelease 文件
Release.gpg 是一个签名文件,随同 Release 一起出现的,比较老的客户端只认这两个文件,而 InRelease 是内嵌签名的(也就是说,将原来 Release 的内容和 Release.gpg 的内容揉到一起了,注意这里不是简单地拼到一起),新的客户端才支持这个这个文件,观察一下 Debian 和 Ubuntu 的仓库 ( http://mirrors.ustc.edu.cn/debian/dists/jessie/, http://mirrors.ustc.edu.cn/ubuntu/dists/xenial/ ) ,可以看到 Debian 的仓库只有 Release 和 Release.gpg 这两个文件,而 Ubuntu 仓库里面这三个文件都有。
如何生成这两个文件:
- 生成自己的gpg key:
gpg --list-keys || gpg --gen-key
- 生成Release.gpg:
gpg --armor --detach-sign --sign -o Release.gpg Release
- 生成InRelease:
gpg --clearsign -o InRelease Release
导入公钥
当运行apt update
的时候,会出现警告:The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 722D2AFAD8BAD548
。
也就是说 InRelease / Release.gpg 虽然签名了,但由于这个签名所用的公钥没有被接受,因此还是不能正常使用,有三种解决方法:
服务端将公钥导出,然后提供给客户端导入:
1
2
3
4
5导出
gpg --export --armor 722D2AFAD8BAD548 -o my-repo.gpg-key.asc
导入
sudo apt-key add my-repo.gpg-key.asc客户端在执行
apt update
的时候,添加--allow-insecure-repositories
选项;在执行apt install pkg
的时候,添加--allow-unauthenticated
选项。用户修改仓库的配置,改为
deb [trusted=yes] http://192.168.56.47:80/hearing/repository stable main
Getting bootstraps(termux-packaging)
- 将获得的deb文件上传到一个
apt repository
- 获取
https://github.com/termux/termux-packaging
仓库 - 在scripts目录下运行:
./generate-bootstraps.sh -p /data/data/$package_name/files/usr -r http://localhost/hearing/repository
- 上传得到的bootstraps.zip文件(可能需要修改bootstraps.zip中的source.list中的软件源)
generate-bootstraps.sh脚本中可以看到需要的依赖包:
1 | Package manager. |
Termux-app
将Termux-app源码中的bootstraps.zip的url替换成我们自己的url。
附录
Java自动将deb文件分目录
1 | import java.io.File; |