
Julia 外部依赖与 JLL 维护实战指南补丁管理、版本升级与校验和刷新【免费下载链接】juliaThe Julia Programming Language项目地址: https://gitcode.com/gh_mirrors/ju/julia本文面向需要修改 Julia 仓库deps/目录外部依赖补丁与版本、或更新任何一个*_jll二进制产物包的开发者系统讲解 Julia 的依赖管理模型、源码构建验证流程、补丁落地规范与校验和刷新机制。读完本文你将能独立完成为某个外部库打补丁并验证源码构建升级依赖版本并同步补丁把某个 JLL 升级到新版本并刷新 checksums这三类日常维护任务。一、这份指南的适用范围Julia 仓库把外部依赖集中托管在deps/目录下把预编译二进制包JLL托管在stdlib/*_jll/目录下。仓库中名为external-deps的维护技能见 SKILL.md明确划定了三类操作场景修改deps/下的依赖版本或deps/patches/下的依赖补丁更新某个*_jll文件夹版本号、Project.toml依赖、校验和任何涉及刷新deps/checksums/中校验和的工作。需要注意这里讨论的外部依赖不包括 stdlib 中的纯 Julia 标准库包那是通过DEPS_GIT与stdlib/子仓库管理的另一套机制本文聚焦于编译期外部 C/C 库及其 JLL 二进制包。二、Julia 外部依赖架构速览deps/、BinaryBuilder 与 JLL2.1 deps/ 目录布局deps/是 Julia 全部第三方构建依赖的集中地从目录结构看分为几类文件deps/name.mk每个依赖一个 Makefile 片段定义下载、解包、配置、编译、安装各阶段规则例如 deps/zlib.mk、deps/gmp.mkdeps/name.version版本元数据文件同时记录 JLL 产物名与源码版本例如 deps/gmp.version 中同时有GMP_JLL_NAME : GMP和GMP_VER : 6.3.0deps/llvm.version 中则有LLVM_JLL_NAME : libLLVM、LLVM_VER : 22.1.8、LLVM_BRANCH、LLVM_SHA1deps/patches/对上游源码的补丁文件集合deps/checksums/每个依赖一份校验和文件如gmp、openblas、llvm也包含部分 stdlib 源码包与 CA 证书等数据文件的校验和deps/tools/核心构建宏包括 git-external.mkgit 源码检出机制与 bb-install.mkBinaryBuilder 产物安装机制由 deps/Makefile 统一 include。2.2 USE_BINARYBUILDER 与 JLL默认行为大多数依赖默认下载 BinaryBuilder 预编译的二进制产物即*_jll包而不是从源码编译。这一默认行为定义在 Make.inc若contrib/normalize_triplet.py能正常解析目标平台 triplet则USE_BINARYBUILDER ? 1默认开启否则回退为0顶层USE_BINARYBUILDER0会全局关闭二进制产物强制全部走源码构建对每个项目SET_BB_DEFAULT宏Make.inc生成USE_BINARYBUILDER_NAME当USE_SYSTEM_NAME1使用系统库或全局USE_BINARYBUILDER0时默认0否则默认1BB_PROJECTS清单Make.inc列出所有走 BB 的依赖如OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB ZSTD P7ZIP LLD LIBTRACYCLIENT BOLT。JLL 的安装由 bb-install.mk 驱动它从stdlib/NAME_jll/Project.toml中读取version字段拼出下载文件名如GMP.v6.3.05.triplet.tar.gz再结合当前平台的BB_TRIPLET生成下载 URL 与校验目标。这正是更新 JLL 版本号要改 stdlib 下的 Project.toml这一流程的底层原因——构建系统以该文件为唯一版本来源。2.3 何时必须走源码构建预编译二进制适用于绝大多数平台但以下场景必须使用源码构建为上游库打补丁需要验证补丁在真实源码上能编译通过依赖某个上游尚未发版的 commit或需要调试依赖本身的 bug平台过于冷门BinaryBuilder 没有提供对应 triplet 的产物。在这些场景下统一做法是把对应依赖的USE_BINARYBUILDER_NAME置 0或全局USE_BINARYBUILDER0触发源码下载-打补丁-编译流程详见 doc/src/devdocs/build/build.md 中 Building a dependency from a Git checkout 一节。三、修改外部依赖deps/ 与 deps/patches/ 的完整流程3.1 第一步始终以 USE_BINARYBUILDER0 验证源码构建修改任何外部依赖补丁或版本后不能只验证预编译二进制路径必须确认源码路径同样能构建成功。这是因为 Julia 的发布与维护流程要求源码构建source build始终可用它既是发行版打包的基础也是排查补丁问题的兜底手段。为什么必须做预编译 JLL 产物里补丁已经打进二进制即使补丁逻辑有误也能蒙混过关而源码构建会真实执行补丁应用与编译任何失败都会立刻暴露。全局关闭所有依赖的二进制产物用make USE_BINARYBUILDER0只针对单个依赖关闭如 LLVM则写入Make.user或命令行USE_BINARYBUILDER_LLVM 03.2 第二步补丁的编写与验证对外部库打补丁SKILL.md 给出了三条硬性要求① 验证补丁能干净应用。运行解包extraction与打补丁patch步骤确认补丁以零冲突方式应用。以 GMP 为例其源码构建链deps/gmp.mk依次是下载 tarball →source-extracted解包并校验→ 按顺序应用gmp-exception.patch、gmp-alloc_overflow.patch、gmp-mpz_realloc.patch→source-patched全部补丁应用完毕的标记→ 进入 configure/compile。任何一步标记文件未生成后续阶段都不会执行因此跑通到build-compiled就等价于补丁干净应用且编译成功。② 测试该依赖的完整构建。直接编译单个依赖跳过无关部分make -C deps USE_BINARYBUILDER0 compile-depname其中depname为依赖小写名例如compile-gmp、compile-zlib。-C deps让 make 在 deps/Makefile 目录下执行。构建系统还提供更细粒度的阶段目标按需使用get-name下载源码、extract-name解包、configure-name配置、compile-name编译、check-name运行上游自带测试如make -C deps USE_BINARYBUILDER0 check-gmp。③ 优先使用 git am 格式的上游完整提交。如果补丁来自上游某个 commit不要手写裸 diff而应使用git format-patch生成包含完整 commit 元数据作者、提交信息的补丁这样 Julia 侧可以用git am应用保留上游的可追溯性同时git format-patch生成的补丁带正确的 diff 头a/、b/前缀与 index 行patch -p1应用时也更稳健。仓库中 deps/patches/libssh2-CVE-2026-55199.patch 一类带序号前缀的补丁即遵循该命名与格式约定。3.3 第三步升级依赖版本时确保所有关联补丁仍适用升级name.version中的*_VER后上游代码基线整体变化旧补丁可能因上下文漂移而无法应用。因此版本升级必须连带执行补丁回归更新deps/name.version中的版本号重新运行解包与打补丁extract-name会以新版本源码为基线逐个确认deps/patches/中所有关联补丁仍能干净应用若某个补丁已包含在上游新版本中应删除该补丁并在deps/name.mk中同步移除其应用规则例如 deps/gmp.mk 中每个补丁对应一段patch-applied规则补丁增删都需维护这里最后跑通make -C deps USE_BINARYBUILDER0 compile-depname全量验证。3.4 源码透视一个补丁的完整生命周期以 GMP 为例deps/patches/中针对 GMP 有三个补丁它们的应用顺序与依赖关系在 deps/gmp.mk 中按 marker 文件串联$(SRCCACHE)/gmp-$(GMP_VER)/gmp-exception.patch-applied: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted cd $(dir $) \ patch -p1 -f $(SRCDIR)/patches/gmp-exception.patch echo 1 $ $(SRCCACHE)/gmp-$(GMP_VER)/gmp-alloc_overflow.patch-applied: .../gmp-exception.patch-applied ... $(SRCCACHE)/gmp-$(GMP_VER)/gmp-mpz_realloc.patch-applied: .../gmp-alloc_overflow.patch-applied ... $(SRCCACHE)/gmp-$(GMP_VER)/source-patched: .../gmp-mpz_realloc.patch-applied echo 1 $这段代码揭示了三层信息补丁按严格顺序串行应用后一个补丁依赖前一个的-applied标记每个补丁的 mark.patch-applied文件记录已成功应用缺任何一个都会阻止source-patched与后续 configure因此验证补丁干净应用在构建系统层面就是让source-patched标记生成最直接的检查命令是make -C deps USE_BINARYBUILDER0 extract-gmp后确认无patch报错。以 deps/patches/gmp-exception.patch 为例其内容是对 GMP__gmp_divide_by_zero函数追加一次真实除零操作确保在 Julia 的浮点异常处理语义下抛出正确的系统异常——这类行为修正型补丁只有源码构建才能真正验证其效果。3.5 仓库中的真实补丁类型浏览 deps/patches/ 可以看到维护中实际存在的三类补丁安全修复CVE backport如libssh2-CVE-2025-15661.patch、libssh2-CVE-2026-55199.patch、libssh2-CVE-2026-66032.patch等将上游安全修复回溯移植到当前锁定版本行为修正如gmp-exception.patch、gmp-alloc_overflow.patch内存分配溢出防护、gmp-mpz_realloc.patch平台适配如libunwind-disable-initial-exec-tls.patch、libunwind-configure-static-lzma.patch、llvm-libunwind-force-dwarf.patch、openblas-winexit.patchWindows 退出处理等。这些补丁的命名规范库名-主题.patch或库名-CVE-编号.patch本身就是新补丁的命名模板。四、更新外部 JLL版本号、Project.toml 与校验和更新一个 JLL如GMP_jll、OpenBLAS_jll、libLLVM_jll到最新版本SKILL.md 给出了三步流程每一步背后都有明确的仓库机制支撑。4.1 步骤一更新 jll 文件夹中的版本号JLL 的版本号记录在stdlib/NAME_jll/Project.toml的version字段。以 stdlib/GMP_jll/Project.toml 为例name GMP_jll uuid 781609d7-10c4-51f6-84f2-b8444358ff6d version 6.3.05注意 Julia 的 JLL 版本号采用X.Y.ZN形式N是 BinaryBuilder 侧的构建号每次 rebuild 递增。构建系统在 bb-install.mk 中通过grep ^version读取该文件自动推导出待下载产物名如GMP.v6.3.05.triplet.tar.gz因此改版本号就是改这个 Project.toml无需手动改任何.mk文件。4.2 步骤二同步 Project.toml 依赖如果上游 JLL 的运行时依赖发生变化例如新增了CompilerSupportLibraries_jll或某个 ABI 相关依赖被替换必须同步更新Project.toml的[deps]段。仍以 stdlib/GMP_jll/Project.toml 为例[deps] Artifacts 56f22d72-fd6d-98f1-02f0-08ddc0907c33 CompilerSupportLibraries_jll e66e0078-7015-5450-92f7-15fbd957f2ae Libdl 8f399da3-3557-5675-b5ff-fb832c97cbdb以及[compat]如julia 1.6与[extras]/[targets]测试目标。遗漏依赖同步会导致运行时加载失败——JLL 的加载 stub见 stdlib/GMP_jll/src/GMP_jll.jl会using CompilerSupportLibraries_jll并依赖Libdl的LazyLibrary依赖列表不完整时这些引用会在加载期报错。4.3 步骤三刷新校验和核心命令版本与依赖更新后需要刷新deps/checksums/中对应的校验和文件make -f contrib/refresh_checksums.mk jll例如contrib/refresh_checksums.mk 注释中的官方示例make -f contrib/refresh_checksums.mk gmp其中jll使用依赖的项目名小写不带_jll后缀如gmp、openblas、llvm、libgit2。不带参数直接运行make -f contrib/refresh_checksums.mk则会刷新所有项目的校验和源码 tarball 全部平台二进制。由于要为每个平台 triplet 重新下载并计算摘要该命令可能耗时几分钟SKILL.md 原文也明确指出 This may take a few minutes。校验和文件的存储格式可从 deps/checksums/gmp 直接看到每行一个条目md5与sha512成对出现GMP.v6.3.05.aarch64-apple-darwin.tar.gz/md5/446a6ce6a7947a95dfce0d32d9b196af GMP.v6.3.05.aarch64-apple-darwin.tar.gz/sha512/22920e0043ea866d89cdbcabb98a14abc... GMP.v6.3.05.x86_64-linux-gnu-cxx11.tar.gz/md5/... GMP.v6.3.05.x86_64-linux-gnu-cxx11.tar.gz/sha512/...命名模式为JLL名.v版本号.triplet.tar.gz/{md5,sha512}/摘要triplet 可能带-cxx11/-cxx03libc ABI与-libgfortranNGCC 工具链 ABI等后缀。这些条目正是 bb-install.mk 中JLCHECKSUM在安装前校验下载文件时核对的内容。4.4 refresh_checksums.mk 内部机制contrib/refresh_checksums.mk 是一个完全独立的 Makefile-f显式指定不依赖主构建其工作原理值得理解便于排查刷新问题平台矩阵TRIPLETSL22硬编码了 18 个支持平台覆盖aarch64/armv6l/armv7l/i686/powerpc64le/riscv64/x86_64架构 × Linux(gnu/musl)/macOS/FreeBSD/Windows 组合项目分类L27-L31BB_PROJECTS走 BinaryBuilder 的常规项目、BB_GCC_EXPANDED_PROJECTSGCC ABI 展开如 openblas、csl、BB_CXX_EXPANDED_PROJECTScxx11/cxx03 双 ABI 展开如 gmp、llvm、clang、lld、NON_BB_PROJECTS纯源码依赖如 patchelf、utf8proc、lmdb目标生成checksum_dep宏L53-L64为每个 (项目, triplet, 特殊构建) 组合生成checksum-name-triplet目标并汇总到checksum-name每个目标先clean-name再调用deps目录中的checksum-name规则如 deps/gmp.mk 的checksum-gmp它对源码 tarball 执行JLCHECKSUM打包整理pack-checksum-%L129-L143把并行计算的散落条目合并、排序写回deps/checksums/name单文件另外通过 L88-L91 的checksum-stdlibs与 L94-L97 的checksum-doc-unicodedata一并刷新 stdlib 源码包与 Unicode 数据文件对应 stdlib/Makefile 的checksumall目标特殊防竞态L99-L123如llvm与llvm-tools、libsuitesparse与suitesparse这类名称互为前缀的项目通过额外依赖规则强制串行执行避免并行打包时互相覆盖。五、维护检查清单完成任何外部依赖或 JLL 变更后按下列清单逐项核对源码构建通过make -C deps USE_BINARYBUILDER0 compile-depname成功且无补丁应用警告补丁可追溯补丁为git format-patch/git am格式含完整 commit 元数据若来自上游 commit文件名含 commit 信息版本-补丁一致性升级*_VER后所有旧补丁仍干净应用已被上游吸收的补丁已删除且.mk中对应规则已同步移除JLL 版本已更新stdlib/NAME_jll/Project.toml的version为最新含N构建号依赖已同步Project.toml的[deps]/[compat]与上游 JLL 声明一致加载 stub 引用的包均已在列校验和已刷新make -f contrib/refresh_checksums.mk name执行完成deps/checksums/name中的 md5/sha512 条目与版本号、triplet 完全对应回归验证对受影响的依赖至少跑一次make -C deps check-name运行上游测试与 Julia 自身的相关测试套件。六、延伸阅读依赖源码构建的完整说明Make.user配置、DEPS_GIT、marker 文件机制doc/src/devdocs/build/build.md校验和刷新的完整 Makefile 实现contrib/refresh_checksums.mk源码依赖构建宏与 JLL 安装宏deps/tools/git-external.mk、deps/tools/bb-install.mkUSE_BINARYBUILDER全局默认逻辑Make.inc补丁与校验和实例目录 deps/patches/、校验和文件 deps/checksums/gmpJLL 示例 stdlib/GMP_jll/Project.toml【免费下载链接】juliaThe Julia Programming Language项目地址: https://gitcode.com/gh_mirrors/ju/julia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考