Harmonybrew 项目是一个将 Homebrew 移植到 OpenHarmony 平台的项目,为鸿蒙用户提供开箱即用的包管理器以及配套的软件仓库,支持运行在鸿蒙 PC、鸿蒙开发板、鸿蒙容器等不同形态的鸿蒙设备上。

Harmonybrew 是一个面向 OpenHarmony 生态的独立第三方开源项目,其开发者社区是一个独立的第三方开源社区,与 OpenHarmony 社区以及华为公司均无隶属关系。

设备支持

设备形态代表产品最低系统版本命令行环境架构支持等级
鸿蒙 PCHUAWEI MateBook ProHarmonyOS 6.1.0.117 SP68HiShellarm64Tier 2(低)
鸿蒙开发板dayu200(rk3568)OpenHarmony 6.1hdc shellarm64Tier 1(高)
鸿蒙容器DockerHarmonyOpenHarmony 6.1任意arm64Tier 1(高)

平台兼容性说明

HarmonyOS 作为 OpenHarmony 的商业发行版,理论上可以继承其生态,因此本项目也能在 HarmonyOS 上运行。

但请注意:能运行不代表完美支持。部分软件包在开发板(hdc shell)或容器中表现正常,但在鸿蒙 PC 的 HiShell 环境下,可能会因系统安全限制等因素受限。这属于系统级原生限制,并非项目本身的问题。

安装指南

鸿蒙 PC

1. 卸载冲突软件

如果 PC 中安装有 GitNext 和 DevBox 这两个应用,需将它们卸载。

2. 打开安全开关

进入“设置” -> “系统” -> “开发者选项”,打开“开发者选项”开关。

进入“设置” -> “隐私和安全” -> “高级”,打开“运行来自非应用市场的扩展程序”开关。

如果系统不显示“开发者选项”菜单,则需要通过隐藏开关来开启:打开“设置” -> “关于本机”(即进入“设置”时的默认界面),找到“软件版本”,连续点击 7 次,出现弹窗后点击“确认重启并开启”即可。

3. 安装 Homebrew

在终端中执行这句命令进行安装:

zsh -c "$(curl -fsSL https://harmonybrew.atomgit.com/install.sh)"

4. 配置环境变量

按照安装脚本的提示,执行以下命令,将 Homebrew 加入到 PATH 中:

echo >> ~/.zshrc
echo 'eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"' >> ~/.zshrc
eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"

现在可以开始使用 brew 命令了。

鸿蒙开发板

1. 配置所需目录

Homebrew 运行过程中需要使用 $HOME、/usr/bin、/storage/Users/currentUser 等目录,需要手动配置这些目录:

mount -o remount,rw /
mkdir -p /usr
mkdir -p /data/storage/Users/currentUser
ln -s /bin /usr/bin

# /storage 目录在 tmpfs 上,数据无法持久化,每次重启设备后需要重新创建软链接
ln -s /data/storage/Users /storage/Users

# hdc shell 环境下 HOME 变量默认指向 / 目录,这个目录可用空间很少,需要将其指向一个大容量的目录
# 此配置仅在当前终端有效,每次进入 hdc shell 需要重新设置
export HOME=/storage/Users/currentUser

2. 安装 curl 和 zsh

在上位机(Windows 电脑)下载好鸿蒙版 curl 和鸿蒙版 zsh,并用 hdc 将 tar 包推到设备上。

在设备上解压,把里面的命令软链接到 /usr/bin 目录下:

mount -o remount,rw /
tar -zxf curl-8.19.0-ohos-arm64.tar.gz -C /data
ln -s /data/curl-8.19.0-ohos-arm64/bin/curl /usr/bin/curl
tar -zxf zsh-5.9-ohos-arm64.tar.gz -C /data
ln -s /data/zsh-5.9-ohos-arm64/bin/zsh /usr/bin/zsh

3. 安装 Homebrew

在终端中执行这句命令进行安装(需确保开发板联网):

zsh -c "$(curl -fsSL https://harmonybrew.atomgit.com/install.sh)"

4. 配置环境变量

手动将 Homebrew 加入到 PATH 中:

# 此配置仅在当前终端有效,每次进入 hdc shell 需要重新设置
export PATH=/storage/Users/currentUser/.harmonybrew/bin:$PATH

现在可以开始使用 brew 命令了。

鸿蒙容器

1. 安装 zsh

在容器内通过 curl 下载 zsh,将其软链接到 /usr/bin 目录下:

curl -fLO https://github.com/Harmonybrew/ohos-zsh/releases/download/5.9/zsh-5.9-ohos-arm64.tar.gz
tar -zxf zsh-5.9-ohos-arm64.tar.gz -C /opt
ln -s /opt/zsh-5.9-ohos-arm64/bin/zsh /usr/bin/zsh

2. 安装 Homebrew

在终端中执行这句命令进行安装:

zsh -c "$(curl -fsSL https://harmonybrew.atomgit.com/install.sh)"

3. 配置环境变量

按照安装脚本的提示,执行以下命令,将 Homebrew 加入到 PATH 中:

echo >> ~/.mkshrc
echo 'eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"' >> ~/.mkshrc
eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"

现在可以开始使用 brew 命令了。

常用操作

以下是一些常用的 Homebrew 操作,更多资料请查看 Homebrew 官方文档:

zsh -c "$(curl -fsSL https://harmonybrew.atomgit.com/install.sh)"        # 安装鸿蒙版 Homebrew
zsh -c "$(curl -fsSL https://harmonybrew.atomgit.com/uninstall.sh)"      # 卸载鸿蒙版 Homebrew
brew update                 # 更新 Homebrew 包管理器和包索引
brew formulae               # 列出软件仓库中可用的软件包列表
brew search [keyword]       # 在软件仓库中通过关键词搜索软件包
brew install [formula]      # 安装软件包
brew uninstall [formula]    # 卸载软件包
brew list                   # 查看已安装的软件包列表
brew upgrade [formula]      # 升级指定的软件包
brew upgrade                # 升级所有已安装的软件包
rm -rf $(brew --cache)      # 清除缓存
rm -rf /storage/Users/currentUser/.harmonybrew   # 彻底删除 Homebrew 安装目录(比卸载脚本删得更干净)

注意:Homebrew 是一套“滚动更新”模式的包管理系统,它对软件包版本的维护策略并不同于 Ubuntu 里面的 apt 或 Red Hat 里面的 yum。如果用户从未使用过 Homebrew 或其他滚动更新包管理系统,请先知悉它们的特点,以免使用时造成困惑。

特色软件

Harmonybrew 本该只负责包管理,但为了让用户能顺利地在 OpenHarmony 设备上写起代码,社区做了一些“分外之事”。

针对系统环境的诸多限制(如代码签名、平台标识等),社区专门维护了一系列特色软件包,优化了 C/C++、Rust、Python、Node.js、Go 等场景的开发体验。

社区替用户填平了这些底层的“坑”,只为让 OpenHarmony 上的操作逻辑能重新对齐用户熟悉的 Linux 或 macOS。

软件包列表

名称说明
ohos-sdk社区将 ohos-sdk 也放在软件仓库中分发,用户安装 ohos-sdk 后即可使用 clang、llvm-ar 等命令。另外,社区对 ohos-sdk 里面的 lld 链接器做了简单的脚本封装,默认启用了链接器签名,使得它编出来的程序可以直接在鸿蒙 PC 上运行,无需手动进行代码签名。
llvm-gcc-compat这个包会生成 cc、gcc、ld 等软链接,全部指向 ohos-sdk 里面的 LLVM 工具链。这使社区可以更顺利地编译各种开源软件,无需手动指定 CC、CXX 等环境变量。此做法是模仿 macOS 的做法,macOS 中的 cc、gcc、ld 等命令也是指向 LLVM 的软链接。
devel-base类似于 Debian 里面的 build-essential。这个包本身没有任何内容,只是将 ohos-sdk、llvm-gcc-compat、make、coreutils 等软件包设置成了级联依赖。只要安装这个包,这些级联依赖就会被装进来,用户就拥有了一个较为完善的 C/C++ 编译环境。命名成 devel-base 是为了避免跟各大 Linux 发行版里面的同类软件包重名。
uname-is-linux一个专为鸿蒙 PC 设计的系统标识伪装工具。它通过劫持 libc 中的 uname() 函数,使应用程序获取的系统标识始终为 Linux。详细用法请查看源码仓里面的 README 文档。注意:Harmonybrew 本身以及软件仓库中的软件包并不依赖 uname-is-linux,这个工具仅供有特殊需求的用户自行安装使用,且需要显式调用才能生效。
musl-compat为 OpenHarmony 补充 musl libc 缺失符号的兼容垫片库。当前主要供 python@3.14、python@3.13 等 formula 使用。详细用法请看源码仓里面的 README 文档。

场景演示

场景一:编译 C/C++ 程序

Harmonybrew 软件仓库中有 3 套 C/C++ 编译工具链:

  • ohos-sdk:里面的 LLVM 15 由 OpenHarmony 社区进行深度适配,是 OpenHarmony 生态的官方工具链。
  • llvm + lld:由 Harmonybrew 社区移植。在 Homebrew 生态中,lld 被拆分成独立的软件包,不在 llvm 主包中。
  • gcc + binutils:由 Harmonybrew 社区移植。

社区首推的编译工具链是 ohos-sdk,本文档仅基于 ohos-sdk 进行演示。如果用户需要使用其他工具链,请自行探索。需要注意:这 3 套工具链的产物不能互相链接,也不能在同一进程内混用,否则极易因运行时库冲突引发隐蔽崩溃。

以下是一个在 HiShell 环境中使用 ohos-sdk 搭配辅助包(llvm-gcc-compat、uname-is-linux)编译开源软件 gzip 的示例:

# 安装编译工具链和环境伪装工具(ohos-sdk 和 llvm-gcc-compat 会作为级联依赖被自动引入)
brew install -y devel-base uname-is-linux

# HiShell 环境中,TMPDIR 环境变量的默认值是 /storage/Users/currentUser,这个目录承载在 hmdfs 上
# 修改这个环境变量,将其指向一个非 hmdfs 的目录,避免因 hmdfs 文件系统缺陷导致编译失败
export TMPDIR=/data/storage/el2/base/cache

# 使用非 hmdfs 目录作为工作目录,避免因 hmdfs 文件系统缺陷导致编译失败
WORKDIR=/data/storage/el2/base/files/work
mkdir -p $WORKDIR
cd $WORKDIR

# gzip 安装目录,安装到 currentUser 下,方便用户使用它
PREFIX=/storage/Users/currentUser/gzip-1.14-ohos-arm64

# 启用全局环境伪装
export LD_PRELOAD=$(brew --prefix)/opt/uname-is-linux/lib/libuname.so

# 编译 gzip
curl -fLO https://ftp.gnu.org/gnu/gzip/gzip-1.14.tar.gz
tar -zxf gzip-1.14.tar.gz
cd gzip-1.14
./configure --prefix=$PREFIX  # 无需再显式指定目标平台(如 --host=aarch64-linux 等)
make -j$(nproc)
make install
cd ..

# 编译完成,取消环境伪装
unset LD_PRELOAD

# 验证编出来的 gzip 是否能正常运行
$PREFIX/bin/gzip --help

# 清理临时目录和工作目录
sh -c "rm -rf $TMPDIR/* $WORKDIR/*"

场景二:编译 Rust 程序

用户只需要同时安装 rust 和 llvm-gcc-compat 这两个包,即可享受到开箱即用的 rust 开发体验。

在不配置任何 config.toml 的情况下,rustc 默认会调用 cc 命令作为 linker。llvm-gcc-compat 提供的 cc 命令刚好可以满足这一需求。

这个 cc 命令实际上是个软链接,指向了 ohos-sdk 里面的 clang 驱动器。clang 驱动器在进行链接操作时,调用的是经过社区封装的 ld.lld 脚本,因此最终 rustc 编译出来的二进制都会默认带有代码签名,可直接在鸿蒙 PC 上运行。

在鸿蒙 PC 的 HiShell 环境中编译并运行一个简单的 Rust 程序,操作是这样的:

# 安装 rust 和 llvm-gcc-compat(ohos-sdk 会作为级联依赖被自动引入)
brew install -y rust llvm-gcc-compat

# 创建一个简单的 cargo 工程并将其编译成二进制
cargo new hello_project
cd hello_project
cat > src/main.rs << 'EOF'
fn main() {
    println!("Hello, world!");
}
EOF
cargo build --release

# 测试编译产物是否能正常运行
./target/release/hello_project

如果用户需要使用 nightly 或特定版本的 Rust 工具链,可使用 rustup 安装。Harmonybrew 软件仓库里面的 rustup 是可用的。

场景三:安装 Python 三方库

Harmonybrew 软件仓库里面提供的 python 经过了定制化适配,详情请看 python 的 formula。

Python 官方目前尚未原生支持 aarch64-linux-ohos 平台,为了确保用户能够使用三方库(尤其是包含原生模块的三方库),社区将其平台三元组硬编码为 aarch64-linux-musl。得益于 OpenHarmony 对 Linux 的兼容性,python 可以直接复用 Linux 现有的生态,直接下载并运行 aarch64-linux-musl 平台的原生二进制制品(如 numpy、cryptography 等)。

PyPI 仓库中 aarch64-linux-musl 平台的二进制制品并非为鸿蒙 PC 而构建,因此必然不会具备鸿蒙 PC 的代码签名,不能在鸿蒙 PC 上直接使用。为了解决这个问题,社区对 python 里面的 pip 打了一个自动签名补丁,让它能在安装三方库的时候自动对里面的 so 文件添加代码签名。如此一来,用户在鸿蒙 PC 上就可以正常通过 pip 安装三方库并使用它们。

以 numpy 为例,在鸿蒙 PC 的 HiShell 环境中安装它的完整流程如下:

# 安装 python
brew install -y python

# 激活 venv(Homebrew 里面的 Python 遵循 PEP 668 提案,安装三方库需要激活虚拟环境)
python3 -m venv .venv
source .venv/bin/activate

# 安装 numpy
pip install numpy

# 编写一段 python 脚本,验证 numpy 是否能正常工作
cat <<EOF > test.py
import numpy as np
arr = np.array([1, 2, 3])
print(arr * 2)
EOF

# 执行脚本
python3 test.py

场景四:编译 Node.js addon

在 npm 中心仓中,部分三方库包含 C/C++ addon,如 sqlite3、node-sass、bufferutil 等。

由于极少有官方社区会为 OpenHarmony 平台提供预构建产物,导致这些库在鸿蒙设备上无法开箱即用。所幸的是,大多数 addon 都支持在缺少预构建包时自动回退到本地实时构建。

借助 Harmonybrew 提供的开发工具,用户可以在本地轻松完成这一构建过程,让这些库能够在 OpenHarmony 平台上工作。

以在鸿蒙 PC 的 HiShell 环境中实时构建三方库 bufferutil 为例,流程如下:

# 安装 node 和开发工具(在此场景中 python 也属于开发工具,因为 node-gyp 依赖它)
brew install -y node python devel-base

mkdir test-bufferutil
cd test-bufferutil

# 设置 Node.js 镜像
# node-gyp 会根据这个地址去下载 Node.js 头文件,这里设置成国内源以避免因网络问题下载失败
export npm_package_config_node_gyp_dist_url=https://mirrors.huaweicloud.com/nodejs

# 安装 bufferutil
# 由于 bufferutil 官方未提供 OpenHarmony 平台的预构建包,它会触发实时构建
npm install bufferutil

# 检查实时构建产物是否已经正确生成
# 注意,这个 .node 文件已经默认带有了代码签名(因为是用封装过的 ohos-sdk 工具链进行构建的),
# 所以 Node.js 运行时可以正常加载它
ls -l node_modules/bufferutil/build/Release/bufferutil.node

# 编写一个测试脚本,测试这个库能否正常工作
cat << 'EOF' > test.js
const bufferUtil = require('bufferutil');
const crypto = require('crypto');

const source = crypto.randomBytes(10);
const mask = crypto.randomBytes(4);

console.log(source, mask)
bufferUtil.mask(source, mask, source, 0, source.length);
console.log(source)
bufferUtil.unmask(source, mask);
console.log(source)
EOF

# 执行测试脚本,观察结果
node test.js

提示:该方案仅适用于需要实时构建的场景。对于三方库已经提供了预构建产物但未进行代码签名的场景(如 rollup、rolldown 等),请使用 ohos-signpost 进行处理。具体实践案例可参见这篇博客。

场景五:编译 Go 程序

Harmonybrew 软件仓库中的 go 可以开箱即用,无需进行额外配置。

社区在 go 的 formula 中添加了一个自动签名补丁,使 go 在产出 ELF 二进制文件时自动为产物添加代码签名,编译出来的程序无需手动签名即可直接在鸿蒙 PC 上运行。

在鸿蒙 PC 的 HiShell 环境中编译并运行一个简单的 Go 程序,操作是这样的:

# 安装 go
brew install -y go

mkdir go-example
cd go-example

# 编写一个简单的 Go 程序
cat > hello.go << 'EOF'
package main

import "fmt"

func main() {
    fmt.Println("Hello!")
}
EOF

# 编译并运行
go build -o hello hello.go
./hello

如果用户需要使用 cgo,可额外安装 llvm-gcc-compat,之后 cgo 编译即可开箱即用。

在 cgo 编译场景中,go 默认会调用 cc 命令作为 C 语言编译器和外部链接器。llvm-gcc-compat 提供的 cc 命令刚好可以满足这一需求。

在鸿蒙 PC 的 HiShell 环境中编译并运行一个简单的 cgo 程序,操作是这样的:

# 安装 go 和 llvm-gcc-compat(ohos-sdk 会作为级联依赖被自动引入)
brew install -y go llvm-gcc-compat

mkdir cgo-example
cd cgo-example

# 编写一个 cgo 程序
cat > hello_cgo.go << 'EOF'
package main

/*
#include <stdio.h>
void hello() { printf("%s\n", "Hello from cgo!"); fflush(stdout); }
*/
import "C"

func main() {
    C.hello()
}
EOF

# 编译并运行
CGO_ENABLED=1 go build -o hello_cgo hello_cgo.go
./hello_cgo

常见使用问题与解决

卸载 Homebrew 时,卸载脚本没有自动清理 zshrc

现象描述:

在卸载 Homebrew 后重新打开 HiShell,终端可能会提示报错:no such file or directory: /storage/Users/currentUser/.harmonybrew/bin/brew。

原因分析:

这不是 bug,上游版本(官方 Homebrew)的行为便是如此。

在首次安装 Homebrew 时,用户通常会根据脚本提示,手动向 ~/.zshrc(或 ~/.mkshrc)中添加如下环境变量初始化配置:

eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"

由于该配置项是由用户手动写入(或手动执行命令追加)的,而非安装脚本自动生成的私有配置,Homebrew 的卸载程序不会擅自修改或清理用户的个人 Shell 配置文件。因此,当 Homebrew 被卸载后,残留的 eval 指令因找不到目标文件而报错。

解决方案:

如需彻底清除报错,请手动编辑配置文件:

  1. 打开配置文件:vim ~/.zshrc(或使用偏好的编辑器)。
  2. 删除包含 .harmonybrew 或 brew shellenv 关键字的相关行。
  3. 保存并退出,重新打开终端即可。

通过后装软件包覆盖系统命令后,调用到的仍是系统命令

现象描述:

在鸿蒙 PC 的 HiShell 环境下,通过 Homebrew 安装了与系统重名的软件包(如 curl)后,即便 Homebrew 的 bin 路径已在 PATH 之中,执行命令时仍会调用系统内置版本,而非 Homebrew 安装的版本。

# 场景复现
curl -V              # 调用系统自带 curl
brew install curl    # 安装新版本覆盖
command -v curl      # 返回仍为 /usr/bin/curl

原因分析:

该现象由 Zsh 的 Command Hashing(命令哈希)机制引起,属于 Shell 的正常行为而非故障。

为了优化性能,Zsh 会将首次调用过的命令路径缓存至内部的“命令哈希表”中。当下一次执行相同命令时,Zsh 会优先从缓存表中读取路径,而不再重新遍历 PATH 环境变量。因此,在安装新软件包之前若已调用过系统同名命令,缓存记录会导致后装的软件包被“屏蔽”。

解决方案(二选一):

  1. 重置缓存:在当前 Shell 中执行 hash -r 命令,强制清除并刷新命令哈希表。
  2. 重启环境:关闭当前的 HiShell 窗口并重新打开,使 Zsh 重新加载环境并扫描 PATH。

无法在 CodeArts IDE 的命令行面板中调用 Homebrew 安装的软件

现象描述:

通过 brew install 安装了一个软件后,在 CodeArts IDE 的命令行面板里面执行相关的命令,依然会报错找不到命令。

原因分析:

这不是包管理器的 bug,也不是系统限制,而是两个 APP 使用的 shell 解释器不同导致的。

HiShell 使用的解释器是 /usr/bin/zsh,CodeArts IDE 使用的解释器是 /bin/sh(其底层实现是 mksh)。zsh 使用的配置文件是 ~/.zshrc,mksh 使用的配置文件是 ~/.mkshrc。因此用户在 ~/.zshrc 中编写的配置无法被 CodeArts IDE 的解释器识别。

由于本项目默认只支持系统自带的 HiShell 环境,并不承诺覆盖所有第三方应用,因此在安装指南中并未介绍这一知识。

解决方案:

如果用户想在两个环境中都能使用 Homebrew 安装的命令,只需要往两个配置文件都写入配置即可:

echo >> ~/.zshrc
echo 'eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"' >> ~/.zshrc

echo >> ~/.mkshrc
echo 'eval "$(/storage/Users/currentUser/.harmonybrew/bin/brew shellenv)"' >> ~/.mkshrc

第三方鸿蒙应用识别不到 Homebrew 安装的软件

现象描述:

通过 brew install 安装了一个软件后,大部分第三方的鸿蒙应用无法识别到 Homebrew 安装的软件。一个典型场景是 CodeArts IDE 的插件会报找不到相关命令。

原因分析:

根因在于鸿蒙应用的环境变量解析逻辑,不在于包管理器本身。

在 ~/.zshrc、~/.mkshrc、~/.bashrc 等配置文件中所做的配置仅能作用于 shell 解释器。如果一个鸿蒙应用不启动一个交互式的 shell 解释器作为子进程,而是在鸿蒙应用主进程中直接读 PATH 去找外部命令,那它是享受不到这部分配置的。因为大部分鸿蒙应用是不会主动去解析这些文件的。

解决方案:

这个问题暂时没有很好的解决方案。

在其他 OS 上,这种 GUI 应用的 PATH 变量问题,一般是由桌面系统来提供解决方案。例如,在 Windows 系统上,系统的设置菜单里面有系统级环境变量和用户级环境变量的设置项;在 Linux 系统上,GNOME 和 KDE 等桌面系统也提供了各自的解决方案。

当前鸿蒙 PC 未提供向 GUI 应用传递环境变量的解决方案,作为应用开发者,社区对此也无能为力。这部分需求请用户向厂商求助,只有用户呼声够大,厂商才会重视。

无法在 PC 上使用开发者命令

现象描述:

用户在鸿蒙 PC 上使用开发者命令(例如 brew test)时,会遇到这样的报错:You have to install development tools first.。

原因分析:

由于 Homebrew 的环境变量过滤机制,社区难以在 PC 上使用开发者命令,详情可查看这个 issue。

Homebrew 本身设计便是如此,并非 Harmonybrew 鸿蒙适配做得不完整。

解决方案:

为了解决这个问题,社区添加了一个 HOMEBREW_EXTRA_PATH 环境变量,详见这个 PR。

只需要设置这个环境变量,引入附加的工具链路径,Homebrew 便可正常构建出 Ruby 原生模块,使开发者命令成功运行。

用法示例:

brew update
brew install make llvm-gcc-compat gzip
export HOMEBREW_EXTRA_PATH="$(brew --prefix)/opt/make/bin:$(brew --prefix)/opt/llvm-gcc-compat/bin"
brew test gzip

项目实现与背景

为什么要卸载 GitNext 和 DevBox?

Homebrew 深度依赖 git。如果它检测到机器上有已安装的 git,它会用已安装的 git 来支撑自身业务。如果安装了 GitNext,Homebrew 就会优先使用 GitNext 提供的 git 来支撑自身业务。

然而 GitNext 携带的 git 存在严重缺陷,无法支撑 Homebrew 正常工作:

  • 鸿蒙适配不完整
  • hnp 打包工具对软链接、硬链接进行强制解引用,导致部分功能出现报错
  • GitNext 开发者删除了 git 的部分文件

用户将其卸载后,Homebrew 检测到系统上没有可用的 git,就会自动下载一个自包含的 git 供自己使用,业务便可正常工作。

这个自包含的 git 仅供 Homebrew 自己使用,不对外暴露。如果用户想使用 git,需要执行 brew install git 安装一个正常版本的 git。

至于卸载 DevBox 的原因,并不是因为它影响 Homebrew 包管理器本身的运行,而是因为它与 Homebrew 提供的工具存在重合。如果两个工具混搭使用,可能会导致 Homebrew 里面提供的部分软件包以及特色软件里面的方案无法正常工作。一旦出现此类问题,用户将难以定界问题来自 Homebrew 还是来自 DevBox。为避免产生不必要的争议和问题定位成本,本项目选择直接将其视为互斥软件。

Tier 1 和 Tier 2 平台的区别

这两个等级的区别主要体现在对 Formula 的维护策略与质量保障上:

Tier 1:核心支持平台

  • 准入机制:在该平台上,Formula 必须通过 brew test 自动化测试。若测试失败,则该 Formula 会被拒绝合入核心软件仓库。
  • 典型环境:社区版 OpenHarmony 系统。
  • 覆盖设备:鸿蒙开发板、鸿蒙容器。

Tier 2:次级支持平台

  • 维护策略:采取“生态随行”策略。社区致力于提供基础运行能力,但不会针对这些平台进行强制性的自动化测试或人工回归。
  • 典型环境:HarmonyOS 系统。
  • 覆盖设备:鸿蒙 PC。

通过这种分层机制,社区能够确保在核心开发环境(Tier 1)的稳定性,同时兼顾更多商用终端(Tier 2)的生态覆盖。

社区对 Homebrew 做了哪些改动?

为了让 Homebrew 适配 OpenHarmony(尤其是鸿蒙 PC 的环境限制),社区对包管理器客户端和安装脚本进行了一系列定制修改。

若用户对修改点感兴趣,可对相关仓库进行 diff 操作,查看比较结果。

包管理器客户端:

mkdir upstream downstream
git clone --depth 1 -b 7.0.6 https://github.com/Homebrew/brew.git upstream/brew
git clone --depth 1 https://atomgit.com/Harmonybrew/brew.git downstream/brew
diff -ruN -x ".git" --no-dereference upstream/brew downstream/brew > out.diff
vim out.diff

安装脚本:

mkdir upstream downstream
git clone https://github.com/Homebrew/install.git upstream/install
git clone https://atomgit.com/Harmonybrew/install.git downstream/install
cd upstream/install
git reset --hard 39c012e6db58f84f7469e9346adba57f8302110b
cd -
diff -ruN -x ".git" --no-dereference upstream/install downstream/install > out.diff
vim out.diff

这里给出一个简略版的修改点总结:

  • 基础设施重定向:将硬编码的 GitHub 代码仓与制品仓(GHCR)地址切换至 AtomGit 仓库与自定义 CDN,以保障国内环境下的顺畅访问与极速下载。
  • 平台识别与路径重构:新增 ohos 平台标志变量,在复用 Linux 业务逻辑的同时,可以针对 OpenHarmony 平台的特有差异进行处理;将所有安装、缓存及临时目录重定义至 /storage/Users/currentUser 下,以规避鸿蒙 PC 系统目录的只读限制。
  • 安全与权限适配:针对鸿蒙 PC 的单用户及安全特性,剔除所有 sudo 相关逻辑。同时在构建流程中注入自动代码签名机制,确保所有 ELF 文件符合系统校验要求,避免运行被拦截。
  • 工具链与 C 库定制:将默认编译器由 gcc 切换为 clang;禁用自包含 glibc 机制,强行链接系统原生的 musl libc,以确保在鸿蒙 PC 上的兼容性并降低环境侵入。
  • 核心机制补全(portable-git):借鉴 portable-ruby 理念,社区为鸿蒙开发了 portable-git。当检测到系统未预置 git 时,Homebrew 会自动下载 git 工具供自己使用,实现“开箱即用”。
  • Shell 运行环境兼容:由于鸿蒙 PC 缺少 /bin/bash,社区对项目中所有 Shell 脚本的 shebang 进行了 Zsh 适配修改,并修复了大量 Bash 专有语法在 Zsh 环境下的执行异常。
  • 系统命令适配(toybox):重写了 find、ps、file 等外部命令的调用逻辑,确保在系统仅内置 toybox 精简工具集的情况下,Homebrew 包管理器的各项功能依然能正常工作。
  • 稳定性增强与特性裁剪:为了确保软件包稳定可靠,社区禁用了在鸿蒙上存在兼容风险的“软件包重定位”与“隐式依赖检测”特性。
  • 开发者生态支持:适配 AtomGit API,使 bump-formula-pr 等维护命令能够自动向 AtomGit 提交 PR。

社区为什么能继承大部分上游的 formula?

核心逻辑在于,社区没有重复造轮子,而是把“蹭生态”的艺术玩到了极致。

能够完全无缝继承 Homebrew 海量的上游 Formula,取决于两个层面的设计:

业务设计层面:

  • 社区对 Homebrew 业务代码做适配的时候,尽可能复用了 Linux 平台上的业务逻辑。
  • 系统身份泛化:在代码底层,社区将 OpenHarmony 视为一种特殊的 Linux 发行版。通过走 Linux 系统的业务路径,大部分 Formula 无需修改即可直接在 OpenHarmony 上进入构建流程。
  • Superenv 垫片适配:社区对 Homebrew 的 superenv 垫片(cc, gcc, ld 等)进行了适配。当 Homebrew 启动构建时,这些垫片能自动拦截编译指令并重定向至 ohos-sdk 中的 LLVM 编译器,实现工具链的无感切换。

构建环境层面:

  • 社区基于 DockerHarmony 封装了专用的流水线镜像,通过模拟标准开发环境扫清构建障碍。
  • 编译器欺骗机制:效仿 macOS 的做法,在镜像中将 cc、gcc、ld 等指令软链接至 LLVM。即使部分软件绕过了 superenv,依然能在 configure 阶段自动识别并调用正确的编译器,无需手动干预环境变量。
  • 内核级平台兼容:由于鸿蒙容器直接运行在 Linux 内核上,系统 uname 原生返回 Linux 标识。社区利用这一特性,使绝大多数开源软件能自动匹配成熟的 Linux 构建分支,避免因识别为“未知系统”而导致构建中断。
  • 标准 GNU 工具链补齐:镜像预置了完整版的 tar、grep、awk 等标准 GNU 工具。这确保了那些默认系统已装有上述工具的 Formula 能够正常运行,无需在每一个 Formula 中额外声明构建依赖。
  • 隐式构建依赖注入:Homebrew 默认运行环境已具备 make、perl 等基础开发工具。社区在流水线镜像中对标补齐了这些隐式依赖,从而保障了上游 Formula 在鸿蒙环境下的构建行为与原生 Linux/macOS 保持高度一致。

为什么选择 Homebrew 而不是别的包管理器?

首先需要明确:Harmonybrew 是一个由社区发起的开源项目,其技术选型由项目创建者 @hqzing 基于个人调研独立做出。此选型与 OpenHarmony 社区或相关 PC 产品的官方规划无关。应避免误解为“鸿蒙选择了 Homebrew”或“鸿蒙 PC 选择了 Homebrew”。

在针对 OpenHarmony 系统进行包管理器方案调研时(详见 @hqzing 编写的技术博客:Linux包管理器生态漫谈),@hqzing 认为 Homebrew 的交互逻辑和生态特征更契合个人 PC 用户的使用习惯。考虑到 PC 终端在鸿蒙生态中的重要性,决定重点开展 Homebrew 的移植工作。

Homebrew 并非社区的唯一路径。目前,@hqzing 已同步完成了 pkgsrc 的移植并创建了 pkgsrc-ohos 项目,该方案同样能够支持鸿蒙 PC 环境,为用户提供了另一种轻量化的选择。

这两套系统呈现出截然不同的技术特性,分别代表了包管理器设计的两个极端,旨在为 OpenHarmony 生态提供全方位的技术参考:

机制深度:极繁 vs 极简

  • Homebrew:侧重于强大的自动化机制。它混合了大量的 Shell 与 Ruby 脚本,实现了如 superenv(超级环境)、自包含 glibc 以及软件包动态重定位等复杂特性。为了在鸿蒙上完美运行,社区对其业务逻辑进行了深度的适配。
  • pkgsrc:追求极致的轻量与纯粹。它由一套构建系统和一套管理工具组成,逻辑简洁,通过源码重编译即可快速接入 OpenHarmony。

实现方式:脚本实现 vs 二进制实现

  • Homebrew:纯脚本实现,高度依赖 Ruby 解释器及大量的外部工具链(git, curl, file 等),灵活性高,适合资源充足的 PC 环境。
  • pkgsrc:其核心组件(如 bmake, pkg_install)完全由 C 语言编写,编译生成的二进制文件可直接运行,无需额外依赖,对系统环境的需求极低。

发布模式:滚动更新 vs 周期发布

  • Homebrew:典型的滚动更新模式,源源不断地为用户推送最新版本的软件包,保持生态的实时性。
  • pkgsrc:遵循严格的季度发布计划,通过固化版本分支来确保环境的高度稳定与可预期。

通过对上述两套路线迥异的方案进行实践,社区已经完成了初步的“技术打样”。这两套方案覆盖了包管理设计的不同形态,后续开发者在移植其他包管理器时(如 Nix 或 Pacman 等),将有迹可循。

OpenHarmony、HarmonyOS 与 GNU/Linux 的关系

关于这方面的背景知识,请参考 @hqzing 编写的技术博客:OpenHarmony、HarmonyOS 与 GNU/Linux 的关系。

代码签名机制的影响

关于这方面的背景知识,请参考 @hqzing 编写的技术博客:代码签名机制对我们的影响。

这里仅补充讲解 Harmonybrew 项目里面的情况:在 Harmonybrew 项目中,“二进制签名工具签名”和“链接器签名”这两种签名方式社区都有使用到。

首先是二进制签名工具签名:社区的流水线在执行编译构建的时候不会启用链接器签名,而是等整体编译构建任务完成后,在打包 bottle 之前统一用二进制签名工具签一遍。

这是因为,如果仅靠链接器签名,会有一些场景覆盖不到:

  • 在社区的仓库中,并非所有软件包都是使用 ohos-sdk 里面的 LLVM 来编译的。比如 gh 是用 Go 编译器来进行编译的、node 是用 Alpine Linux 软件仓库里面的 GCC 编译器来进行编译的。对于这些软件包,ohos-sdk 的链接器签名是照顾不到的。
  • 部分软件包会在编译完成后再次对二进制文件进行修改。比如 brotli 这个软件包,它的构建系统(cmake)会在编译完成后对二进制文件进行修改。即使社区为它做了链接器签名,经过 cmake 修改之后签名也会失效,仍无法通过验签。

因此社区分发的软件包全部都是用二进制签名工具做的签名。

其次是链接器签名:社区虽然有用到这种方式,但并不是用来分发软件包的,而是给用户提供方便的。

社区在制作 ohos-sdk 这个 formula 的时候,对 ohos-sdk 里面的 lld 链接器做了简单的脚本封装,默认启用了链接器签名,使得它编出来的程序可以直接在鸿蒙 PC 上运行,无需手动进行代码签名。

应用沙箱环境和非应用沙箱环境的区别

关于这方面的背景知识,请参考 @hqzing 编写的技术博客:应用沙箱环境和非应用沙箱环境的区别。

hmdfs 的影响

关于这方面的背景知识,请参考 @hqzing 编写的技术博客:hmdfs 对我们的影响。

这里仅补充讲解 Harmonybrew 项目里面的情况:Harmonybrew 正是安装在 /storage/Users/currentUser 目录下,在 HiShell 环境中,它正是承载在 hmdfs 上的。

既然 hmdfs 有这么多缺陷,为什么 Harmonybrew 还要执意安装在这里呢?

这其实是一个极其无奈的选择。在鸿蒙 PC 的应用沙箱内,系统管控非常严格,这个家目录是目前唯一一个既能让用户有写权限、又能实现跨应用共享的目录。如果想让 Harmonybrew 安装的软件在 HiShell 里能用,在 CodeArts IDE 这种开发工具里也能调用,就只能选这里,别无他处。

社区曾多次向厂商反馈,希望能在 PC 上新增一些基于普通文件系统的 FHS 目录(比如 /usr/local 或 /opt),但这些意见最终都没被采纳。作为开发者,社区没有更好的目录可以选择。

这就引出了一个为了全局稳定性而做的牺牲:全平台路径统一。

为了让 Harmonybrew 的生态在所有设备上保持一致,无论是在 PC、开发板还是容器中,社区都强制统一了安装路径。这意味着,即使在鸿蒙开发板或鸿蒙容器中,社区本可以随心所欲地使用更标准的 /usr/local、/opt 等目录,但为了迁就鸿蒙 PC 这个“最小公约数”,大家不得不统一使用 /storage/Users/currentUser。

不过有一点可以让开发者放心:虽然路径看起来一样,但底层的“土壤”不同。

  • 在鸿蒙开发板上,社区首推的使用方法是在 hdc shell 调试终端中使用 Harmonybrew,并没有进入到应用沙箱中。因此,社区也就没有使用应用沙箱提供的家目录,而是直接在常规文件系统中创建了这个路径,所以它不受 hmdfs 限制。
  • 在鸿蒙容器中,这个路径也是在容器自己的 rootfs 上创建的,同样没有这些限制。

贡献和维护

如何访问流水线?

Harmonybrew 使用自部署的开源流水线系统 Buildbot 来承载核心 CI 任务。

出于安全考虑,社区没有将流水线 Web UI 向公网开放,但社区通过以下方式确保流程的透明与公开:

  • 实时反馈:社区通过 Webhook 实现了代码仓与流水线的联动。当用户提交 PR 后,机器人会将运行日志自动同步至 PR 讨论区,用户可以直接在评论区查看构建结果。
  • 逻辑公开:流水线的核心业务逻辑并非“黑盒”。所有构建脚本与配置代码均在 Harmonybrew/ci 仓库开源,任何人都可以审计或参考该 CI 流程。

如何加入维护团队?

目前项目的协作机制尚在完善中,暂无正式的增员计划。

但开源的魅力在于,无需“管理员”身份也一样能参与核心建设。相比于权限,维护团队更多承担的是评审 PR、例行巡检等繁琐的责任。社区非常欢迎用户先以贡献者的身份提交 PR,当深度参与成为常态时,加入团队便是水到渠成的事。

支持和规划

对旧版本系统的兼容性

与上游 Homebrew 针对多个 macOS 版本(如 macOS 14、macOS 15)分别构建制品的做法不同,Harmonybrew 目前采取单版本、向前滚动的维护策略:

  • 唯一版本制品:社区为每个软件包仅构建一个 ohos 版本的 Bottle 制品,暂不区分具体的系统小版本(如 OpenHarmony 6.1、OpenHarmony 7.0 等)。
  • 激进的版本跟随策略:由于 OpenHarmony 目前仍处于快速迭代期,本项目将始终跟随官方最新的正式版本。当新版本系统发布且鸿蒙 PC 开始大规模推送更新后,社区会同步升级工具链与流水线执行机,后续的所有软件包将会基于最新环境构建。
  • 兼容性边界:在迭代期内,社区的工作重心是确保软件在最新系统上的可用性。一旦流水线环境完成升级,社区将不再关注软件包在旧版本系统上的兼容情况或运行表现。

这种“向前看”的策略能够让社区集中精力解决新系统带来的技术挑战,确保包管理器始终与鸿蒙生态的最新特性保持同步。

如何提供商用支持?

Harmonybrew 作为一个由社区发起的开源项目,在商用支持与责任边界上遵循以下原则:

  • 免责声明与许可证:本项目对标上游 Homebrew 的运作模式,采用 BSD 2-Clause License 开源许可证。项目提供的所有代码与软件包均按“现状”(As-is)提供,不提供任何形式的明示或暗示保证,包括但不限于对商用结果、特定用途适用性或系统稳定性的保障。
  • 非营利与社区驱动模式:社区是一个纯粹的非营利性开源社区,不从事任何商业经营活动。项目的发展由社区兴趣与共识驱动,不承接任何来自企业端的定向定制需求。如果用户的业务场景需要特定的软件包支持,欢迎通过提交 Pull Request 的方式贡献至社区仓库,社区将一视同仁地进行技术评审。
  • 关于企业“可信”诉求:本项目不为任何企业的“可信软件”、“可信构建”等内部合规诉求背书。由于开源项目的公开性质,社区无法满足特定企业私有的安全合规审计要求。对于有极高合规性或内网运行要求的企业,社区建议用户 Fork 本项目并在企业内网独立运营。用户可以基于社区的开源底座,自行构建符合企业内部安全标准的软件源与流水线。

是否能支持其他架构?

目前 Harmonybrew 仅原生支持 arm64 架构,且暂无主动适配其他架构的计划。

若相关硬件厂商或社区组织有强烈意愿将特定架构(如 x86_64)融入本社区生态,社区持开放合作态度,但合作方需具备独立承担工程适配与运行成本的能力。

新增架构的准入需完成以下工作:

构建环境适配:

  • 鸿蒙容器:对 DockerHarmony 项目进行 fork 并迭代升级,使其能通过 docker buildx 构建多架构镜像(包含目标架构),将改动回馈至上游。
  • 原生编译工具链:提供可在目标架构原生运行的 ohos-sdk。出于构建质量考虑,社区的流水线仅接受原生编译,不接受交叉编译方案。
  • 流水线镜像:对 Harmonybrew/ci 项目进行 fork 并迭代升级,使其 ci-runner 能通过 docker buildx 构建多架构镜像(包含目标架构),将改动回馈至上游。

流水线工程改造:

  • 脚本兼容性:对 Harmonybrew/ci 项目进行 fork 并迭代升级,使流水线能够支持多架构 Bottle 的并行构建与分发,将改动回馈至上游。

持续的资源投入:

  • 硬件与流量成本:合作方需承担因新增架构产生的额外构建机开销及 CDN 下行流量成本。

长期维护承诺:

  • 测试与排障:合作方需指派专人维护 Formula 的架构兼容性。若某软件包在 arm64 上通过但在新增架构上失败,合作方有义务及时修复,严禁因架构差异长期阻塞社区 PR 的合入流程。

如果合作方满足上述所有条件并希望发起合作,可通过邮件与社区联系。

什么时候能回馈上游?

Harmonybrew 参考了 Linuxbrew 的早期演进路径:即先通过独立 Fork 版本进行快速迭代与验证,待生态成熟后再寻求合入 Homebrew 上游。

然而,基于当前的客观技术环境与社区治理现状,本项目在短期内暂无回馈上游的计划。

主要的挑战在于以下三个层面:

架构的侵入性变更:

为了优先适配 OpenHarmony 特有的底层限制,社区对 Homebrew 核心代码进行了一些非兼容性修改。这些变更目前尚未完全实现“平台解耦”,若直接回馈,可能会对 Homebrew 在 macOS 或标准 Linux 平台上的既有行为产生副作用。

平台定义的路线抉择:

目前的工程实践将 OpenHarmony 视为一个“特殊的 Linux 发行版”以实现快速迁移。但在寻求上游合入时,必须确立明确的平台定义标准——是将 OpenHarmony 视为一个特殊的 Linux 发行版,还是视为一个完全独立的新平台?

社区需要在这两条路线之间做出抉择:

  • 方案 A(兼容路径):继续沿用 Linux 兼容路线(类似 Ruby 对 Android 的处理)。
  • 方案 B(原生路径):将 OpenHarmony 定义为完全独立的全新平台架构(类似 Node.js 对 Android 的处理)。

这两条路线在技术上均可行,但涉及重大的架构顶层设计决策,需与上游社区进行长期的技术论证与共识构建。

开源治理与成本分担:

合入上游不仅是代码的合并,更涉及长期运维责任的分担:

  • 流水线压力:新增平台意味着上游社区需额外维护一套针对 OpenHarmony 的构建与测试流水线(CI/CD),这将显著增加其核心维护团队的工作负载。
  • 基础设施成本:多平台构建涉及算力资源等成本,目前尚无明确的资金支持方案来覆盖这部分由上游承担的额外开支。
  • 构建环境合规性:上游社区通常要求官方认可的、标准化的云化构建环境。目前社区使用的鸿蒙容器方案虽能满足功能需求,但该鸿蒙容器并非 OpenHarmony 官方提供,而是个第三方解决方案,在合规性与上游认可度方面仍需长期的沟通与背书。

总结:社区目前的重心在于“生态可用性”的打磨。回馈上游是一个涉及技术、资金、治理规则的复杂系统工程,社区将在 OpenHarmony 桌面生态进一步壮大、相关构建基础设施更趋标准化后,再适时启动与上游社区的正式磋商。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐