尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Skia 的 ARM64 Sysroot 资产:在 x86_64 Linux 上交叉编译 C++ 的 sysroot 构建与 CI 使用指南

Skia 的 ARM64 Sysroot 资产:在 x86_64 Linux 上交叉编译 C++ 的 sysroot 构建与 CI 使用指南 图形学【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images. See documentation for contribution instructions.项目地址https://gitcode.com/gh_mirrors/ski/skia点击查看免费下载导读本文以 Skia 仓库中 infra/bots/assets/arm64_sysroot/README.md 为核心深入剖析 Skia 如何在 x86_64 Linux 的 CI 机器上为 ARM64aarch64目标交叉编译 C 代码。你将了解到这套 sysroot 资产目录的文件结构与上传工作流、基于 Docker 的 Debian 交叉编译包装配原理、以及它如何被 Chromebook ARM64 构建任务通过 GN 参数实际消费。读完本文你可以复现该资产的构建过程并理解 Skia 机器人基础设施bot infra中交叉编译工具链资产的完整生命周期。一、资产是什么为 x86_64 主机准备的 ARM64 sysrootarm64_sysroot是 Skia 机器人基础设施infra中管理的一类资产asset。其定位在 README 中写得非常明确ARM64 sysroot for cross-compiling c code on an x86_64 Linux machine.即它是一套在 x86_64 Linux 机器上交叉编译 ARM64 C 代码所需的系统根目录sysroot内含 ARM64 目标的 C/C 标准库头文件、libc/libm等基础库以及交叉链接所需的 binutils 运行时组件。README 同时给出了标准的生产流程Run create_and_upload which installs some debian packages and turns them into a toolchain.也就是说该资产不是手工维护的而是通过脚本安装若干 Debian 交叉编译包再将其变成一个可用的交叉工具链 sysroot。资产目录结构该资产实际由 4 个文件组成文件作用README.md资产用途与创建流程说明Dockerfile定义如何在一个容器内装配出 sysrootcreate.py调用 Docker 构建并提取 sysroot 内容的创建脚本VERSION当前资产版本号内容为4这个目录结构遵循 infra/bots/assets/README.md 约定的通用模板每个资产子目录包含VERSION当前版本号以及可选的create.py由sk asset upload调用的创建脚本、可选的create_and_upload.py用户实现的便捷包装脚本。README中提到的create_and_upload正是指后者这类工作流——README 明确说明Run create_and_upload而arm64_sysroot目录内实际只提供了create.py与 Dockerfile说明完整的便捷脚本是维护者在仓库外按需实现的核心自动化逻辑仍集中在create.py中。二、资产管理与上传工作流在 Skia 的 bot 基础设施中资产统一存放在 Google Storage以版本号命名区分。日常管理通过sk asset命令族完成infra/bots/assets/README.md 给出了完整示例前提是拥有 google.com 账号并通过gcloud auth application-default login完成认证添加一个新资产并上传初始版本$ sk asset add myasset Do you want to add a creation script for this asset? (y/n): n $ sk asset upload --in ${MY_ASSET_LOCATION} myasset $ git commit添加一个可以自动创建的资产$ sk asset add myasset Do you want to add a creation script for this asset? (y/n): y Created infra/bots/assets/myasset/create.py; you will need to add implementation before uploading the asset. $ vi infra/bots/assets/myasset/create.py (implement the create_asset function) $ sk asset upload myasset $ git commit更新一个已有资产这正是arm64_sysroot升级新版本时的标准动作(update the create.py script) $ sk asset upload myasset (assuming infra/bots/assets/myasset/VERSION has been updated by the previous command, regenerate tasks.json per infra/bots/README:) $ make -C infra/bots train $ git commitarm64_sysroot当前版本号为4见 VERSION说明它已经历过至少 4 次迭代——例如跟随 Ubuntu 版本升级、GCC/交叉工具链版本更新而重新生成。每次上传后还需要执行make -C infra/bots train重新生成 infra/bots/tasks.json确保机器人任务引用的是最新 CIPD 包版本。在 tasks.json 中可以看到该资产被引用为skia/bots/arm64_sysroot的 CIPD 包安装路径为arm64_sysroot。三、Dockerfile 深度解读如何安装 Debian 包并变成工具链arm64_sysroot/Dockerfile 是整个装配过程的核心它把安装 Debian 交叉包与整理成 sysroot两步都封装在了可复现的容器构建中。1. 固定基础镜像满足 SLSA Level 1# This was ubuntu:jammy on Jan 8 2025. # Found by running # docker pull ubuntu:jammy docker images --digests | grep ubuntu FROM ubuntusha256:ed1544e454989078f5dec1bfdabd8c5cc9c48e0705d07b678ab6ae3fb61952d2基础镜像是 Ubuntu 22.04jammy在 2025 年 1 月 8 日时的固定 digest。通过锁定镜像摘要digest而非标签构建结果变得完全可复现且符合供应链安全SLSA Level 1要求。2. 安装固定的交叉编译 Debian 包RUN apt-get update \ apt-get install -y --no-install-recommends \ libstdc-12-dev-arm64-cross12.3.0-1ubuntu1~22.04cross1 \ libgcc-12-dev-arm64-cross12.3.0-1ubuntu1~22.04cross1 \ binutils-arm-linux-gnueabihf2.38-4ubuntu2.7 \ rm -rf /var/lib/apt/lists/*注释明确说明这些精确版本号是在 2025 年 1 月 8 日创建镜像时确认可用的固定版本同样是为了满足 SLSA Level 1。三个包各司其职libstdc-12-dev-arm64-crossARM64 目标的 libstdc 头文件与静态/动态库GCC 12libgcc-12-dev-arm64-crossARM64 目标的 libgcc 头文件与库链接时用于提供底层运行时支持binutils-arm-linux-gnueabihf交叉 binutils 组件其中包含的libbfd/libopcodes/libctf等运行时库会被拷贝进 sysroot供链接器linker使用。使用--no-install-recommends避免引入非必要依赖并在安装后清理 apt 缓存保持镜像精简。3. 组装 sysroot 目录ENV TARGET_DIR/tmp/arm64_sysroot_output RUN cp -RL /usr/aarch64-linux-gnu ${TARGET_DIR} \ cp -RL /usr/lib/gcc-cross/aarch64-linux-gnu/12 ${TARGET_DIR}/gcc-cross \ cp /usr/lib/x86_64-linux-gnu/libbfd-2.38-armhf.so ${TARGET_DIR}/lib \ cp /usr/lib/x86_64-linux-gnu/libopcodes-2.38-armhf.so ${TARGET_DIR}/lib \ cp /usr/lib/x86_64-linux-gnu/libctf-armhf.so.0.0.0 ${TARGET_DIR}/lib装配逻辑可以概括为将 Debian 安装的/usr/aarch64-linux-gnu多架构包的标准安装前缀内含头文件与库整体拷贝为 sysroot 根将 GCC-12 交叉编译器配套目录/usr/lib/gcc-cross/aarch64-linux-gnu/12拷贝为gcc-cross子目录后续链接时会用它定位crt*.o、libgcc*.so等把 x86_64 主机上的三个 binutils 运行时.solibbfd、libopcodes、libctf拷贝进 sysroot 的lib/目录确保交叉链接时依赖的库可用。这里一个有意思的细节是libbfd-2.38-armhf.so、libopcodes-2.38-armhf.so的文件名中带有armhf字样但它们是被安装在 x86_64 主机上/usr/lib/x86_64-linux-gnu/的 binutils 运行时组件与之前安装的binutils-arm-linux-gnueabihf包对应——armhf 与 arm64 目标在链接器辅助库层面是共享这套 binutils 运行时的。4. 重写 libc/libm 链接脚本中的绝对路径RUN sed -i s/\/usr\/aarch64-linux-gnu\/lib\///g ${TARGET_DIR}/lib/libc.so \ sed -i s/\/usr\/aarch64-linux-gnu\/lib\///g ${TARGET_DIR}/lib/libm.soDebian 的libc.so/libm.so本质上是链接脚本linker script其中引用的GROUP ( /usr/aarch64-linux-gnu/lib/libc.so.6 ... )等条目带有硬编码的绝对路径。当 sysroot 被整体移动到机器上的任意位置例如 CI 的[START_DIR]/arm64_sysroot时这些绝对路径就失效了。因此 Dockerfile 用sed将/usr/aarch64-linux-gnu/lib/前缀剥离使链接脚本只保留相对文件名让链接器能通过--sysroot正确解析它们——这正是把 Debian 包变成可迁移 toolchain的关键一步。四、create.py从容器到资产目录的两步提取create.py 是一个只允许在 Linux 上运行的 Python 脚本if linux not in sys.platform直接退出它把 Docker 构建与文件提取封装成两步第一步构建本地镜像args [docker, build, -t, arm64_sysroot, ./infra/bots/assets/arm64_sysroot] subprocess.run(args, checkTrue, encodingutf8)以arm64_sysroot为 tag 构建镜像构建产物即上节所述的/tmp/arm64_sysroot_output。第二步挂载目录并拷贝资产args [docker, run, --mount, typebind,source%s,target/OUT % target_dir, arm64_sysroot, /bin/sh, -c, cp -R /tmp/arm64_sysroot_output/* /OUT chmod -R aw /OUT] subprocess.run(args, checkTrue, encodingutf8)通过 bind mount 将--target_dir即sk asset upload提供的资产目标目录挂载为容器内的/OUT把 sysroot 内容拷贝出来。注释特别解释了chmod -R aw的必要性Docker 默认使文件属主为 root若不放开写权限例如删除权限在 bot 上由非 root 用户操作这些文件时会出问题。最终调用方式为python3 infra/bots/assets/arm64_sysroot/create.py --target_dir 目标目录README 中提到的create_and_upload即是在sk asset upload外层再包装一层、自动传入目标目录的便捷脚本。五、资产的真实消费场景Chromebook ARM64 构建sysroot 本身不是终点它最终服务于 Skia 的交叉编译构建。最典型的消费者是 infra/bots/recipe_modules/build/chromebook.py 中的compile_fn它在target_arch arm64分支中直接使用该资产。1. 定位 sysroot 并设置运行环境sysroot_dir os.path.join(top_level, arm64_sysroot) gl_dir os.path.join(top_level, chromebook_arm64_gles) env {LD_LIBRARY_PATH: os.path.join(sysroot_dir, lib)}其中top_level是 bot 的工作目录[START_DIR]arm64_sysroot正是 tasks.json 中该 CIPD 包被拉取到本地的路径。LD_LIBRARY_PATH指向 sysroot 的lib/使链接阶段能加载上节拷入的libbfd/libopcodes/libctf等交叉链接辅助库——这一细节可以在Build-Debian10-Clang-arm64-Debug-Chromebook_GLES的期望输出 full.expected JSON 中直接看到。2. GN 参数中的 sysroot 使用chromebook.py 为 GN 生成的一组关键参数如下结合 chromebook.py 与期望输出 JSON 归纳汇编器/编译器目标asm/c flags--targetaarch64-linux-gnueabihf --sysroot[START_DIR]/arm64_sysroot -marcharmv8-a -mfpuneon -mthumbC/C 头文件搜索路径extra_cflags-I[START_DIR]/arm64_sysroot/include -I[START_DIR]/arm64_sysroot/include/c/12 -I[START_DIR]/arm64_sysroot/include/c/12/aarch64-linux-gnu -I[START_DIR]/chromebook_arm64_gles/include -U_GLIBCXX_DEBUG前三条分别指向 sysroot 的基础头文件、libstdc 头文件以及架构相关的 C 配置头文件include/c/12/aarch64-linux-gnu对应 GCC 12 交叉包第四条指向 Chromebook ARM64 的 GLES 头文件资产-U_GLIBCXX_DEBUG用于关闭调试迭代器以提升性能。链接参数extra_ldflags--targetaarch64-linux-gnueabihf --sysroot[START_DIR]/arm64_sysroot -static-libstdc -static-libgcc -fuse-ld[START_DIR]/clang_linux/bin/ld.lld -B[START_DIR]/arm64_sysroot/bin -B[START_DIR]/arm64_sysroot/gcc-cross -L[START_DIR]/arm64_sysroot/gcc-cross -L[START_DIR]/arm64_sysroot/lib -L[START_DIR]/chromebook_arm64_gles/lib -Wl,-u,__aarch64_swp4_acq_rel -Wl,-u,__aarch64_cas4_acq_rel [START_DIR]/arm64_sysroot/gcc-cross/libgcc.a其设计意图可以逐条解读--sysroot与--target是 clang 交叉编译的基石告诉编译器/链接器以该目录为系统根-static-libstdc -static-libgcc静态链接 C 与 GCC 运行时避免在目标 Chromebook 上依赖特定版本的系统库-fuse-ld使用 clang 自带的ld.lld作为链接器两个-B帮助链接器定位 sysroot 内的交叉汇编器/链接器辅助程序与crt*.o启动文件两个-L提供libgcc*.so与基础库的搜索路径显式链接libgcc.a并引入__aarch64_swp4_acq_rel/__aarch64_cas4_acq_rel符号是为了解决 ARM64 目标上原子操作支持atomics的链接问题。3. 任务编排谁在拉取这个资产资产并不是凭空出现在 bot 上的。infra/bots/gen_tasks_logic/gen_tasks_logic.go 中的任务生成逻辑表明当 bot 带有ChromebookExtraConfig 时会根据架构选择资产组合} else if b.ExtraConfig(Chromebook) { b.asset(clang_linux) if b.Arch(x86_64) { b.asset(chromebook_x86_64_gles) } else if b.Arch(arm) { b.asset(armhf_sysroot) b.asset(chromebook_arm_gles) } else if b.Arch(arm64) { b.asset(arm64_sysroot) b.asset(chromebook_arm64_gles) } ... }可以看到arm64架构的 Chromebook 构建任务会同时拉取三件套clang_linux交叉编译器本身、arm64_sysroot系统根、chromebook_arm64_glesEGL/GLES 头文件与库用于链接 Chromebook 的 GPU 代码。生成后的任务定义沉淀在 infra/bots/tasks.json 中以skia/bots/arm64_sysroot的 CIPD 包形式被引用。六、姊妹资产与升级注意点理解arm64_sysroot的姊妹资产有助于把握整体设计armhf_sysroot面向 32 位 ARMhard float目标同样服务于 x86_64 bot 的交叉编译。其 README 额外提示了一个重要运维经验每当支持的标准升级例如从 C14 到 C17时该资产都需要随之更新——这同样适用于arm64_sysroot因为它决定了对目标系统 C/C 运行时的最低要求chromebook_arm64_gles提供 ARM64 Chromebook 上 EGL/GLES 的 include 与 lib。它的创建流程是从真实 ARM64 Chromebook如 Cherry上打包/usr/lib64与/usr/local/lib64中的库再与本机安装的libgles2-mesa-dev/libegl1-mesa-dev头文件合并。当需要升级arm64_sysroot例如跟随 Ubuntu 新版本或新 GCC时标准流程是修改 Dockerfile更新基础镜像 digest、Debian 包版本运行create.py生成新的 sysroot 内容并检查其完整性执行sk asset upload arm64_sysroot自动更新 VERSION执行make -C infra/bots train重新生成 tasks.json提交代码变更。七、总结arm64_sysroot资产是 Skia 大规模 CI 矩阵中在 x86_64 上交叉编译 ARM64这一能力的地基。从仓库证据可以看到一套完整的工程化链路可复现装配Dockerfile 锁定 Ubuntu jammy 镜像 digest 与精确的 Debian 包版本符合 SLSA Level 1杜绝了环境漂移可迁移性处理通过sed重写libc.so/libm.so链接脚本中的绝对路径让 sysroot 可以部署到 bot 工作区的任意位置版本化分发经 create.py 提取后以版本号当前为 4存入 Google Storage经 CIPD 以skia/bots/arm64_sysroot分发到任务消费端闭环gen_tasks_logic.go 负责在任务生成时拉取该资产chromebook.py 负责把它翻译成--sysroot、extra_cflags、extra_ldflags等一组完整的 GN 交叉编译参数。对于任何需要维护在一种架构的 CI 机器上为另一种架构产出二进制的团队这套Debian 交叉包 → Docker 装配 → 版本化资产 → CIPD 分发 → GN 参数注入的范式都极具参考价值。赞分享图形学【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images. See documentation for contribution instructions.项目地址https://gitcode.com/gh_mirrors/ski/skia点击查看免费下载相关推荐.NET 的 Linux 构建方法论基于 sysroot 交叉编译的 libc 兼容性与供应链安全方案.NET 的 Linux 构建方法论基于 sysroot 交叉编译的 libc 兼容性与供应链安全方案 从 .NET 8 开始dotnet/runtime语言运行时标准库JIT编译编译器在 FreeBSD 上构建 .NET CoreCLRDocker 交叉编译、Linux 交叉编译与直接构建全指南在 FreeBSD 上构建 .NET CoreCLRDocker 交叉编译、Linux 交叉编译与直接构建全指南 本文基于 dotnet/runtime 仓库语言运行时标准库JIT编译编译器Vector 在 Linux 上全面支持 ARMv7 与 ARM64安装、使用与交叉编译构建全解析Vector 在 Linux 上全面支持 ARMv7 与 ARM64安装、使用与交叉编译构建全解析 Vector高性能可观测性数据管道自 0.6.0 版本可观测性数据工程数据集成日志分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表