新闻详情

新闻详情

首页 / 资讯中心 / 详情

Skia 的 clang_linux 工具链资产:Linux 主机 Clang 编译器的构建、发布与 Bazel/GN 消费全解析

发布时间:2026/9/25 6:57:30来源:尧图网络
Skia 的 clang_linux 工具链资产:Linux 主机 Clang 编译器的构建、发布与 Bazel/GN 消费全解析
图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载导读infra/bots/assets/clang_linux/是 Skia 仓库为 Linux 主机维护的一套“编译工具链资产”asset它把从源码构建的 Clang 编译器以及 clang-tidy、include-what-you-useIWYU、LLD、LLVM 符号化/性能工具等打包进 CIPD再镜像到 GCS供 Skia 的 GN 构建与 Bazel 构建统一下载使用。本文以该目录下的 README.md 为主线结合仓库中的 create.py、Dockerfile、download_linux_amd64_toolchain.bzl 与 linux_amd64_toolchain_config.bzl 等源码完整讲解资产里装了什么、如何重新构建、GN 构建如何自动跟随版本、以及手动更新 Bazel 侧工具链的 5 个可复现步骤。读完你可以独立完成一次 Skia Linux Clang 工具链的升级与验证。一、clang_linux 资产是什么根据 infra/bots/assets/clang_linux/README.md 的定位这是一套为 Linux 主机从源码构建的 Clang 编译器及配套工具主要包括Clang / Clang 编译器当前版本对应 LLVM 15.0.1clang-tidy来自 clang-tools-extra 工程include-what-you-useIWYU头文件包含检查工具其他工具如 lld链接器、llvm-symbolizer、llvm-profdata、llvm-cov为 MemorySanitizerMSAN与 ThreadSanitizerTSAN预构建的 instrumented libc/libcabi 运行库从宿主机 glibc 中抽取的libstdc.so.6动态库。该资产被两套构建系统同时消费GN 构建构建脚本直接从解压后的资产目录取用bin/clang、bin/clang等可执行文件Bazel 构建通过download_linux_amd64_toolchain.bzl中的 repository rule 按 sha256 从 GCS 镜像下载解压作为 amd64 Linux 的 C 工具链。资产目录结构如下infra/bots/assets/clang_linux/ ├── README.md # 使用与升级说明本文主体 ├── VERSION # 当前资产版本号当前为 30 ├── create.py # 调用 Docker 构建 clang 并拷贝进 CIPD 目录的脚本 └── Dockerfile # 定义 LLVM 源码构建环境与构建步骤1.1 资产的版本管理约定资产版本由一个纯数字文件 VERSION 维护当前值为30。所有机器人bot在构建前会读取该文件并把版本号通过宏注入到编译命令中例如 default.py 中if compiler Clang and api.vars.is_linux: cc clang_linux /bin/clang cxx clang_linux /bin/clang extra_cflags .append(-B%s/bin % clang_linux) extra_ldflags.append(-B%s/bin % clang_linux) extra_ldflags.append(-fuse-ldlld) extra_cflags.append(-DPLACEHOLDER_clang_linux_version%s % api.run.asset_version(clang_linux, skia_dir))版本号的读取由 recipe_modules/run/api.py 中的asset_version()完成它直接读取infra/bots/assets/asset/VERSION文件内容测试环境下默认值为42。-DPLACEHOLDER_clang_linux_versionN这类宏的作用是一旦 clang 资产版本变化宏值随之改变从而让 Ninja/Bazel 的编译哈希失效强制全量重编避免新旧编译器混用导致的隐性错误。Chromebook 交叉编译场景同样通过 chromebook.py 注入-DREBUILD_IF_CHANGED_clang_linux_version。二、GN 构建自动跟随资产版本README 明确说明“GN 构建会在使用sk工具更新该资产后自动更新”。这里的关键是sk工具与 CIPD 的联动机制更新资产内容修改create.py或Dockerfile后重新生成后运行sk asset upload clang_linux工具会自动调用create.py生成资产内容将内容上传到 CIPD 包skia/bots/clang_linux递增并写回infra/bots/assets/clang_linux/VERSION同时更新infra/bots/tasks.json任务配置因此需要按 infra/bots/assets/README.md 的说明运行make -C infra/bots train重新生成任务并提交。各 CI 任务在编译开始时先读取 VERSION 文件见上文asset_version()再下载对应版本的 CIPD 包编译参数中自动带上版本宏实现“资产升级即构建重编”。因此维护 GN 构建不需要手动改任何构建文件——只要通过sk asset upload clang_linux正常走发布流程GN 侧会“自动更新”。三、手动更新 Bazel 构建五步流程Bazel 侧不会自动跟随sk asset upload需要按 README.md 给出的流程手动同步。下面结合仓库源码把每一步展开。第 1 步从 CIPD 下载最新版本 zip从 CIPD 包页面skia/bots/clang_linux下载最新版本得到 zip 压缩包。第 2 步按 VERSION 重命名把 zip 改名为clang_linux_amd64_vNN.zip其中NN是 VERSION 文件中的新版本号。命名规则必须严格对齐download_linux_amd64_toolchain.bzl中下载时使用的gcs_mirror_only(clang_sha256, .zip)见下文第 4 步Bazel 侧实际上通过 sha256 定位文件文件名主要用于人工可读与排查。第 3 步上传到 GCS 镜像桶使用仓库自带的 gcs_mirror 工具上传README 给出的命令是go run ./bazel/gcs_mirror/gcs_mirror.go --sha256 hash --file /path/to/clang_linux_amd64_vNN.zip结合 gcs_mirror.go 的源码看这个工具通过--sha256校验本地文件完整性以 sha256 作为内容寻址CAS键上传到gs://skia-world-readable/bazel/桶成功后打印https://storage.googleapis.com/skia-world-readable/bazel/sha256.zip形式的镜像地址。工具也支持--url直接镜像远程 URL与--json从 stdin 批量镜像两种模式日常在 Bazel 侧引用新依赖时用的就是 gcs_mirror_url 宏。由于桶是 CAS 语义重复上传同一 sha256 是无害的 no-op。第 4 步更新 sha256在 toolchain/download_linux_amd64_toolchain.bzl 中把clang_sha256更新为新文件的哈希# The clang from CIPD has no prefix, and we download it directly from our GCS bucket # This is clang 15.0.1 and iwyu built from source. clang_sha256 e61f498154e4664d1f16e3b22d4087657205a86d5bd5301d606f5f1d314b133arepository rule_download_linux_amd64_toolchain_impl会据此从镜像下载并校验解压download_linux_amd64_toolchain.bzlctx.download_and_extract( url gcs_mirror_only(clang_sha256, .zip), output , sha256 clang_sha256, )解压位置是 Bazel 外部目录external/clang_linux_amd64对应toolchain/linux_amd64_toolchain_config.bzl中的EXTERNAL_TOOLCHAIN它同时作为工具链的 sysroot 使用。第 5 步本地测试与 BUILD.bazel 修正README 要求用make -C bazel known_good_builds在本地做回归验证同时说明“可能需要更新生成的 BUILD.bazel 以容纳重定位/新增的文件并更新//toolchain/linux_amd64_toolchain_config.bzl使其正确使用这些文件”。需要澄清的是当前仓库快照中bazel/Makefile并不包含known_good_builds目标bazel/Makefile 目前只有 generate、generate_cmake、generate_gni、mocks、gazelle_update_repo 等目标该目标是 Skia 内部持续迭代的验证入口README 中给出的命令面向的是当时或其后端的 Makefile。若当前分支缺少该目标等效的本地验证方式是直接构建依赖该工具链的代表性目标例如bazelisk build //:skia_public bazelisk test //tests/... --test_outputerrors # 视仓库测试配置而定那为什么“可能需要更新 BUILD.bazel”因为解压出的工具链内容头文件、库文件、可执行文件会随 Clang 版本变化。规则在下载后会用ctx.file动态生成一份 BUILD.bazel其中把工具链文件按职责分成几组compile_filesbin/clang、bin/include-what-you-useinclude/c/v1/**、lib/clang/15.0.1/**、usr/include/**等头文件 globlink_filesbin/clang、bin/ld.lld、lib/x86_64-unknown-linux-gnu/libc.a等静态库以及usr/lib/x86_64-linux-gnu/**等 sysroot 库文件 globarchive_filesbin/llvm-arlink_libslibc/libcabi 静态库generated_module_map为系统头文件生成的 modulemap。若新版本 Clang 的头文件路径变化比如lib/clang/15.0.1/include变成lib/clang/16.0.0/include这些 glob 与硬编码路径都需要同步调整而linux_amd64_toolchain_config.bzl中的_make_default_flags()也硬编码了同样的-isystem路径linux_amd64_toolchain_config.bzl因此两处必须保持一致。四、资产是怎么构建出来的Dockerfile 与 create.py理解“更新后要同步哪里”先得知道资产内容从何而来。整个构建由 create.py 驱动docker build -t clang_linux_asset ./infra/bots/assets/clang_linux构建镜像耗时较长产物在镜像内/tmp/clang_outputdocker run --mount typebind,sourcetarget_dir,target/OUT ... cp -R /tmp/clang_output/* /OUT chmod -R aw /OUT把产物拷贝到宿主机的 CIPD 准备目录并递归放开写权限——Docker 默认产出 root 属主文件若不加aw后续 CI 机器人无法删除/覆盖这些文件会导致更新失败。4.1 构建环境的可复现性设计Dockerfile 体现了很强的可复现性追求固定基础镜像基于launcher.gcr.io/google/debian10sha256:3242ff...2022-09-22 的 digest固定依赖版本apt 安装的 cmake、make、python3、clang、lld 等都显式锁版本如cmake3.13.4-1、clang1:7.0-47注释明确说明这是为了满足SLSA level 1供应链安全要求固定 LLVM 源码版本ENV CLANG_RELEASEllvmorg-15.0.1git clone 指定该 tag固定 IWYU 提交git checkout 6d416d5f90755dd76d55c0f33f9ac0de6dd27b5f2022-10 时 iwyu 0.19 尚无 clang 15 分支故锁定当时 tip校验下载物手动安装 ninja 1.8.2 时用 sha256sum 校验。4.2 主 Clang 的构建命令核心 cmake 配置Dockerfilecmake -G Ninja -S llvm -B out \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX${TARGET_DIR} \ -DLLVM_ENABLE_PROJECTSclang;lld;clang-tools-extra \ -DLLVM_ENABLE_RUNTIMESall \ -DLLVM_INSTALL_TOOLCHAIN_ONLYON \ -DLLVM_USE_LINKERlld \ -DLLVM_ENABLE_UNWIND_TABLESOFF \ -DLLVM_ENABLE_TERMINFOOFF \ -DLLVM_EXTERNAL_PROJECTSiwyu \ -DLLVM_EXTERNAL_IWYU_SOURCE_DIR/tmp/iwyu要点解读-DLLVM_ENABLE_PROJECTSclang;lld;clang-tools-extra产出 clang、lld 与 clang-tidy-DLLVM_ENABLE_RUNTIMESall一次构建 libc、libcabi、compiler-rt 等全部运行时-DLLVM_USE_LINKERlld先用系统 clang 7 把 lld 编出来再用 lld 链接后续产物解决编译器自举阶段用内置 ld 编 compiler-rt 失败的问题-DLLVM_EXTERNAL_PROJECTSiwyu把 IWYU 作为外部工程并入本次构建ninja -C out install后 IWYU 即随工具链一起安装。安装后 Dockerfile 还做了三处补充DockerfileRUN cp out/bin/llvm-symbolizer out/bin/llvm-profdata out/bin/llvm-cov ${TARGET_DIR}/bin RUN cp c -print-file-namelibstdc.so.6 ${TARGET_DIR}/lib复制 llvm-symbolizer让 sanitizer 崩溃栈可符号化、llvm-profdata / llvm-cov供覆盖率与性能剖析使用复制宿主 Debian 10 的libstdc.so.6到资产lib/目录——后续 GN 构建里-Lclang_linux/lib即可让链接找到它。4.3 MSAN / TSAN 专用 libc 的构建Dockerfile 的第二阶段用刚编译好的新 clangENV CC${TARGET_DIR}/bin/clang重新构建两套插桩版运行时# TSANThread 插桩 cmake -G Ninja -S runtimes -B tsan_out \ -DCMAKE_BUILD_TYPERelease \ -DLLVM_ENABLE_RUNTIMESlibcxx;libcxxabi \ -DLLVM_USE_SANITIZERThread ninja -C tsan_out cxx cxxabi cp -r tsan_out/lib ${TARGET_DIR}/tsan # MSANMemoryWithOrigins 插桩 cmake -GNinja -S runtimes -B msan_out \ -DCMAKE_BUILD_TYPERelease \ -DLLVM_ENABLE_RUNTIMESlibcxx;libcxxabi \ -DLLVM_USE_SANITIZERMemoryWithOrigins ninja -C msan_out cxx cxxabi cp -r msan_out/lib ${TARGET_DIR}/msanDockerfile 注释特别强调MSAN/TSAN 运行库的构建必须从runtimes子目录启动而不是像主构建那样从llvm子目录启动bootstrapping-build 文档的常规路径会在这里踩坑社区讨论见 stackoverflow 73827100。官方 MemorySanitizer libc 构建指南当时已过时因此这里采用直接配置runtimes的方式。这两套产物在 CI 中的消费点在 default.pyMSAN 任务给链接器追加-Lclang_linux/msanTSAN 任务追加-Lclang_linux/tsan普通 Linux 任务则用-Lclang_linux/libSwiftShader 的 CMake 构建还会通过-fsanitizememory / -fsanitizethread与-lcabi消费对应目录见 default.py。五、Bazel 工具链如何消费这份资产5.1 下载与 sysroot 组装Bazel 侧通过 download_toolchains.bzl 注册工具链其中clang_linux_amd64: download_linux_amd64_toolchain对应本资产。download_linux_amd64_toolchain这个 repository rule 除了下载 clang zip还会从 Debian 官方仓库下载并解压一批 .deb 包download_linux_amd64_toolchain.bzl来拼出完整 sysroot包括glibc 三件套libc6、linux-libc-dev、libc6-dev固定使用 Debian 10 buster 的 glibc 2.28——因为当时许多 Swarming 宿主机仍是 Debian 10编译产物需要能在其上运行X11 栈libx11-dev、libxcb*、libxau*、libxdmcp*Bazel 构建的 Skia 需要 X11 头文件与库GL 栈libgl-dev、libglx*、libgl1、libglu1-mesa*、libegl-dev、libgles-dev字体与 Rust 链接libfontconfig*、libgcc-s1。每个 .deb 都锁定了 sha256 与具体版本下载同样走gcs_mirror_url。_download_linux_amd64_toolchain_impl还会做两件事建立lib/x86_64-linux-gnu/libgcc_s.so符号链接让-lgcc_s可用针对builtin_include_directoriesinclude/c/v1、lib/clang/15.0.1/include、usr/include等调用 clang_layering_check.bzl 生成系统头文件 modulemap用于 Clang 模块化构建的包含层级检查。5.2 工具链配置中的关键默认 flaglinux_amd64_toolchain_config.bzl 定义了对本资产的全部使用方式几个值得注意的细节sysroot 即工具链根目录builtin_sysroot EXTERNAL_TOOLCHAIN即external/clang_linux_amd64。原因在源码注释中解释得很清楚libc 的动态库被解压到.../lib而头文件与 .so 引用在.../usr下libc.so其实是引用/lib/x86_64-linux-gnu/libc.so.6的文本文件把顶层目录设为 sysroot 后链接器才能解析这些绝对路径trampoline 脚本Bazel 只允许执行EXEC_ROOT/toolchain下的可执行文件而真正的 clang 在external/下因此 action_config 通过linux_trampolines/clang_trampoline_linux.sh、ar_trampoline_linux.sh间接调用linux_amd64_toolchain_config.bzl编译 flag-stdc17 -stdliblibc头文件搜索顺序经过精心排列include/c/v1→include/x86_64-unknown-linux-gnu/c/v1→usr/include→lib/clang/15.0.1/include→usr/include/x86_64-linux-gnu并加了-no-canonical-prefixes防止 clang 用绝对路径找头文件导致 Bazel 判定越界链接 flag-fuse-ldlld、--rtlibcompiler-rt并静态链接libc.a、libcabi.a、libunwind.a避免开发者机器上缺少 libc 动态库glibc 的动态部分-lpthread -lm -ldl则保持动态链接可诊断特性--features diagnostic编译/链接加-v、--trace-includes、-Wl,--verbose、--features print_search_dirs链接失败但打印库搜索路径IWYU 渐进式开启--features skia_enable_iwyu会在编译命令中注入-DSKIA_ENFORCE_IWYU该宏对 clang 本身无影响只作为信号被 clang_trampoline.sh 识别按目录白名单决定是否调用 include-what-you-use同时注入-DSKIA_SKIP_LINKING跳过链接以节省时间linux_amd64_toolchain_config.bzl。六、实操一次完整的 clang_linux 升级演练把 README 的流程与源码细节整合成一份可直接照做的清单面向拥有 CIPD/GCS 权限的仓库维护者改构建配置按需修改 Dockerfile升级CLANG_RELEASEtag、apt 依赖版本、IWYU 提交号等生成新资产python3 infra/bots/assets/clang_linux/create.py --target_dir /tmp/clang_new得到新的工具链目录走标准资产发布sk asset upload clang_linux自动调用 create.py、上传 CIPD、递增 VERSION、更新 tasks.json然后make -C infra/bots train重新生成任务并提交——这一步完成后GN 构建自动跟进无需改 GN 文件同步 Bazel从 CIPD 下载新 zip重命名为clang_linux_amd64_v新版本.zip计算 sha256sha256sum clang_linux_amd64_v新版本.zip上传镜像go run ./bazel/gcs_mirror/gcs_mirror.go --sha256 hash --file /path/to/clang_linux_amd64_v新版本.zip更新 download_linux_amd64_toolchain.bzl 中的clang_sha256检查并同步linux_amd64_toolchain_config.bzl中的-isystem路径与lib/clang/新版本/路径、生成 BUILD.bazel 中的 glob版本路径变化时必须改验证运行make -C bazel known_good_builds若当前分支无此目标则直接bazelisk build //:skia_public等代表目标再抽查一个 CI 任务编译确认无重定位/头文件路径问题后提交。七、常见问题与排查要点升级后编译报找不到头文件优先检查 linux_amd64_toolchain_config.bzl 的-isystem顺序与builtin_include_directories、生成 BUILD.bazel 的 glob 是否仍指向lib/clang/旧版本链接报 libc 相关错误确认 sysroot 设置仍为external/clang_linux_amd64且lib/x86_64-linux-gnu/libgcc_s.so符号链接存在download_linux_amd64_toolchain.bzlGN 构建没有重编确认 VERSION 已递增且编译参数中的PLACEHOLDER_clang_linux_version/REBUILD_IF_CHANGED_clang_linux_version宏已变化default.py、chromebook.pysanitizer 任务异常检查-Lclang_linux/msan、-Lclang_linux/tsan指向的插桩 libc 是否随资产一起更新Dockerfile 的tsan_out/msan_out产物。结语infra/bots/assets/clang_linux/是 Skia 双构建系统GN Bazel在 Linux 主机上共用的编译器资产GN 通过sk asset upload自动跟随Bazel 则需要按 README 的五步流程手动同步 sha256 与工具链配置。理解 Dockerfile 的构建细节固定版本、LLVM 15.0.1、IWYU、MSAN/TSAN 运行库与 download_linux_amd64_toolchain.bzl 的消费方式zip deb sysroot 生成 BUILD.bazel你就能在升级 Clang 时同步处理好 GN、Bazel 与 CI 三方的版本一致性避免“编译器换了、编译缓存没失效”或“头文件路径漂移”这两类最典型的构建事故。赞分享图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载相关推荐Skia 的 clang_ubuntu_noble 工具链资产Linux 自研 Clang 编译器的构建、分发与 Bazel/GN 集成指南Skia 的 clang_ubuntu_noble 工具链资产Linux 自研 Clang 编译器的构建、分发与 Bazel/GN 集成指南 导读 本文围绕图形学Skia clang_linux 工具链资产深度解析CIPD 构建、GCS 镜像与 Bazel/GN 双构建集成Skia clang_linux 工具链资产深度解析CIPD 构建、GCS 镜像与 Bazel/GN 双构建集成 导读 本篇文章围绕 Skia 仓库中 inf图形学Flutter Engine编译工具链GN构建系统与前端服务器Flutter Engine编译工具链GN构建系统与前端服务器 本文详细解析了Flutter Engine的编译工具链架构重点介绍了GN构建系统的配置管理、跨平台图形学前端上一篇MP4Box.js高级用法自定义MP4盒子解析与扩展开发下一篇Argo Workflows 使用 emptyDir 卷解决输出 Artifacts/Parameters 收集问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Atlas 300V 24G推理加速卡如何高效部署YOLOv5?昇腾平台实战解析 2026/9/25 7:34:45

Atlas 300V 24G推理加速卡如何高效部署YOLOv5?昇腾平台实战解析

先说结论:Atlas 300V 24G 确实是一张运算加速卡,但它和大众理解的“GPU 通用计算卡”不是一回事。如果你手头有这张卡,或者正在调研用昇腾平台部署 YOLO,那么这篇内容应该能帮你省掉不少弯路。我最近刚好基于 Atlas 300V 24G 完整…

阅读更多 →
重庆市家庭人口信息平台服务器地址解析与实操指南 2026/9/25 7:34:45

重庆市家庭人口信息平台服务器地址解析与实操指南

1. 从一份文档名说起:这个平台到底在解决什么问题第一次看到“重庆市家庭人口信息平台服务器地址”这个标题,很多人第一反应是:这不就是个内部系统的访问入口吗,有什么好聊的。但真在政务信息化、人口数据管理或者基层社区数字化这…

阅读更多 →
Atlas 300V 24G推理加速卡部署YOLO实战:从ONNX到OM全流程 2026/9/25 7:34:45

Atlas 300V 24G推理加速卡部署YOLO实战:从ONNX到OM全流程

1. Atlas 300V 24G到底是什么卡:一张图看懂它的定位先说结论:有人在热搜里问“Atlas 300V 24G是运算加速卡吗”,答案是肯定的——它是运算加速卡,但更准确的说法是AI推理加速卡。很多刚接触昇腾生态的同学,看到Atlas这…

阅读更多 →
ScienceDirect高效检索与Elsevier投稿全流程攻略 2026/9/25 7:34:45

ScienceDirect高效检索与Elsevier投稿全流程攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Atlas 300V 24G推理卡部署YOLOv5全流程实战与避坑指南 2026/9/25 7:34:39

Atlas 300V 24G推理卡部署YOLOv5全流程实战与避坑指南

开篇先把话说清楚:以“atlas”这个词搜到我这篇内容的人,大部分不是来看星座神话的,而是手里已经拿到或正打算入手一张华为 Atlas 300V 推理卡,想在上面把 YOLO 跑起来。这卡在深度学习圈子里一直有点“低调”,官方资料…

阅读更多 →
Atlas 300V Pro 24G推理加速卡部署YOLO全流程实战 2026/9/25 7:34:39

Atlas 300V Pro 24G推理加速卡部署YOLO全流程实战

跑AI推理的工程师,最近应该没少在各种群里看到“Atlas部署YOLO”这类话题。尤其当热搜词里同时出现“atlas 300v 24g 是运算加速卡吗”这种问题时,我意识到很多刚接触昇腾推理的开发者,对这块卡的身份定位、部署链路和性能边界,其…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉