ohos-m4 是为 OpenHarmony 平台编译的 m4 宏处理器。本文档详细介绍如何在鸿蒙PC上安装和使用官方适配完成的 m4 工具,包括 HNP 包的打包、安装和使用方法。
📋 目录
- 一、项目概述
- [二、为什么需要 HNP 包](#二、为什么需要 HNP 包)
- [三、HNP 包打包方法](#三、HNP 包打包方法)
- 四、安装与使用
- 五、使用示例
- 六、常见问题
- 七、总结与最佳实践
- 八、参考资料
一、项目概述
1.1 m4 工具简介
m4 是一个强大的宏处理器,由 Brian Kernighan 和 Dennis Ritchie 开发。它是 Unix/Linux 系统中重要的文本处理工具,被广泛用于构建系统、配置文件生成和代码模板处理。
核心特性:
- 🔤 宏处理:支持宏定义、展开、条件判断等高级功能
- 📝 文本生成:可以生成复杂的配置文件、代码文件等
- 🔧 跨平台:支持多种操作系统和平台
- 🎯 构建系统基础:是 autoconf、automake 等构建工具的基础依赖
- ⚡ 轻量高效:体积小,处理速度快
主要应用场景:
- 构建系统配置(autoconf、automake)
- 配置文件模板处理
- 代码生成和模板化
- 文本处理和转换
- 与 autotools 工具链配合使用

1.2 项目信息
| 项目信息 | 详情 |
|---|---|
| 项目名称 | ohos-m4 |
| 版本 | 1.4.20(官方适配版本) |
| 许可证 | GPL-3.0+ |
| 目标平台 | 鸿蒙PC (aarch64-linux-ohos) |
| 源码仓库 | https://www.gnu.org/software/m4/ |
| 适配仓库 | https://github.com/Harmonybrew/ohos-m4 |
| 预构建包 | https://github.com/Harmonybrew/ohos-m4/releases |
| 编译方式 | 交叉编译(在 Linux x64 上) |
1.3 m4 与其他工具的区别
| 特性 | m4 | ruby | ninja |
|---|---|---|---|
| 类型 | 宏处理器 | 编程语言解释器 | 构建工具 |
| 依赖 | 静态链接,零依赖 | 需要 openssl、yaml 等 | 静态链接,零依赖 |
| 编译方式 | 交叉编译(在 Linux/macOS 上) | 本地编译(在鸿蒙容器中) | 交叉编译(在 Linux/macOS 上) |
| 可执行文件 | 仅 m4 一个 | ruby、irb、gem 等多个 | 仅 ninja 一个 |
| 使用场景 | 宏处理和文本生成 | 运行 Ruby 脚本、开发应用 | 执行构建任务 |
| 构建系统角色 | 构建系统的基础工具 | 独立运行环境 | 构建执行器 |
1.4 为什么需要 ohos-m4?
在鸿蒙PC上进行开发时,我们经常需要:
- ✅ 构建系统支持:许多开源项目使用 autoconf/automake,需要 m4 作为基础工具
- ✅ 配置文件生成:使用 m4 宏处理生成复杂的配置文件
- ✅ 代码模板化:通过 m4 宏实现代码的模板化和生成
- ✅ 工具链完整性:完整的构建工具链需要包含 m4
二、为什么需要 HNP 包
2.1 系统安全限制
重要说明: 在鸿蒙PC上,由于系统安全规格限制等原因,暂不支持通过"解压 + 配 PATH"的方式直接使用 tar.gz 包。
这意味着:
- ❌ 不能直接解压 tar.gz 包到任意目录
- ❌ 不能通过设置 PATH 环境变量来使用
- ✅ 必须打包成 HNP(HarmonyOS Native Package)格式才能正常使用
2.2 HNP 包的优势
HNP 包是鸿蒙PC的官方包管理格式,具有以下优势:
- ✅ 系统集成:与鸿蒙PC的包管理系统集成
- ✅ 安全可靠:通过官方工具安装,符合系统安全规范
- ✅ 易于管理:支持安装、卸载、更新等操作
- ✅ 路径规范 :统一安装在
/data/service/hnp/目录下
2.3 其他平台的使用方式
在鸿蒙开发板上:
- 可以使用 hdc 推送 tar.gz 包
- 支持"解压 + 配 PATH"的方式
在鸿蒙容器中:
- 可以直接下载 tar.gz 包
- 支持"解压 + 配 PATH"的方式
三、HNP 包打包方法
3.1 准备工作
3.1.1 下载预构建包
首先,从 release 页面 下载官方适配完成的预构建包:
bash
# 下载 m4 预构建包
wget https://github.com/Harmonybrew/ohos-m4/releases/download/1.4.20/m4-1.4.20-ohos-arm64.tar.gz
3.1.2 解压并查看结构
bash
# 解压 tar.gz 包
tar -zxf m4-1.4.20-ohos-arm64.tar.gz
# 查看目录结构
tree m4-1.4.20-ohos-arm64/
目录结构示例:
m4-1.4.20-ohos-arm64/
├── bin/
│ └── m4 # m4 可执行文件
├── share/
│ └── info/ # 文档信息
├── COPYING # 许可证文件
└── AUTHORS # 作者信息
3.2 创建 HNP 包配置
3.2.1 创建 hnp.json
在解压后的目录中创建 hnp.json 配置文件:
json
{
"type": "hnp-config",
"name": "m4",
"version": "1.4.20",
"install": {
"links": [
{
"source": "bin/m4",
"target": "m4"
}
]
}
}
配置说明:
type: 固定为"hnp-config"name: 包名称(m4)version: 版本号(1.4.20)install.links: 安装时的符号链接配置source: 源文件路径(相对于安装目录)target: 链接目标名称(命令名称)
3.2.2 准备安装目录结构
按照 HNP 包的路径规则,准备安装目录:
bash
# HNP 包的路径规则:${HNP_PUBLIC_PATH}/<包名>.org/<包名>_<版本号>
# 例如:/data/service/hnp/m4.org/m4_1.4.20
export HNP_PUBLIC_PATH=/data/service/hnp
export M4_INSTALL_PATH=${HNP_PUBLIC_PATH}/m4.org/m4_1.4.20
# 创建安装目录
mkdir -p ${M4_INSTALL_PATH}
3.3 打包脚本
3.3.1 方法一:手动打包
创建打包脚本 pack_hnp.sh:
bash
#!/bin/bash
set -e
# 配置变量
M4_VERSION="1.4.20"
TAR_FILE="m4-${M4_VERSION}-ohos-arm64.tar.gz"
EXTRACT_DIR="m4-${M4_VERSION}-ohos-arm64"
HNP_PUBLIC_PATH="/data/service/hnp"
M4_INSTALL_PATH="${HNP_PUBLIC_PATH}/m4.org/m4_${M4_VERSION}"
OUTPUT_DIR="output"
WORKDIR=$(pwd)
# 创建输出目录
mkdir -p ${OUTPUT_DIR}
# 解压 tar.gz 包
if [ ! -d "${EXTRACT_DIR}" ]; then
echo "解压 ${TAR_FILE}..."
tar -zxf ${TAR_FILE}
fi
# 创建安装目录
echo "创建安装目录..."
mkdir -p ${M4_INSTALL_PATH}
# 复制文件(保留目录结构)
echo "复制文件..."
cp -r ${EXTRACT_DIR}/* ${M4_INSTALL_PATH}/
# 创建 hnp.json
echo "创建 hnp.json..."
cat > ${M4_INSTALL_PATH}/hnp.json << 'EOF'
{
"type": "hnp-config",
"name": "m4",
"version": "1.4.20",
"install": {
"links": [
{
"source": "bin/m4",
"target": "m4"
}
]
}
}
EOF
# 设置执行权限
echo "设置执行权限..."
chmod +x ${M4_INSTALL_PATH}/bin/*
# 使用 hnpcli 打包(如果可用)
if command -v hnpcli &> /dev/null; then
echo "使用 hnpcli 打包..."
hnpcli pack -i ${M4_INSTALL_PATH} -o ${OUTPUT_DIR}/
echo "HNP 包已生成: ${OUTPUT_DIR}/m4.hnp"
else
echo "警告: 未找到 hnpcli 工具,跳过 HNP 包生成"
echo "请手动使用 hnpcli 打包:"
echo " hnpcli pack -i ${M4_INSTALL_PATH} -o ${OUTPUT_DIR}/"
fi
# 生成 tar.gz 包(备用)
echo "生成 tar.gz 包..."
cd ${HNP_PUBLIC_PATH}/m4.org
tar -zcf ${WORKDIR}/${OUTPUT_DIR}/ohos_m4_${M4_VERSION}.tar.gz m4_${M4_VERSION}/
cd - > /dev/null
echo "打包完成!"
echo "输出文件:"
echo " - ${OUTPUT_DIR}/m4.hnp (如果 hnpcli 可用)"
echo " - ${OUTPUT_DIR}/ohos_m4_${M4_VERSION}.tar.gz"
3.4 验证打包结果
打包完成后,验证生成的文件:
bash
# 检查 HNP 包
ls -lh output/m4.hnp
# 检查 tar.gz 包
ls -lh output/ohos_m4_1.4.20.tar.gz
# 验证安装目录结构
tree ${M4_INSTALL_PATH}/
预期的安装目录结构:
/data/service/hnp/m4.org/m4_1.4.20/
├── bin/
│ └── m4 # m4 可执行文件
├── share/
│ └── info/ # 文档信息
├── COPYING # 许可证文件
├── AUTHORS # 作者信息
└── hnp.json # HNP 配置文件
四、安装与使用
4.1 安装 HNP 包
手动安装(使用 tar.gz)
bash
# 在鸿蒙PC上执行
# 1. 解压 tar.gz 包
tar -xzf ohos_m4_1.4.20.tar.gz
# 2. 复制到安装目录
sudo cp -r m4_1.4.20/* /data/service/hnp/m4.org/m4_1.4.20/
# 3. 设置执行权限
sudo chmod +x /data/service/hnp/m4.org/m4_1.4.20/bin/m4
# 4. 创建符号链接(根据 hnp.json 配置)
# hnp 系统会自动处理 links 配置,但也可以手动创建
sudo ln -sf /data/service/hnp/m4.org/m4_1.4.20/bin/m4 /usr/local/bin/m4
4.2 验证安装
bash
# 检查 m4 是否在 PATH 中
which m4
# 检查版本
m4 --version
# 应该输出:m4 (GNU M4) 1.4.20
4.3 配置 PATH(可选)
如果 m4 命令不在 PATH 中,可以手动添加到 PATH:
bash
# 临时添加到 PATH(当前会话有效)
export PATH=$PATH:/data/service/hnp/m4.org/m4_1.4.20/bin
# 永久添加到 PATH(添加到 ~/.bashrc 或 ~/.zshrc)
echo 'export PATH=$PATH:/data/service/hnp/m4.org/m4_1.4.20/bin' >> ~/.bashrc
source ~/.bashrc
五、使用示例
5.1 基本使用
5.1.1 查看帮助
bash
m4 --help
5.1.2 查看版本
bash
m4 --version
# 输出: m4 (GNU M4) 1.4.20
5.1.3 处理简单宏
bash
# 创建一个简单的 m4 文件
cat > example.m4 << 'EOF'
define(`NAME', `World')
Hello, NAME!
EOF
# 使用 m4 处理
m4 example.m4
# 输出: Hello, World!
5.2 宏定义和使用
5.2.1 定义宏
bash
# 创建宏定义文件
cat > macros.m4 << 'EOF'
define(`VERSION', `1.0.0')
define(`AUTHOR', `HarmonyOS Developer')
define(`DATE', `2025-01-01')
EOF
# 使用宏
cat > config.m4 << 'EOF'
include(`macros.m4')
Project: MyProject
Version: VERSION
Author: AUTHOR
Date: DATE
EOF
# 处理文件
m4 config.m4
# 输出:
# Project: MyProject
# Version: 1.0.0
# Author: HarmonyOS Developer
# Date: 2025-01-01
5.2.2 条件判断
bash
# 创建带条件的 m4 文件
cat > conditional.m4 << 'EOF'
define(`DEBUG', `1')
ifelse(DEBUG, `1', `#define DEBUG_MODE 1', `#define DEBUG_MODE 0')
EOF
# 处理文件
m4 conditional.m4
# 输出: #define DEBUG_MODE 1
5.3 与 autoconf 配合使用
5.3.1 生成 configure 脚本
m4 是 autoconf 的基础工具,autoconf 使用 m4 来生成 configure 脚本:
bash
# 在包含 configure.ac 的项目中
# autoconf 会使用 m4 处理宏,生成 configure 脚本
# 示例:如果项目使用 autoconf
cd /path/to/project
autoconf # 内部会调用 m4 处理宏
5.3.2 处理 autoconf 宏
bash
# autoconf 定义的宏示例
cat > test.m4 << 'EOF'
AC_INIT([myproject], [1.0])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
EOF
# 使用 autoconf 处理(内部使用 m4)
# autoconf test.m4
5.4 实际应用场景
场景 1:生成配置文件
bash
# 创建模板文件
cat > config.h.in << 'EOF'
#define VERSION "@VERSION@"
#define PREFIX "@PREFIX@"
#define DATADIR "@DATADIR@"
EOF
# 创建 m4 处理脚本
cat > generate_config.sh << 'EOF'
#!/bin/bash
VERSION="1.0.0"
PREFIX="/usr/local"
DATADIR="${PREFIX}/share"
m4 -DVERSION="${VERSION}" \
-DPREFIX="${PREFIX}" \
-DDATADIR="${DATADIR}" \
config.h.in > config.h
EOF
chmod +x generate_config.sh
./generate_config.sh
场景 2:代码模板化
bash
# 创建函数模板
cat > function.m4 << 'EOF'
define(`FUNCTION', `int $1(int x) {
return x * 2;
}')
EOF
# 生成多个函数
cat > functions.c.m4 << 'EOF'
include(`function.m4')
FUNCTION(`double')
FUNCTION(`triple')
EOF
# 处理生成 C 代码
m4 functions.c.m4 > functions.c
场景 3:批量文本替换
bash
# 创建替换规则
cat > replace.m4 << 'EOF'
define(`OLD_TEXT', `NEW_TEXT')
define(`OLD_NAME', `NEW_NAME')
EOF
# 处理文件
m4 -DOLD_TEXT="Hello" -DOLD_NAME="World" input.txt > output.txt
5.5 高级用法
5.5.1 使用预定义宏
bash
# m4 提供了一些预定义宏
cat > predefined.m4 << 'EOF'
__file__: __file__
__line__: __line__
__program__: __program__
EOF
m4 predefined.m4
# 输出当前文件名、行号和程序名
5.5.2 递归宏展开
bash
# 创建递归宏
cat > recursive.m4 << 'EOF'
define(`COUNTDOWN', `ifelse($1, 0, `0', `$1 COUNTDOWN(decr($1))')')
COUNTDOWN(5)
EOF
m4 recursive.m4
# 输出: 5 4 3 2 1 0
5.5.3 文件包含
bash
# 创建公共宏文件
cat > common.m4 << 'EOF'
define(`PROJECT_NAME', `MyProject')
define(`VERSION', `1.0.0')
EOF
# 在其他文件中包含
cat > main.m4 << 'EOF'
include(`common.m4')
Project: PROJECT_NAME
Version: VERSION
EOF
m4 main.m4
六、常见问题
Q1: 为什么不能直接使用 tar.gz 包?
A: 由于鸿蒙PC的系统安全规格限制,不允许通过"解压 + 配 PATH"的方式直接使用软件包。必须使用 HNP 包格式,通过官方包管理工具安装。
Q2: 如何获取 hnpcli 工具?
A: hnpcli 是鸿蒙PC的包管理工具,通常包含在 OHOS SDK 中。你可以:
Q3: 安装后找不到 m4 命令?
A: 检查以下几点:
- 确认安装路径是否正确:
/data/service/hnp/m4.org/m4_1.4.20/bin/m4 - 检查 PATH 环境变量是否包含该路径
- 检查 hnp.json 中的 links 配置是否正确
- 尝试手动创建符号链接
Q4: 如何卸载 m4?
A: 手动卸载:
bash
# 删除安装目录
sudo rm -rf /data/service/hnp/m4.org/m4_1.4.20
# 删除符号链接
sudo rm -f /usr/local/bin/m4
Q5: 可以在开发板上使用 tar.gz 包吗?
A: 可以。在鸿蒙开发板上,可以使用 hdc 推送 tar.gz 包,然后解压使用:
bash
hdc file send m4-1.4.20-ohos-arm64.tar.gz /data
hdc shell
cd /data
tar -zxf m4-1.4.20-ohos-arm64.tar.gz
export PATH=$PATH:/data/m4-1.4.20-ohos-arm64/bin
Q6: 如何更新到新版本?
A:
- 下载新版本的预构建包
- 按照打包步骤重新打包
- 卸载旧版本:
hnp uninstall m4 - 安装新版本:
hnp install m4.hnp
Q7: m4 处理文件时出错怎么办?
A: 检查以下几点:
- 确认宏定义是否正确
- 检查引号使用是否正确(m4 使用反引号 ` 和单引号 ')
- 查看详细错误信息:
m4 -d example.m4 - 检查文件编码是否为 UTF-8
Q8: m4 与 autoconf 的关系是什么?
A: m4 是 autoconf 的基础工具。autoconf 使用 m4 宏来生成 configure 脚本。当你运行 autoconf 时,它会使用 m4 处理 configure.ac 文件中的宏,生成 configure 脚本。
Q9: 如何从源码构建 m4?
A: 参考项目中的 build.sh 脚本:
- 准备 OHOS SDK 和交叉编译工具链
- 下载 m4 源码
- 应用补丁(适配鸿蒙平台)
- 配置并编译
详细步骤请参考项目 README。
七、总结与最佳实践
7.1 安装最佳实践
- 使用 HNP 包:始终使用 HNP 包格式在鸿蒙PC上安装
- 版本管理:明确指定版本号,避免版本冲突
- 路径规范 :遵循 HNP 包的路径规范:
/data/service/hnp/<包名>.org/<包名>_<版本号>
7.2 使用最佳实践
- 宏命名规范 :使用大写字母和下划线命名宏,如
PROJECT_NAME、VERSION_NUMBER - 引号使用:正确使用反引号 ` 和单引号 ' 来定义和引用宏
- 文件组织 :将公共宏定义放在单独的文件中,使用
include()包含 - 错误处理 :使用
-d参数调试宏展开过程
7.3 与构建系统集成
- autoconf 项目:m4 是 autoconf 的必需依赖,确保在构建环境中可用
- 宏库管理:合理组织 m4 宏库,便于复用和维护
- 版本兼容:注意不同版本的 m4 可能有不同的宏行为
7.4 故障排查
- 查看宏展开 :使用
m4 -d查看详细的宏展开过程 - 检查语法:确认反引号和单引号的使用是否正确
- 验证宏定义 :使用
m4 --trace=MACRO_NAME跟踪特定宏的展开 - 测试隔离:在单独的文件中测试宏定义,确认无误后再集成
📎 附录
A. 📁 文件清单
📦 预构建包:
m4-1.4.20-ohos-arm64.tar.gz- 官方适配完成的预构建包
📝 配置文件:
hnp.json- HNP 包配置文件0001-port-gnulib-to-ohos.patch- 适配鸿蒙平台的补丁文件
📦 生成文件:
m4.hnp- HNP 格式安装包ohos_m4_1.4.20.tar.gz- tar.gz 格式发布包
B. 💻 常用命令
bash
# 打包命令
./pack_hnp.sh
# 安装命令
hnp install m4.hnp
# 验证安装
m4 --version
# 处理 m4 文件
m4 input.m4 > output.txt
# 调试模式
m4 -d input.m4
# 跟踪宏展开
m4 --trace=MACRO_NAME input.m4
C. 📌 版本信息
- 📁 m4 版本: 1.4.20
- 📅 适配日期: 2025-01-15
- 🎯 目标平台: aarch64-linux-ohos
- 🔧 构建系统: autotools (configure + make)
- 📦 包格式: HNP (HarmonyOS Native Package)
- 🔨 编译方式: 交叉编译(需要 OHOS SDK)
🎉 结语
本文档详细介绍了如何在鸿蒙PC上安装和使用官方适配完成的 m4 宏处理器。通过将预构建的 tar.gz 包打包成 HNP 格式,我们可以在鸿蒙PC上安全、规范地使用 m4 工具。
希望本文档能够帮助开发者:
- 📦 理解 HNP 包的必要性和打包方法
- 🔧 掌握 m4 在鸿蒙PC上的安装和使用
- 📚 学习 m4 宏处理的基本用法和高级技巧
- 💻 提升构建系统和代码生成的效率
💬 如有问题或建议,欢迎反馈!