4.7.2、编写规则
1、规范概述
Buildroot
像一个「自动化厨房」,每个包是一道菜。如果菜名(包名)、食材位置(路径)、做法(脚本)不统一,厨房会报错。规范是让机器人(Buildroot
脚本)能读懂你的菜谱。
2、命名规则
-
包目录名(
package/
下的文件夹)小写字母 + 短横线,如
package/my-app
-
配置项名(
Config.in
里的变量)BR2_PACKAGE_
+ 包目录名大写 + 下划线分隔,如BR2_PACKAGE_MY_APP
,和包目录名严格对应(复制粘贴避免拼写错误) -
.mk
文件中的变量- 包名:
PKG_NAME := my-app
(和目录名一致) - 版本:
PKG_VERSION := 1.0
(语义化版本) - 源文件:
PKG_SOURCE := my_app.tar.gz
(建议和包名相关)
- 包名:
-
脚本中的路径
禁止硬编码,比如
/home/user/...
,必须使用Buildroot
内置变量:$(TOPDIR)
:Buildroot
根目录(自动识别)$(TARGET_DIR)
:最终生成的根文件系统目录(如/output/target
)$(BUILD_DIR)
:编译中间目录(如/output/build
)
3、文件结构
buildroot/
└─ package/
└─ my-app/ 包目录(和包名一致)
├─ Config.in 菜单配置(必选)
├─ my-app.mk 构建脚本(必选)
└─ my_app.tar.gz 源文件(可选,本地文件)
4、Config.in
编写(让包出现在菜单里)
config BR2_PACKAGE_MY_APP 配置项名(必须和包目录名对应)
bool "My Qt Application" 菜单显示的名称(用户看到的)
help 帮助说明(按 H 键显示)
这是我自己的 应用,安装到 /usr/bin/panorama
依赖:Qt5 库
- 必须有
config
行:否则make menuconfig
找不到你的包 - 不要用中文:菜单显示可能乱码(虽然 Buildroot 支持,但不建议)
5、.mk
文件编写(核心脚本,分 6 步)
下载源文件 → 编译 → 安装
-
基本信息
PKG_NAME := my-app 包名(和目录名一致) PKG_VERSION := 1.0 版本号 PKG_LICENSE := MIT 许可证(必填,否则警告) PKG_LICENSE_FILES := LICENSE 许可证文件(如果有源文件)
-
源文件位置
-
本地文件(推荐,避免网络问题):
PKG_SITE := $(TOPDIR)/package/my-app 本地目录 PKG_SOURCE := my_app.tar.gz 源文件名
-
远程下载(需网络):
PKG_SITE := http://example.com/packages 下载地址 PKG_SOURCE := my-app-$(PKG_VERSION).tar.gz
-
-
解压命令
define PKG_EXTRACT_CMDS # 创建解压目录(Buildroot 自动管理,无需硬编码路径) mkdir -p $(BUILD_DIR)/my-qt-app-$(PKG_VERSION) # 复制本地文件到编译目录 cp $(PKG_SITE)/$(PKG_SOURCE) $(BUILD_DIR)/ # 解压(注意 .tar.gz 用 xvzf,.tar.xz 用 xvJf) tar -xvzf $(BUILD_DIR)/$(PKG_SOURCE) -C $(BUILD_DIR) endef
-
编译命令(可选)
-
如果是预编译好的二进制文件(如果应用已经是可执行文件):
define PKG_BUILD_CMDS true 跳过编译(写 `true` 避免报错) endef
-
如果需要编译(如 C 代码):
define PKG_BUILD_CMDS $(MAKE) -C $(BUILD_DIR)/my-app-1.0 进入源码目录编译 endef
-
-
安装命令
define PKG_INSTALL_TARGET_CMDS # 创建目标目录(避免因目录不存在报错) mkdir -p $(TARGET_DIR)/usr/bin # 安装文件(-D 自动创建路径,-m 755 设置权限) install -D -m 755 $(BUILD_DIR)/my-qt-app-1.0/panorama $(TARGET_DIR)/usr/bin/panorama endef
-
依赖项
PKG_DEPENDS := qt5-base 依赖的包(如你的程序需要 Qt5)
6、package
变量名规范
6.1、基础元数据后缀(必选 / 常用)
后缀名 | 作用描述 | 示例(以 mypackage 为例) | 注意事项 |
---|---|---|---|
_NAME | 包的唯一标识(小写,无空格) | mypackage_NAME := mypackage | 必须与目录名一致(package/mypackage/mypackage.mk ) |
_VERSION | 版本号(遵循语义化或上游格式) | mypackage_VERSION := 1.2.3 | 支持 git describe 等动态版本(需配合 _SITE_METHOD := git ) |
_SITE | 源代码下载地址(HTTP/FTP/Git) | mypackage_SITE := https://example.com | 优先使用官方源,避免第三方镜像 |
_LICENSE | 许可证(SPDX 标识符) | mypackage_LICENSE := GPL-2.0 | 需与 LICENSES 目录下的文本匹配(可选) |
_LIC_FILES_SCAN | 许可证文件路径(相对于解压目录) | mypackage_LIC_FILES_SCAN := */LICENSE | 自动扫描许可证时使用(非必选) |
6.2、源代码处理后缀(核心)
后缀名 | 作用描述 | 示例 | 场景说明 |
---|---|---|---|
_SOURCE | 源代码压缩包名(含扩展名) | mypackage_SOURCE := mypackage-$(mypackage_VERSION).tar.gz | 配合 _SITE 下载,支持 xz , gz , bz2 等格式 |
_EXTRACT_CMDS | 自定义解压命令(覆盖默认行为) | mypackage_EXTRACT_CMDS := tar -C $@ -xzf ... | 处理特殊压缩格式或加密包时使用 |
_SITE_METHOD | 源代码获取方式(url , git , svn , hg ) | mypackage_SITE_METHOD := git | Git 需配合 _SITE_URL 和 _SITE_TAG (替代 _VERSION ) |
_PATCH_DIR | 补丁目录(相对于 package/mypackage ) | mypackage_PATCH_DIR := patches | 补丁命名需遵循 0001-xxx.patch 格式(按顺序应用) |
_NO_EXTRACT | 跳过解压(用于无需解压的包,如脚本) | mypackage_NO_EXTRACT := y | 需配合 _BUILD_IN_SOURCE := y |
6.3、编译与安装后缀(关键)
后缀名 | 作用描述 | 示例 | 经典场景 |
---|---|---|---|
_BUILD_IN_SOURCE | 在解压目录直接编译(而非 build 子目录) | mypackage_BUILD_IN_SOURCE := y | 适用于 CMake 项目(默认隔离编译) |
_CONFIGURE_CMD | 配置命令(替代默认 ./configure ) | mypackage_CONFIGURE_CMD := ./autogen.sh | 处理需要预处理的项目(如 autotools) |
_CONFIGURE_ARGS | 配置参数(追加到默认参数) | mypackage_CONFIGURE_ARGS := --prefix=/usr | 覆盖默认安装路径($(STAGING_DIR) ) |
_BUILD_CMD | 编译命令(替代默认 make ) | mypackage_BUILD_CMD := make -j$(nproc) | 自定义并行编译参数 |
_INSTALL_CMD | 安装命令(替代默认 make install ) | mypackage_INSTALL_CMD := make DESTDIR=$(TARGET_DIR) install | 明确指定安装目录(避免污染宿主) |
_STRIP_CMD | 二进制瘦身命令(默认自动调用) | mypackage_STRIP_CMD := strip --strip-debug | 针对特殊文件格式(如 WebAssembly) |
6.4、依赖与配置后缀
后缀名 | 作用描述 | 示例 | 注意事项 |
---|---|---|---|
_DEPENDS | 依赖包列表(空格分隔) | mypackage_DEPENDS := host-pkgconfig zlib | 区分 host- (宿主工具)和 target- (目标运行时)依赖 |
_KCONFIG_DEPENDS | 配置菜单依赖(Kconfig 表达式) | mypackage_KCONFIG_DEPENDS := \$(CONFIG_PACKAGE_ZLIB) | 控制包在菜单中的可见性(需与 Config.in 配合) |
_DISABLED | 禁用包(通过配置菜单隐藏) | mypackage_DISABLED := y | 临时禁用,优先级高于 Kconfig 条件 |
_SELECT | 隐式依赖(自动选中其他包) | mypackage_SELECT := packageA packageB | 用于功能捆绑(如 qt5 依赖 qtbase ) |
6.5、高级功能后缀(扩展)
后缀名 | 作用描述 | 示例 | 适用场景 |
---|---|---|---|
_SOVERSION | 共享库版本号(用于动态链接库) | mypackage_SOVERSION := 1 | 需配合 PKG_CONFIG 生成 .pc 文件 |
_TEST_SUITE | 测试套件命令 | mypackage_TEST_SUITE := make check | 仅在 BR2_PACKAGE_mypackage_TEST 启用时执行 |
_AUTORECONF_CMD | 自动生成配置文件(替代 autoreconf ) | mypackage_AUTORECONF_CMD := autoreconf -fi | 处理老旧 autotools 项目 |
_POST_INSTALL_SCRIPT | 安装后脚本(目标根文件系统) | mypackage_POST_INSTALL_SCRIPT := $(call script,post_install) | 用于创建符号链接、初始化配置等 |
_HOST_BUILD_CMDS | 宿主工具编译命令(区分目标和宿主) | mypackage_HOST_BUILD_CMDS := make -C hosttools | 同时生成宿主工具和目标库的场景(如交叉编译工具) |
6.6、特殊约定后缀(官方保留)
后缀名 | 作用描述 | 示例 | 禁止自定义 |
---|---|---|---|
_PKG_DIR | 包目录路径(自动生成:$(TOPDIR)/package/mypackage ) | 无需手动设置 | 内部使用,禁止修改 |
_TARGET_BIN | 目标二进制文件路径(用于 file 检测) | mypackage_TARGET_BIN := /usr/bin/mypkg | 配合 TARGET_CROSS 校验架构兼容性 |
_FINGERPRINT | 源代码指纹(校验完整性) | 自动生成(基于 _SOURCE 和 _VERSION ) | 用于增量下载时的哈希校验 |