Termux Packages 构建系统完全指南:从包配方到多仓库发布机制
【免费下载链接】termux-packagesA package build system for Termux.项目地址: https://gitcode.com/GitHub_Trending/te/termux-packages
本篇技术指南以 README.md 为核心脉络,系统讲解 Termux 官方软件包构建系统 termux-packages 的整体架构、仓库布局、包配方(package recipe)编写规范与多仓库发布机制。你将掌握如何阅读build.sh配方、理解 packages / x11-packages / root-packages 三类仓库的划分逻辑、按打包政策提交新包,以及版本更新、补丁制作、重建与降级等完整实操流程。
项目定位:为 Termux 构建 Android 软件包
termux-packages是一个为 Termux Android 应用构建软件包的脚本与补丁集合。正如 README.md 所述,它不直接提供软件本体,而是提供一整套“把开源软件编译成可在 Termux 环境运行的.deb包”的自动化工程——包括每个包的构建配方、针对 Android 环境的补丁、NDK 补丁以及 Docker 构建环境。
值得强调的是,Termux 并非标准 Linux 平台:所有软件均由 Android NDK 编译,且 Android(尤其是 Termux)存在大量与传统 FHS(Filesystem Hierarchy Standard)不同的路径约定,因此仓库中的包配方不能简单照搬主流发行版的打包方式(详见 CONTRIBUTING.md 中 “Working with packages” 一节)。
仓库结构:四大包目录与支撑目录
从仓库根目录可以清楚看到构建系统的组织方式:
| 目录 | 用途 |
|---|---|
| packages/ | 主仓库(termux-main)的包配方,面向普通非 root 用户,数量超过 1000 个 |
| x11-packages/ | 图形界面(X11 / Wayland)相关包的配方,对应 termux-x11 仓库 |
| root-packages/ | 需要 root 权限或依赖 SELinux permissive 模式、自定义固件的包,对应 termux-root 仓库 |
| disabled-packages/ | 因构建失败、上游废弃等原因被禁用的包配方存档 |
| ndk-patches/ | 对 Android NDK 头文件与库的修正补丁(如langinfo.h、libintl.h) |
| scripts/ | 构建系统核心脚本、Docker 环境与各类辅助工具 |
| sample/ | 新包配方的骨架模板 |
| repo.json | 定义各软件源仓库的元数据(名称、发行版、组件、URL) |
repo.json:三个软件源的元数据定义
repo.json 是理解“多仓库机制”的关键配置文件,它声明了三个独立的 APT 软件源:
{ "pkg_format": "debian", "packages": { "name": "termux-main", "distribution": "stable", "component": "main", "url": "https://packages-cf.termux.dev/apt/termux-main" }, "root-packages": { "name": "termux-root", "distribution": "root", "component": "stable", "url": "https://packages-cf.termux.dev/apt/termux-root" }, "x11-packages": { "name": "termux-x11", "distribution": "x11", "component": "main", "url": "https://packages-cf.termux.dev/apt/termux-x11" } }三个仓库分别对应packages/、root-packages/、x11-packages/三个目录,包格式统一为 Debian(.deb),通过 APT 系列工具(apt/pkg)安装管理。这种划分使得“普通终端工具”“需要 root 的软件”“图形界面软件”三类内容互不干扰,也与 CONTRIBUTING.md 中“Termux 主要面向非 root 使用”的设计原则一致。
一个真实配方示例:hello
每个包通过./packages/<name>/build.sh定义,文件名即包名。以 packages/hello/build.sh 为例:
TERMUX_PKG_HOMEPAGE=https://www.gnu.org/software/hello/ TERMUX_PKG_DESCRIPTION="Prints a friendly greeting" TERMUX_PKG_LICENSE="GPL-3.0" TERMUX_PKG_MAINTAINER="@termux" TERMUX_PKG_VERSION="2.12.3" TERMUX_PKG_REVISION=1 TERMUX_PKG_SRCURL=https://mirrors.kernel.org/gnu/hello/hello-${TERMUX_PKG_VERSION}.tar.gz TERMUX_PKG_SHA256=0d5f60154382fee10b114a1c34e785d8b1f492073ae2d3a6f7b147687b366aa0 TERMUX_PKG_DEPENDS="libiconv" TERMUX_PKG_AUTO_UPDATE=true TERMUX_PKG_BUILD_IN_SRC=true termux_step_pre_configure() { LDFLAGS+=" -liconv" }该配方展示了核心变量(版本、源码 URL、SHA-256 校验和、运行时依赖)以及termux_step_pre_configure()函数对默认构建步骤的覆写——这里在链接阶段追加-liconv。构建脚本 build-package.sh 会按预定义步骤执行下载、校验、打补丁、配置、编译、打包全流程。
包配方 build.sh 核心变量速查
CONTRIBUTING.md 的 “Basics” 一节给出了最小配方模板:
TERMUX_PKG_HOMEPAGE=https://example.com TERMUX_PKG_DESCRIPTION="Termux package" TERMUX_PKG_LICENSE="GPL-3.0" TERMUX_PKG_MAINTAINER="@github" TERMUX_PKG_VERSION=1.0 TERMUX_PKG_SRCURL=https://example.com/sources-${TERMUX_PKG_VERSION}.tar.gz TERMUX_PKG_SHA256=0000000000000000000000000000000000000000000000000000000000000000 TERMUX_PKG_DEPENDS="libiconv, ncurses"各变量含义与约束如下:
TERMUX_PKG_VERSION:版本号必须以数字开头,只能包含.、-、+,仅在指定 epoch 时允许冒号(如1:2.6.0)。若使用特定 Git 提交,则必须用YYYY.MM.DD或YYYYMMDD格式的提交日期作为版本,严禁用 Git hash 或分支名。TERMUX_PKG_SRCURL:只能指向官方源码包,且必须保证与TERMUX_PKG_VERSION、TERMUX_PKG_SHA256严格对应。不要硬编码版本号,应通过${TERMUX_PKG_VERSION}变量引用;Bash 的切片语法可用于处理带 epoch 的版本,例如${TERMUX_PKG_VERSION:2}。TERMUX_PKG_SHA256:源码包的 SHA-256 校验和,构建系统会下载后校验,防止内容与版本不匹配。TERMUX_PKG_DEPENDS:仅包含运行时依赖。所有仅构建期需要的依赖(如静态库)应放入TERMUX_PKG_BUILD_DEPENDS。常见构建工具(autoconf、automake、bison、clang、ndk-sysroot等)无需也不能写进依赖。TERMUX_PKG_LICENSE:使用 SPDX 标识符,或以逗号分隔多个许可证;特殊值custom、non-free可用。TERMUX_PKG_BUILD_IN_SRC=true:仅支持源码树内构建的项目(如纯 Makefile 项目)启用。TERMUX_PKG_PLATFORM_INDEPENDENT=true:标记平台无关包,可在任意 CPU 架构设备上运行。TERMUX_PKG_REVISION:版本不变时的重建序号(详见下文“重建”一节)。TERMUX_PKG_MAINTAINER:维护者标识,惯例为@用户名格式。
子包拆分:sample 模板
大型包可拆分为多个子包。sample/sample-sub.subpackage.sh 提供了子包配方的骨架,只需重命名并填写:
TERMUX_SUBPKG_DESCRIPTION="" TERMUX_SUBPKG_INCLUDE=""其中TERMUX_SUBPKG_INCLUDE指定子包应包含的文件列表,用于把文档、开发头文件、独立二进制等拆到不同子包,缩小主包体积。
Termux 路径约定与补丁中的占位符
Android 上不存在标准 FHS 路径,Termux 使用带前缀的虚拟 rootfs。补丁中凡涉及以下路径,都必须使用占位符(补丁在应用前会做预处理替换):
| 原路径 | 替换为 |
|---|---|
前缀(/usr等) | @TERMUX_PREFIX@(即/data/data/com.termux/files/usr) |
家目录(/home) | @TERMUX_HOME@(即/data/data/com.termux/files/home) |
/run | @TERMUX_PREFIX@/var/run |
/sbin | @TERMUX_PREFIX@/bin |
源码常硬编码的/bin、/etc、/home、/run、/sbin、/tmp、/usr、/var这些路径在 Termux 中均不存在,必须通过补丁替换为上述带前缀的等价路径。
补丁制作规范
使用 git diff 生成补丁(推荐)
按 CONTRIBUTING.md 的指引,大多数情况下用git diff生成补丁更简单:
# 1. 克隆上游源码仓库 git clone https://github.com/curl/curl # 2. 检出最新发布标签(可用 git describe 查看最近标签) cd curl git describe git checkout curl-8_12_1 # 3. 修改源码 vim sourcefile.c # 4. 生成补丁文件 git diff > /path/to/package-build/example.patch若一次制作多个补丁,建议保存一个补丁后执行git reset HEAD --hard,或将文件/目录名作为参数传给git diff以限制范围,避免不同补丁内容重叠。
使用 GNU diff 生成补丁
对于不使用 Git 或对发布包有额外改动的项目,可退回到diff -uNr:
cd ./packages/your-package (source build.sh 2>/dev/null; curl -LO "$TERMUX_PKG_SRCURL") tar xf package-1.0.tar.gz cp -a package-1.0 package-1.0.mod cd package-1.0.mod vim sourcefile.c cd .. diff -uNr package-1.0 package-1.0.mod > very-nice-improvement.patch补丁文件命名应自描述(让人一眼看出修了什么),且每项修改建议单独存放一个补丁文件。整个仓库中遍布的*.patch文件(如 packages/htop/ 等目录下)即为这套规范的实际产物。
包版本更新流程
常规更新
大多数情况下更新包只需改几个变量并提交:
- 为
TERMUX_PKG_VERSION赋新版本号,注意不要误删 epoch 前缀(如1:、2:)。 - 若存在
TERMUX_PKG_REVISION变量则删除它(revision 只在同一版本内多次构建时使用)。 - 下载源码并计算 SHA-256:
cd ./packages/${YOUR_PACKAGE} (source build.sh 2>/dev/null; curl -LO "$TERMUX_PKG_SRCURL") - 将新校验和写入
TERMUX_PKG_SHA256。
重建(revision bump)
仅修改补丁或构建选项、版本号不变时,需要定义或递增TERMUX_PKG_REVISION使包管理器识别为更新:
TERMUX_PKG_VERSION=1.0 TERMUX_PKG_REVISION=4TERMUX_PKG_REVISION应紧跟在TERMUX_PKG_VERSION下方。若版本号已更新,则须删除该变量。例如 packages/hello/build.sh 中TERMUX_PKG_VERSION="2.12.3"配合TERMUX_PKG_REVISION=1,就是版本不变时重建的实例。
降级与修改版本方案(epoch)
需要降级包或改变版本方案时,须设置或递增 epoch,强制包管理器把新版本视为更新:
TERMUX_PKG_VERSION=1:5.0.0若提交者不是 @termux 协作成员,提交降级 PR 必须附上理由说明,无正当理由的降级会被拒绝。
处理补丁失败
上游大版本改动常导致旧补丁失效。可尝试:
- 若补丁修的是已知上游问题,先检查上游 VCS 是否已修复——若已修复则该补丁可移除。
- 检查失败补丁并手动应用修改(仅在理解源码与补丁改动时进行),再用
diff -uNr package-1.0 package-1.0.mod > 补丁文件.patch重新生成。
常见构建错误
No files in package. Maybe you need to run autoreconf -fi before configuring?:构建系统找不到 Makefile。可尝试设置TERMUX_PKG_BUILD_IN_SRC=true(纯 Makefile 项目),或在termux_step_pre_configure中运行./autogen.sh或autoreconf -fi(Autotools 项目)。No LICENSE file was installed for ...:构建系统找不到许可证文件,需通过TERMUX_PKG_LICENSE_FILE手动指定。
打包政策:新包入仓的准入标准
CONTRIBUTING.md 明确列出了新包必须满足的条件,任何提交 PR 前都应核对:
- 活跃且知名的项目:主流 Linux 发行版中存在的软件更易被收录;不接受过时、死亡或社区不活跃的项目。
- 广泛认可的开放源码许可证:Apache、BSD、GPL、MIT 等;闭源、含二进制组件或 EULA 分发的软件不接收。
- 不通过语言级包管理器安装:能用
cargo、cpan、dotnet tool、gem、npm、pip安装的模块不应打包(Node.js、Perl、Ruby 模块的交叉编译尤为困难)。 - 体积限制:成品包应小于 100 MiB。因为要同时为 aarch64、arm、i686、x86_64 四种 CPU 架构编译,实际磁盘占用是单个
.deb的 4 倍;特殊例外需个别申请。 - 功能不重复:不接收与现有包功能重复的提交,以免稀释有限的维护资源。
- 拒绝破坏性功能:不接受纯粹用于渗透测试、钓鱼、暴力破解、短信/电话轰炸、DDoS、OSINT 等破坏或侵犯隐私用途的包。
补充规则:独立的库包主要对开发者有价值,除非作为其他包的依赖,否则一般不打包;需要 root、依赖 SELinux permissive 模式或自定义固件的包放入 root-packages/ 对应的 termux-root 仓库(如arp-scan、bubblewrap、containerd等),因为 Termux 主要面向非 root 使用,若 root 功能干扰非 root 场景或引发构建问题,维护者可能移除相关功能。
不符合政策但有需求的包,可提交到独立的用户仓库(TUR)。
提交规范:commit 消息格式与类型
CONTRIBUTING.md 要求提交消息描述清楚改动对象与范围,推荐格式:
<commitType>(<repo>/<package>): (改动摘要) [可选但强烈建议的详细说明] [Fixes (termux/repo)#<issue number>] [Closes (termux/repo)#<pr number>]其中<repo>为main、root或x11(对应repo.json中三个仓库,也可按去掉termux-前缀的包目录名确定)。任何行不应超过 80 字符。
常用的 commitType 包括:
| 类型 | 含义 |
|---|---|
addpkg(<repo>/<package>) | 新增包 |
bump(<repo>/<package>) | 更新一个或多个包,摘要应包含新版本号 |
fix(<repo>/<package>) | 修复 Termux 特定 bug |
dwnpkg(<repo>/<package>) | 降级包,需说明理由 |
disable(<repo>/<package>) | 禁用包,摘要应说明原因 |
enhance(<repo>/<package>) | 启用此前未启用的功能 |
chore | 不影响用户的家务性改动 |
rebuild | 为链接新版共享库而重建,如rebuild(deps:main/openssl): link against OpenSSL 3.0 |
scripts(path/to/script) | 修改构建脚本等非配方内容 |
ci(action_file_without_extension) | 修改 GitHub Actions 相关文件 |
典型示例:
bump(main/nodejs): v18.2.0 dwnpkg(main/htop): v2.2.0 v3.x needs access to /proc/stat which is now restricted by Android enhance,bump(main/nodejs): v18.2.0 and use shared libuv构建系统支撑与脚本工具
构建脚本体系
构建的核心由 scripts/ 目录下的脚本驱动,包括 Docker 构建环境(Dockerfile)、环境初始化(setup-termux.sh、setup-ubuntu.sh、setup-archlinux.sh等)、包列表工具与维护脚本:
- list-packages.sh:遍历
packages/*,逐个 source 各包build.sh,输出包名(版本): 主页与描述——直接展示了“配方即数据”的读取方式。 - check-versions.sh、check-built-packages.py、lint-packages.sh:版本检查、已构建包校验与配方静态检查。
- buildorder.py:计算依赖构建顺序。
- run-docker.sh / run-docker.ps1:在 Docker 中启动统一构建环境,保证构建可复现。
新包配方骨架
提交新包时,可参考 sample/ 中的模板(sample-sub.subpackage.sh与sample.alternatives),以及仓库内现有配方的写法;build.sh中还可覆写termux_step_*系列步骤函数(如 hello 配方中的termux_step_pre_configure)以适配特殊构建流程。
结语
termux-packages 是一套完整、严谨的 Android 软件包构建工程:通过build.sh配方声明元数据与构建行为,借助统一的TERMUX_PKG_*变量体系和termux_step_*步骤钩子,在 Docker 环境中将开源软件编译为 Debian 格式的.deb包,并经由repo.json定义的 termux-main、termux-root、termux-x11 三个软件源向数百万用户分发。无论你是想了解 Termux 软件从源码到安装包的完整链路,还是准备提交自己的第一个包配方,都可以从 README.md 出发,结合 CONTRIBUTING.md 的规范、repo.json 的仓库定义与 packages/ 中的真实配方逐步上手。
【免费下载链接】termux-packagesA package build system for Termux.项目地址: https://gitcode.com/GitHub_Trending/te/termux-packages
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考