终于可以在鸿蒙PC电脑上直接使用vcpkg啦。用到的三方库可以直接在鸿蒙PC上使用vcpkg命令安装。在鸿蒙PC上使用之前,需要先把vcpkg这个可执行命令行程序移植上去。本文记录使用 OHOS SDK + CMake + Ninja,在Ubuntu24.04linux宿主机环境上 ,交叉编译 vcpkg-tool(生成可在鸿蒙 PC 上运行的 vcpkg 可执行文件)的全过程,包括依赖约定、典型报错与处理方式,以及在设备侧运行时与 dlopen / 签名 / libcurl 相关的注意事项。


vcpkg在鸿蒙PC上使用效果截图:

在这里插入图片描述

移植成功的鸿蒙PC上的vcpkg项目地址https://gitcode.com/qq8864/vcpkg-tool.git

找到ohos-pc分支,里面有编译好的在鸿蒙PC上可运行的vcpkg可执行文件,将其拷贝到鸿蒙PC上即可运行。

如何真机验证和使用?

1.在鸿蒙PC上,clone以下仓库地址:

git clone https://gitcode.com/OpenHarmonyPCDeveloper/ohos_vcpkg.git

将构建生成的可在鸿蒙pc上运行的vcpkg可执行文件放进上面clone下来的ohos_vcpkg里。将依赖的鸿蒙PC平台上的so库(libcurl.so.4、libssl.so.3、 libcrypto.so.3、libz.so)也放进来。

2.运行:

cd ohos_vcpkg
LD_LIBRARY_PATH="$(pwd)" ./vcpkg --version

预期可见版本信息,例如:

vcpkg package management program version 2999-12-31-unknownhash

接下来介绍下vcpkg-tool 交叉编译的详细过程:

1. 环境与目标

项目 说明
目标三元组 / 架构 aarch64-linux-ohos
SDK OHOS SDK(示例路径见下)
CMake ≥ 3.28,示例 4.1.2
Ninja 示例 1.12.1
生成系统 Ninja
典型宿主机 Ubuntu 24.04(x86_64),交叉编译目标为 aarch64 OHOS
真机验证环境 鸿蒙PC(arm64-v8a)

宿主机 | Ubuntu 24.04(x86_64)环境下SDK安装及下载:

1.0 环境准备(Ubuntu 24.04_x86_64 宿主机环境)
sudo apt update
sudo apt install -y git curl cmake ninja-build gcc g++ make autoconf automake libtool yasm nasm

sudo apt install -y gettext autopoint
sudo apt install python3 python3-pip
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1

1.1下载配置ohos-sdk
sdk_download_url="https://cidownload.openharmony.cn/version/Daily_Version/OpenHarmony_6.1.0.27/20260111_020523/version-Daily_Version-OpenHarmony_6.1.0.27-20260111_020523-ohos-sdk-public.tar.gz"
curl -o ohos-sdk-public.tar.gz $sdk_download_url
mkdir ohos-sdk
tar -zxf ohos-sdk-public.tar.gz -C ohos-sdk

cd ~/ohos-sdk/linux
unzip native-linux-x64-6.1.0.27-Beta1.zip
unzip toolchains-linux-x64-6.1.0.27-Beta1.zip

这段代码的作用是从指定的 URL 下载 SDK 压缩包,然后创建一个名为 ohos-sdk 的目录,并将压缩包解压到该目录下。

SDK 目录示例(以 $OHOS_SDK_ROOT/linux/native/ 为前缀):

/root/ohos-sdk/linux/native/
├── build-tools/
├── llvm/              # clang、lld、ar 等
├── sysroot/           # 头文件与系统库
└── toolchain.cmake    # 或 ohos.toolchain.cmake(依 SDK 版本而定)

设置环境变量:

export OHOS_SDK_ROOT=/root/ohos-sdk/linux

2. 前置依赖

在配置工程前,确认 SDK 自带的构建工具可用:

"$OHOS_SDK_ROOT/native/build-tools/cmake/bin/cmake" --version
"$OHOS_SDK_ROOT/native/build-tools/cmake/bin/ninja" --version

注意, 还需要:

  • 已在 同一 OHOS triplet 下通过 vcpkg(或其它方式)准备好 curlfmtnlohmann-json 等鸿蒙PC上的so库,外部依赖的安装前缀(下文 CMake 变量中的路径需要用到)。
  • 若在大陆网络环境构建,FetchContent / GitHub 直连失败时需准备代理或离线包(见第 5 节)。

关于这部分内容,可以参考博文:使用 vcpkg 为鸿蒙(HarmonyOS / OHOS)下载与安装三方库实践指南

简单来说,就是需要先搞个在linux或windows上能用的vcpkg环境,用来安装鸿蒙pc上的三方库。

因为vcpkg可执行文件,依赖了curl和openssl等鸿蒙pc上的so库。

如下所示:

1.安装依赖fmt:

./vcpkg install fmt:arm64-ohos

在这里插入图片描述
2.安装libcurl和json库:

# 安装鸿蒙pc上的libcurl的so库
./vcpkg install libcurl:arm64-ohos
# 安装鸿蒙pc上的nlohmann-jsonso库
./vcpkg install nlohmann-json:arm64-ohos

在这里插入图片描述


3. 构建思路简述

  1. 使用 OHOS 的 CMake toolchain 指向 Clang 与 sysroot。
  2. curlnlohmann-json 作为外部 CMake 包接入(DVCPKG_DEPENDENCY_EXTERNAL_*),避免使用 vcpkg-tool 内置抓取的头文件与宿主不匹配。
  3. fmt 建议走内置静态依赖:外部 fmt 主版本与 vcpkg-tool 源码(期望 fmt v11 / fmt::v11)不一致时会出现模板符号歧义(见第 6 节)。
  4. curl/curlbuild.h 一类交叉编译宏冲突,通过 额外 include 路径 指向你用 OHOS 工具链编好的 curl 头文件。

4. 问题一:libcurl 头文件 / curlbuild.h 报错

4.1 典型报错摘录

In file included from include/vcpkg/base/curl.h:14:
build/_deps/libcurlheaders-src/include/curl/curlbuild.h:122:4:
  error: "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"

build/_deps/libcurlheaders-src/include/curl/curlrules.h:79:4:
  error: "CURL_SIZEOF_LONG definition is missing!"

在这里插入图片描述

4.2 原因说明(简述)

vcpkg-tool 会 FetchContent 一套用于编译期的 curl 头文件树;该树里的 curlbuild.h 与当前交叉目标(OHOS / aarch64)的长整数、socklen_t 等尺寸假定不一致时,会触发 curlrules.h 的静态断言。

4.3 处理办法

改为使用已为 OHOS 编好的 curl 安装树中的头文件,并通过编译选项把该 include 目录放到搜索路径最前(示例路径请替换为你的包路径):

-DCMAKE_CXX_FLAGS="-I/root/ohos_vcpkg/packages/curl_arm64-ohos/include"

同时配合「外部 curl CMake 包」开关(见第 7 节完整 CMake 命令)。


5. 问题二:CMake 拉取 GitHub / FetchContent 失败

5.1 现象

配置阶段在下载 cmrclibcurlheaders 等依赖 tarball 时超时或 TLS 失败。

在这里插入图片描述

5.2 方法一:代理(推荐)

export http_proxy=http://<代理主机>:<端口>
export https_proxy=http://<代理主机>:<端口>
# 重新执行 cmake 配置命令

5.3 方法二:离线放置源码包(「欺骗」下载步骤)

在可访问 GitHub 的机器上下载对应版本,例如:

  • https://github.com/vector-of-bool/cmrc/archive/refs/tags/2.0.1.tar.gz

上传到构建机后,放入 CMake FetchContent 期望的 populate 源码目录(路径需与你的 build/_deps/... 实际一致),例如:

mkdir -p /root/vcpkg-tool/build/_deps/cmakerc-subbuild/cmakerc-populate-prefix/src/
cp 2.0.1.tar.gz /root/vcpkg-tool/build/_deps/cmakerc-subbuild/cmakerc-populate-prefix/src/

mkdir -p /root/vcpkg-tool/build/_deps/libcurlheaders-subbuild/libcurlheaders-populate-prefix/src/
cp curl-7.29.0.tar.gz /root/vcpkg-tool/build/_deps/libcurlheaders-subbuild/libcurlheaders-populate-prefix/src/

保留 build 目录后再次运行 同一套 cmake 命令,若哈希与大小校验策略允许,常会跳过重新下载。

5.4 方法三:改镜像 URL

若允许修改 vcpkg-tool 仓库内的 CMakeLists.txt / cmake/ 中的 FetchContent URL,可替换为国内镜像或自建制品地址(注意版本与校验和一致性)。


6. 问题三:fmt 版本不一致导致编译歧义

6.1 典型报错特征

编译错误中出现 fmt::v11fmt::v12(或其它主版本)并存、formatter ambiguous 等描述。
在这里插入图片描述

6.2 根因

vcpkg-tool 当前源码按 fmt v11 API 编写;若 DVCPKG_DEPENDENCY_EXTERNAL_FMT=ON 且提供的 fmt 过新(例如 v12),会出现命名空间与模板实例歧义。

这个报错的原因是 fmt 库的版本冲突导致的。
报错根本原因版本不匹配:vcpkg-tool 的源代码(尤其是 stringview.h 和 fmt.h)是基于 fmt v11 编写的(代码中期望找到 fmt::v11)。

符号冲突:你手动编译并提供的外部 fmt 库版本太新了(从错误日志看是 v12,即 fmt::v12::formatter)。歧义:当编译器遇到 fmt::formatter 时,它同时发现了 v11(代码声明)和 v12(你提供的库),导致 reference to ‘formatter’ is ambiguous(引用歧义)。

6.3 推荐做法

-DVCPKG_DEPENDENCY_EXTERNAL_FMT=OFF

让工程 内置获取并静态链接 与源码匹配的 fmt,避免与外部包版本打架。外部 curl / nlohmann-json 仍可保持 ON。关闭它,让它自己下载并编译链接使用内部的静态库。


7. 问题四:构建成功后在鸿蒙 PC 上运行找不到 libcurl

7.1 现象

可执行文件启动即退出,提示类似:

vcpkg was unable to find a libcurl.so.4, libcurl-gnutls.so.4, or libcurl-nss.so.4 to use on this system.

即便已将目录加入 LD_LIBRARY_PATH,仍可能失败。

7.2 原因概要

  1. vcpkg-tool 不在链接期硬链接 libcurl,而是在运行时用 dlopen("libcurl.so.4", ...) 加载(参见源码 src/vcpkg/base/curl.cpp)。
  2. 鸿蒙侧对加载进进程的 ELF 共享库往往有签名校验要求;未签名的 libcurl.so / 其传递依赖可能在策略上无法被成功 dlopen
  3. libcurl.so.4 与 SONAME:部分构建产物 SONAMElibcurl.so,但 dlopen 按文件名查找 libcurl.so.4;部署时需保证 查找路径下存在期望文件名(必要时同时保留符号链接或拷贝)。

7.3 依赖链自检

readelf -d build/libcurl.so | grep -E "SONAME|NEEDED"

示例输出(示意):

 0x0000000000000001 (NEEDED)             Shared library: [libssl.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypto.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libz.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x000000000000000e (SONAME)             Library soname: [libcurl.so]

结论: libcurlopensslzlib 等在运行路径中不仅要「找得到」,在鸿蒙 PC 上通常还需要满足 签名 / 安全策略

7.4 签名与运行示例

在鸿蒙环境使用 binary-sign-tool.so 签名(路径与参数以你的 SDK / 系统文档为准):

cd build

binary-sign-tool sign -inFile libcurl.so -outFile libcurl.so -selfSign "1"
binary-sign-tool sign -inFile libcurl.so.4 -outFile libcurl.so.4 -selfSign "1"
binary-sign-tool sign -inFile libssl.so.3 -outFile libssl.so.3 -selfSign "1"
binary-sign-tool sign -inFile libcrypto.so.3 -outFile libcrypto.so.3 -selfSign "1"
binary-sign-tool sign -inFile libz.so -outFile libz.so -selfSign "1" || true

批量示例:

cd build
for lib in libcurl.so libcurl.so.4 libssl.so.3 libcrypto.so.3; do
  binary-sign-tool sign -inFile "$lib" -outFile "$lib" -selfSign "1"
done
binary-sign-tool sign -inFile libz.so -outFile libz.so -selfSign "1" || true

运行:

cd build
LD_LIBRARY_PATH="$(pwd)" ./vcpkg --version

预期可见版本信息,例如:

vcpkg package management program version 2999-12-31-unknownhash

便捷脚本示例(run-vcpkg.sh):

#!/bin/sh
cd "$(dirname "$0")/build"
export LD_LIBRARY_PATH="$(pwd)"
exec ./vcpkg "$@"

7.5 已知限制说明

  • binary-sign-tool 对部分较小或非典型 ELF 文件可能报 FILE_NOT_FOUND 等误报;业界反馈中 libz.so 偶发;一般 不影响文件完整性,核心 libcurl / libssl / libcrypto 签名成功即可优先验证主流程。
  • vcpkg 主程序本身 的签名若失败,多数场景下 不影响「只要能加载依赖 .so」的运行路径验证。

8. 完整 CMake 配置示例(全新构建)

以下为一组「可用作起点」的命令;请将所有 /root/... 路径替换为你的 OHOS SDK、vcpkg 安装前缀与依赖包路径

##进入vcpkg-tool目录
cd ~/vcpkg-tool/
# 执行脚本
cmake -S . -B build -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_TESTING=OFF \
  -DCMAKE_TOOLCHAIN_FILE="$OHOS_SDK_ROOT/native/build/cmake/ohos.toolchain.cmake" \
  -DCMAKE_INSTALL_PREFIX=build/install \
  -DVCPKG_DEPENDENCY_EXTERNAL_FMT=OFF \
  -DVCPKG_DEPENDENCY_EXTERNAL_CURL=ON \
  -DVCPKG_DEPENDENCY_EXTERNAL_NLOHMANN_JSON=ON \
  -Dfmt_DIR="/root/ohos_vcpkg/packages/fmt_arm64-ohos/share/fmt" \
  -Dcurl_DIR="/root/ohos_vcpkg/packages/curl_arm64-ohos/share/curl" \
  -Dnlohmann_json_DIR="/root/ohos_vcpkg/packages/nlohmann-json_arm64-ohos/share/nlohmann_json" \
  -DCMAKE_CXX_FLAGS="-I/root/ohos_vcpkg/packages/curl_arm64-ohos/include"

cmake --build build

增量重建:

ninja -C build

清理:

ninja -C build -t clean
# 或彻底删除 build/
rm -rf build

在鸿蒙PC上执行:
拷贝vcpkg可执行文件和依赖的库放到鸿蒙PC上,例如下面的build目录作为测试:

# 鸿蒙 PC 运行前:对依赖 .so 签名(见第 7 节)
cd build
for lib in libcurl.so libcurl.so.4 libssl.so.3 libcrypto.so.3; do
  binary-sign-tool sign -inFile "$lib" -outFile "$lib" -selfSign "1"
done

LD_LIBRARY_PATH="$(pwd)" ./vcpkg --version

9. 常见问题 FAQ

Q1:clang++: warning: argument unused during compilation: '--gcc-toolchain=...'

多为 OHOS Clang 识别了 --gcc-toolchain 但在当前链接模型下未使用所致,一般 可忽略。如需静默可加:

-Wno-unused-command-line-argument

或在 toolchain 中精简该参数的传递(视 SDK 版本而定)。

Q2:明明存在 libcurl.so.4,仍提示找不到?

  1. readelf -S 等工具确认是否已有 鸿蒙 codesign / .ohos.codesign 相关段(具体命令以你环境文档为准)。
  2. 确认 libssl.so.3libcrypto.so.3libz.so 等同路径可得且策略允许加载。
  3. LD_LIBRARY_PATH 是否覆盖 实际放置 .so 的目录;文件名是否与 dlopen 期望一致。

Q3:在鸿蒙 PC 上没有图形界面,如何低成本验证?

可在 x86_64 Linux 上通过容器模拟鸿蒙 PC 运行环境;社区有不少基于 Docker 的搭建文章可参考,例如:

低成本搭建鸿蒙 PC 运行环境:基于 Docker 的 x86_64 服务器(CSDN)

在这里插入图片描述
真机上运行:
在这里插入图片描述


附录:产物自检命令

file ohos_vcpkg/vcpkg
# 示例:ELF 64-bit LSB executable, ARM aarch64, ...

readelf -d ohos_vcpkg/vcpkg | grep NEEDED
readelf -n ohos_vcpkg/vcpkg | grep "Build ID"

readelf -S ohos_vcpkg/libcurl.so.4 | grep -i codesign

readelf -d ohos_vcpkg/libcurl.so | grep -E "SONAME|NEEDED"

LD_LIBRARY_PATH=ohos_vcpkg ohos_vcpkg/vcpkg --version

结语

vcpkg-tool 交叉编译到 鸿蒙 PC(aarch64 OHOS),难点通常集中在三件事:交叉编译下 curl 头文件与宏的一致性FetchContent 的网络与离线兜底、以及 运行时 libcurl 的 dlopen + 系统级签名策略。按本文顺序逐项对齐后,可在宿主机稳定产出 ELF,并在鸿蒙 PC(或容器模拟环境)中完成 vcpkg --version 级别的冒烟验证。


更多分享请访问:猫哥的博客

欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态: 鸿蒙PC开发者社区

Logo

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

更多推荐