前言

当前最新版本的鸿蒙 PC 系统已经支持在终端(HiShell)里面直接运行二进制了,打 hnp 不再是运行二进制的唯一渠道。

但这有一个前提条件:这个二进制以及它所加载的 so 必须要有代码签名。无论是正式签名还是自签名都可以,只要有签名就行。

当前我见到网上的博客里面做法基本上都是用 ohos-sdk 编完东西之后再用 ohos-sdk 里面的签名工具手动做一次签名。这样的手工操作较为繁琐,尤其是涉及到大量二进制或 so 的时候就会更繁琐。

我这里提供一个技巧,可以让编译工具链在编东西的时候直接自动对产物打上代码签名,省去人工操作的繁琐。

大致思路

我这个技巧是建立在这个 PR 的基础之上的:https://gitcode.com/openharmony/third_party_llvm-project/pull/882

这是 OpenHarmony 社区的人往 ohos-sdk 里面的 LLVM 添加的一个特性:如果链接器收到了 --code-sign 参数,它就会自动对生成出来的 ELF 文件做自签名。

这相比于手工签名已经便利很多了,但每次编东西要额外加一个链接器参数还是会有点影响体验。

为了把这最后一步的体验问题也优化掉,我选择对调用链接器的流程做一点改造,让 clang 驱动器在调用链接器的时候一定携带这个参数,那就能实现自动签名的效果了。

操作流程

我这里以交叉编译的场景为例进行演示,我使用的构建机是 Ubuntu 24.04 x64。

1. 升级 ohos-sdk

首先,为了使用这个最新的链接器签名特性,我们需要把 ohos-sdk 换成最新的日构建版本。ohos-sdk 6.0 正式版是不行的,比较旧的日构建版本也不行。

我这里就下载一份今天(1 月 11 日)的日构建版本

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 -q native-*.zip
cd -

2. 将 ld.lld 改成封装脚本

把 ld.lld 这个软链接删掉,然后写一个同名的封装脚本

cd ohos-sdk/linux/native/llvm/bin
rm ld.lld
lld_absolute_path=$(realpath lld)
printf '#!/bin/bash\nexec -a "$0" %s --code-sign "$@"\n' "$lld_absolute_path" > ld.lld
chmod 0755 ld.lld
cd -

从软链接改成脚本之后,clang 在进行链接的时候就会调用到这个脚本,再通过这个脚本去调用 lld,这样就每次都会把 --code-sign 参数带上。

3. 验证是否生效

随便写个 hello world 编一下

export PATH=$PATH:$(realpath ohos-sdk/linux/native/llvm/bin)
echo -e '#include <stdio.h>\nint main(void) {\n    printf("Hello, world!\\n");\n    return 0;\n}' > helloworld.c
clang --target=aarch64-linux-ohos helloworld.c -o helloworld

验证一下看看编出来的二进制有没有 .codesign 段

llvm-readelf -S helloworld

你会看到里面包含这么一段数据(我只截取了部分内容),里面有 .codesign 段

  [34] .symtab           SYMTAB          0000000000000000 001de0 000990 18     36  91  8
  [35] .shstrtab         STRTAB          0000000000000000 002770 000178 00      0   0  1
  [36] .strtab           STRTAB          0000000000000000 0028e8 0002f9 00      0   0  1
  [37] .codesign         PROGBITS        0000000000000000 003000 001000 00      0   0 4096

现在签名已经有了,这个产物直接下载到 PC 上就能跑了。

常见问题

1. 下载 url 失效

日构建版本的产物过期策略并不透明,有时候一年都不会过期,有时候一个月就过期了。

如果你刚好碰到文中的下载链接过期了,这里有两个处理办法:1. 去网页上下载最新的;2. 用脚本下载最新的。

网页的话就是这个网页:https://dcp.openharmony.cn,对着我的截图去找这个产物就行

在这里插入图片描述

脚本的话可以这么写

query_component() {
  component=$1
  curl -fsSL 'https://dcp.openharmony.cn/api/daily_build/build/list/component' \
    -H 'Accept: application/json, text/plain, */*' \
    -H 'Content-Type: application/json' \
    --data-raw '{"projectName":"openharmony","branch":"master","pageNum":1,"pageSize":10,"deviceLevel":"","component":"'${component}'","type":1,"startTime":"2025080100000000","endTime":"20990101235959","sortType":"","sortField":"","hardwareBoard":"","buildStatus":"success","buildFailReason":"","withDomain":1}'
}

sdk_download_url=$(query_component "ohos-sdk-public" | jq -r ".data.list.dataList[0].obsPath")
curl -o ohos-sdk-public.tar.gz $sdk_download_url
Logo

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

更多推荐