欢迎加入【开源鸿蒙PC社区】,一起共建鸿蒙化C/C++三方库生态。
欢迎在【PC社区】平台贡献你的项目。
仓库: open-mpi/hwloc v2.14.0 — Portable hardware topology detection library
适配平台: 鸿蒙PC


资源 地址
hwloc 上游仓库 https://github.com/open-mpi/hwloc
hwloc 官方文档 https://www.open-mpi.org/projects/hwloc/doc/
lycium_plusplus 框架 https://atomgit.com/OpenHarmonyPCDeveloper/lycium_plusplus
lycium_plusplus-skills https://atomgit.com/unisources/lycium_plusplus-skills
hwloc 适配后仓库 https://atomgit.com/unisources/hwloc

image-20260613071758618

一、前言

不知道你有没有这种经历:一个 Linux 上编译如丝般顺滑的 C 库,换到嵌入式平台后就处处碰壁——今天缺个工具链,明天不认操作系统名。为了编译一个跨平台库,你花了半天装依赖、改 Makefile、调试链接错误,最后发现最根本的问题是 autoconf 的那一套工具链根本不认识你的目标平台。

hwloc(Hardware Locality)就让我经历了这样一次「水土不服」。它是一个成熟的硬件拓扑检测库,在 HPC(高性能计算)领域应用广泛,能够探测 CPU 核心数、缓存层级、NUMA 节点、甚至 GPU 在系统总线上的物理位置。在 Linux 服务器上,它可以帮你做进程资源绑定和性能优化。而我们的目标,是把这套能力带到鸿蒙PC。

结果一上来就遇到了一个经典问题:configure: OS ‘ohos’ not recognized。OpenHarmony 这个操作系统名字,autoconf 不认识。这个错误信息背后的机制,涉及到 autoconf 工具链中一个叫做 config.sub 的关键文件——它维护了一份已知操作系统的白名单。解决方案其实很简单——在名单里加上 ohos——但前提是你得理解这个文件在构建流程中的位置。

更具体地说,hwloc 使用 autoconf/automake/libtool 构建系统,这意味着它的 GitHub tarball 甚至不包含可直接运行的 configure 脚本。你需要先安装 libtool,运行 autogen.sh 引导构建,修补 config/config.sub,然后才能进入常规的 configure && make && make install 流程。每一步都藏着坑。

本文将完整记录如何通过 AtomCode Skills 工作流,将 hwloc 2.14.0 移植到鸿蒙PC(OpenHarmony arm64-v8a)平台。全文涵盖 autoconf 库的 HPKBUILD 编写、config.sub 的修补原理与实操、构建验证全流程。


二、AtomCode Skills 工作流总览

在正式开始适配之前,先看一下 AtomCode Skills 如何将 hwloc 的 autoconf 适配流程结构化:

Skills工作流

new-package
HPKBUILD生成

lycium-build-check
环境检查

发现 libtool 缺失

安装 libtool

autogen.sh 引导构建

config.sub 不识别 ohos

sed 修补 config.sub

configure / make / install

lycium-compliance-docs
合规文档生成

✅ 适配完成

AtomCode 提供的核心技能加速器:

Skill 作用 传统方式耗时 Skills 耗时
new-package 生成 autoconf 类 HPKBUILD 骨架 30 分钟 30 秒
lycium-build-check 验证交叉编译环境(含 libtool 检测) 15 分钟 1 分钟
lycium-fix-musl musl 兼容性问题修复 120 分钟 5 分钟
lycium-compliance-docs 生成 OAT / README / SHA512 45 分钟 3 分钟

数据对比:传统方式完成一个 autoconf 库的鸿蒙适配平均耗时 6~10 小时(主要时间花在 config.sub 排查和工具链缺失定位上),AtomCode Skills 工作流可将核心工作量压缩到 40 分钟以内。


四、Step 1:HPKBUILD 编写

4.1 前置条件

工具 版本 说明
OHOS SDK latest /home/ohpkg/linux
lycium_plusplus latest 交叉编译框架
libtool 2.4.7+ hwloc 依赖 autoconf/automake/libtool

4.2 HPKBUILD 骨架生成

hwloc 使用 autoconf/automake 构建,与 CMake 库不同,它的 GitHub tarball 不包含生成的 configure 脚本——只包含 configure.ac。因此 prepare() 中需要先运行 autogen.sh 来引导构建系统。

pkgname=hwloc
pkgver=2.14.0
pkgrel=0
pkgdesc="Hardware Locality (hwloc) — Portable hardware topology detection library"
url="https://www.open-mpi.org/projects/hwloc/"
archs=("arm64-v8a")
license=("BSD-3-Clause")
depends=()
makedepends=()

source="https://github.com/open-mpi/hwloc/archive/refs/tags/hwloc-$pkgver.tar.gz"
autounpack=true
buildtools="autoconf"
builddir=hwloc-hwloc-$pkgver

关键点buildtools="autoconf" 告诉 lycium 框架使用 autoconf 构建系统。builddir 从 tarball 目录结构提取为 hwloc-hwloc-2.14.0(前缀 hwloc- + 版本号)。

4.3 环境检查

========== 1. OHOS_SDK ==========
✅ OHOS_SDK = /home/ohpkg/linux

========== 2. LLVM 工具链 ==========
✅ aarch64-linux-ohos-clang

========== 3. 构建工具 ==========
✅ gcc   ✅ g++   ✅ cmake   ✅ make
✅ autoconf ✅ automake ❌ libtool  ← 缺失

关键点:hwloc 需要 libtool 2.2.6 或更高版本来运行 autogen.sh。如果在环境检查中发现了缺失的构建工具,务必在构建前安装。这是一个 autoconf 类库特有的依赖,CMake 类库不需要。


五、核心问题发现:从两个编译错误入手

5.1 审查结果总览

问题 严重度 影响
libtool 未安装 🔴 阻塞 autogen.sh 无法运行
config.sub 不识别 ohos 🔴 阻塞 configure 无法执行
Cairo/PCI/GL 不可用 🟡 可选 禁用无关组件即可

5.2 问题一:libtool 未安装

现象:第一次运行 autogen.sh 时:

autoreconf: running: aclocal --force -I ./config
configure.ac:70: error: libtool version 2.2.6 or higher is required
configure.ac:70: the top level
autom4te: error: /usr/bin/m4 failed with exit status: 63
aclocal: error: /usr/bin/autom4te failed with exit status: 63
autoreconf: error: aclocal failed with exit status: 63

排查:hwloc 使用 libtool 管理共享库的编译和安装。autoreconf(autogen.sh 内部调用的工具)需要 libtool.m4 宏文件来生成 configure 脚本和 ltmain.sh

根因定位:系统未安装 libtool 包。

修复方案:安装 libtool:

sudo apt-get install libtool libtool-bin

安装后验证:

$ libtool --version
libtool (GNU libtool) 2.4.7

5.3 问题二:config.sub 不识别 OHOS 操作系统

现象:configure 失败:

checking host system type... Invalid configuration `aarch64-unknown-linux-ohos':
OS `ohos' not recognized
configure: error: /bin/bash .././config/config.sub aarch64-unknown-linux-ohos failed

排查configure 脚本首先调用 config.sub 来规范化主机类型三元组(host triple)。三元组 aarch64-unknown-linux-ohos 包含 CPU(aarch64)、厂商(unknown)、内核(linux)和操作系统(ohos)。config.sub 需要将 ohos 识别为合法的操作系统名。

根因定位config.sub 是 GNU autoconf/automake/libtool 工具链的一部分,由 autogen.sh 从系统 /usr/share/libtool/build-aux/config.sub 复制到项目目录中。这个文件维护了一份已知操作系统的白名单——包括 Linux、Android、FreeBSD、Fuchsia 等——但 ohos(OpenHarmony)不在其中。

具体来说,config.sub 中有两个位置需要修改:

  1. 操作系统名列表case $os in):此处列出所有可识别的操作系统名称
  2. 内核-OS 组合验证case $kernel-$os in):此处验证内核与 OS 的合法组合

修复前在 config.sub 中的相关上下文:

# 位置1:操作系统名列表(约第1755行)
| fuchsia* | redox* | bme* \
| midnightbsd* | ... | fiwix* )
    ;;       # ← ohos 不在列表中,走到 *) 分支报错

# 位置2:内核-OS 组合验证(约第1774行)
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
       | linux-musl* | linux-relibc* | linux-uclibc* )
    ;;       # ← linux-ohos 不在列表中,走到 *) 分支报错

修复方案:在 autogen.sh 运行后、configure 运行前,用 sed 在两处添加 ohos 支持。

# 位置1:在操作系统名列表中添加 ohos*
sed -i 's/| fiwix* )/| fiwix* | ohos* )/' config/config.sub

# 位置2:在 kernel-OS 组合中添加 linux-ohos*
# 注意:用行首 anchor 避免误匹配 "uclinux-uclibc" 行
sed -i '/^[[:space:]]*linux-gnu*/s/linux-uclibc* )/linux-uclibc* | linux-ohos* )/' config/config.sub

验证修补效果:

$ grep "ohos" config/config.sub
| fiwix* | ohos* )                          # 位置1:操作系统已识别
| linux-musl* | linux-relibc* | linux-uclibc* | linux-ohos* )  # 位置2:组合已验证

5.4 可选组件禁用

hwloc 支持多种后端。OpenHarmony 上没有以下组件,需要在 configure 时显式禁用:

--disable-cairo     # 无 GUI 依赖
--disable-pci       # 无 PCI 总线
--disable-gl        # 无 OpenGL
--disable-libudev   # 无 udev(OHOS 使用 devfs)
--disable-libxml2   # 仅影响 XML 语法检查高级功能

这些禁用的后端不影响 hwloc 的核心拓扑检测能力。CPU 拓扑、NUMA 节点、缓存层级等信息仍然可以通过 /sys/devices/system/cpu/proc/cpuinfo 等标准 Linux 接口获取。


六、构建验证

6.1 完整的构建日志

=== Step 1: autogen.sh ===
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I ./config
autoreconf: running: libtoolize --install
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --force-missing
autoreconf: Leaving directory '.'
OK

=== Step 2: patch config.sub ===
| fiwix* | ohos* )
| linux-musl* | linux-relibc* | linux-uclibc* | linux-ohos* )
OK

=== Step 3: configure ===
checking build system type... x86_64-pc-linux-gnu
checking host system type... aarch64-unknown-linux-ohos
checking for aarch64-unknown-linux-ohos-gcc...
  /home/ohpkg/linux/native/llvm/bin/aarch64-linux-ohos-clang
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
...
config.status: creating Makefile
config.status: creating hwloc.pc
---
Probe / display I/O devices: LinuxIO
Graphical output:            no
XML input / output:          basic
Plugin support:              no
OK

=== Step 4: make ===
make[1]: Entering directory 'arm64-v8a-build'
  CC       topology.lo
  CC       traversal.lo
  CC       distances.lo
  ...
  CC       topology-linux.lo
  CCLD     libhwloc.la
make[1]: Leaving directory 'arm64-v8a-build'
OK

=== Step 5: install ===
make[2]: Entering directory 'arm64-v8a-build'
 /usr/bin/install -c
   .../libhwloc.a  '/lycium/usr/hwloc/arm64-v8a/lib/libhwloc.a'
OK

6.2 产物验证

# 静态库大小
$ ls -lh lycium/usr/hwloc/arm64-v8a/lib/libhwloc.a
-rw-r--r-- 1 root root 1.9M  libhwloc.a

# 目标架构验证
$ file lycium/usr/hwloc/arm64-v8a/lib/libhwloc.a
libhwloc.a: current ar archive

# 头文件查看
$ ls lycium/usr/hwloc/arm64-v8a/include/hwloc.h
hwloc.h    # 主头文件

6.3 安装产物结构

lycium/usr/hwloc/arm64-v8a/
├── lib/
│   ├── libhwloc.a              # 静态库 (1.9 MB)
│   ├── libhwloc.la              # libtool archive
│   └── pkgconfig/hwloc.pc       # pkg-config 配置
├── include/
│   ├── hwloc.h                  # 主头文件
│   └── hwloc/ (31个子头文件)     # 子模块:bitmap, helper, linux 等
├── bin/                         # 命令行工具 (hwloc-info, lstopo 等)
└── share/                       # 文档和 man pages

七、经验总结

7.1 config.sub 的运作机制

config.sub 是 autoconf 工具链中最容易被忽视但最关键的文件之一。它的职责是将用户输入的"主机类型"字符串(如 aarch64-unknown-linux-ohos)规范化,并验证操作系统是否在已知列表中。

输入:aarch64-unknown-linux-ohos
  │
  ├─ 第1步:按 - 分割
  │   cpu=aarch64, vendor=unknown, kernel=linux, os=ohos
  │
  ├─ 第2步:验证 CPU 架构  → aarch64 ✅
  ├─ 第3步:验证 OS 名称    → ohos → 不在白名单 → ❌
  │
  └─ 修复后:添加 ohos*      → ohos ✅

通过这个流程,我们可以理解为什么在其他 Linux 发行版上顺利编译的库,到了 OpenHarmony 就需要修补 config.sub——因为 ohos 这个操作系统名实在太新了。

7.2 同类库适配对比

对比维度 hwloc (当前) raylib SDL
构建系统 autoconf CMake CMake
核心问题 config.sub 不识别 OHOS Memory 平台缺链接库 无显示后端
修复方式 sed 修补 config.sub cmake 补丁 (LIBS_PRIVATE) 配置开关
禁用组件 5 个 (cairo/pci/gl/udev/xml2) X11/Wayland
构建步骤 autogen.sh → configure → make cmake → make cmake → make
静态库大小 1.9 MB 2.6 MB 5.1 MB

7.3 鸿蒙化适配最佳实践

  1. autoconf 类库的适配分三步autogen.sh → 修补 config.subconfigure --host=*linux-ohos。第一步可能缺失 libtool,第二步是新增操作系统名的必经之路,第三步则要禁用 OHOS 上不可用的组件。

  2. config.sub 的修补优先于其他修改:很多 autoconf 库在首次编译到新平台时,第一关就是 config.sub。通过 sedautogen.sh 后修补是最小侵入方案——不需要维护一个随着 libtool 版本变化的 patch 文件。

  3. 禁用组件要过度而非不足:在 configure 时显式 --disable-* 所有可疑组件,比等待编译失败再回溯更快。hwloc 的 5 个 --disable-* 选项中,有些(如 Cairo)在 config.summary 中显示为 “no” 也没关系——核心拓扑检测功能不受影响。

  4. 构建主机的工具链完整性与目标平台无关:hwloc 需要 libtool 来生成 configure 脚本,但 libtool 本身只在构建主机上运行,其版本与目标平台上的运行时无关。

7.4 总结

适配 autoconf 类库到 OpenHarmony 的关键,不在于修改多少行 C 代码,而在于理解三层工具链的传递关系:主机上的 autoconf 生成 configure,configure 调用 config.sub 验证目标平台,最后才是交叉编译器编译源码。config.sub 不认识 ohos 不是 bug——是整个工具链生态还没跟上新平台的速度。而我们开发者要做的,就是在这个链条的最早环节插一脚,告诉它:“这个操作系统,我认识。”


八、相关文件一览

thirdparty/hwloc/
├── HPKBUILD                   # 交叉编译构建脚本
├── LICENSE                    # BSD-3-Clause 许可证
├── OAT.xml                    # 许可证合规配置
├── README.OpenSource          # 开源元数据声明
├── README_zh.md               # 中文说明文档
└── SHA512SUM                  # 源码包完整性校验

HPKBUILD 中的关键配置

# prepare() 中的核心逻辑:
# 1. 运行 autogen.sh 生成 configure
# 2. 用 sed 修补 config/config.sub 添加 ohos 支持
# 3. 设置交叉编译器

# build() 中的关键配置:
../configure \
    --host=aarch64-unknown-linux-ohos \
    --target=aarch64-unknown-linux-ohos \
    CC=$cc CXX=$cxx \
    --enable-static --disable-shared \
    --disable-cairo --disable-pci --disable-gl \
    --disable-libudev --disable-libxml2
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐