欢迎加入【开源鸿蒙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-skillshttps://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-muslmusl 兼容性问题修复120 分钟5 分钟
lycium-compliance-docs生成 OAT / README / SHA51245 分钟3 分钟

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


四、Step 1:HPKBUILD 编写

4.1 前置条件

工具版本说明
OHOS SDKlatest/home/ohpkg/linux
lycium_pluspluslatest交叉编译框架
libtool2.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 (当前)raylibSDL
构建系统autoconfCMakeCMake
核心问题config.sub 不识别 OHOSMemory 平台缺链接库无显示后端
修复方式sed 修补 config.subcmake 补丁 (LIBS_PRIVATE)配置开关
禁用组件5 个 (cairo/pci/gl/udev/xml2)X11/Wayland
构建步骤autogen.sh → configure → makecmake → makecmake → make
静态库大小1.9 MB2.6 MB5.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

赋能鸿蒙PC开发者,共建全场景原生生态,共享一次开发多端部署创新价值。

更多推荐