让ohos-sdk实现自动代码签名的小技巧
我这里提供一个技巧,可以让编译工具链在编东西的时候直接自动对产物打上代码签名,省去人工操作的繁琐。
前言
当前最新版本的鸿蒙 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
更多推荐


所有评论(0)