ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Zcash depends 依赖构建系统详解:交叉编译、缓存机制与包配方实战

Zcash depends 依赖构建系统详解:交叉编译、缓存机制与包配方实战 Zcash depends 依赖构建系统详解交叉编译、缓存机制与包配方实战【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash本篇技术指南聚焦 Zcash 仓库中depends/目录所实现的依赖构建系统它能够在当前主机上为任意目标平台Windows、macOS、Linux ARM/RISC-V 等交叉编译并缓存全部第三方依赖并生成可供configure直接使用的工具链前缀目录。读完本文你将掌握make/make HOST...的基本用法、SOURCES_PATH等依赖选项的语义、download系列附加目标以及系统底层的构建 ID 缓存机制与包配方recipe编写规范并能结合源码定位每个环节的实现位置。一、depends 是什么为 Zcash 构建可移植、可缓存、可复现的依赖depends/是一套独立于主构建系统的依赖构建与缓存子系统。与大多数同类系统不同它的设计目标详见 depends/description.md决定了它在 Zcash 发布流程中的核心地位与构建机/目标机解耦builder and host agnostic理论上任何 OS/架构的构建机都能产出任意目标平台的二进制。实践中当默认配置不适用时需要显式指定构建侧工具且包配方需要针对新平台进行适配。当前版本默认以 x86_64Linux 或 macOS作为构建架构。不依赖时间戳系统用文件是否存在来判断哪些包需要构建而非比较时间戳。这使得构建结果可以分发也便于自动化构建机消化处理。每次构建只暴露声明的依赖每个包的构建都会清空 sysroot 并安装其递归依赖避免未知文件造成副作用从而保证构建的确定性。按需缓存与重建每个包在构建前会生成唯一 build-id该 id 是对构建该包所用全部文件Makefile、包配方等以及所有递归依赖的哈希。配方一变该包及其依赖它的包全部重建Makefile、funcs.mk等主文件一变所有包全部重建。构建结果被缓存为 tarball可复用、可分发。源码自动获取与校验每个包必须定义源码位置与 checksum获取到的源码不匹配即构建失败源码可预置或按需缓存。自清理构建与 staging 目录在使用后被清空成功构建后旧的缓存结果也会被移除自动化构建机无需人工干预即可逐版本构建并归档结果。这套机制保证了 Zcash 每个发布版本所依赖的第三方库如 Boost、libevent、libsodium、Rust 工具链等在全部目标平台上行为一致、可复现。二、快速开始为当前架构构建全部依赖进入 depends 目录 后为当前架构 操作系统构建依赖只需一条命令make执行后系统会依据config.guess探测当前构建平台见 depends/Makefile读取hosts/host_os.mk、builders/build_os.mk、packages/packages.mk等配置depends/Makefile为所有包计算 build-id按依赖拓扑依次完成 下载 → 解压 → 预处理 → 配置 → 编译 → 暂存 → 缓存 的流水线最终在depends/host/下生成带share/config.site的前缀目录并可选执行 Rust crate 的 vendor 操作。构建完成后前缀目录可以直接作为主项目configure的--prefix使用见下文第三节。若需要并行加速直接追加-j即可make -j$(nproc)三、交叉编译HOST 平台三元组详解为其他架构/操作系统构建依赖使用make HOSThost-platform-tripletmake HOSTx86_64-w64-mingw32 -j4HOST采用标准的 GNU canonical host 三元组格式arch-vendor-os。系统会据此生成一个前缀目录上例为x86_64-w64-mingw32其中包含该目标平台所需的全部交叉编译工具链与库。然后将其接入主项目 configure./configure --prefixpwd/depends/x86_64-w64-mingw32depends会自动把交叉编译器路径、CFLAGS/CXXFLAGS/LDFLAGS、Rust target 等写入$(host_prefix)/share/config.site生成逻辑见 depends/Makefileautoconf 在读取--prefix指定的前缀目录时会自动加载其中的config.site因此正如原文档所述——除HOST外无需其他选项路径会自动配置。常见的host-platform-triplets包括三元组目标平台i686-w64-mingw32Win32x86_64-w64-mingw32Win64x86_64-apple-darwin18macOSarm-linux-gnueabihfLinux ARM 32 位aarch64-linux-gnuLinux ARM 64 位riscv32-linux-gnuLinux RISC-V 32 位riscv64-linux-gnuLinux RISC-V 64 位以 Win64 为例完整的交叉构建链路为cd depends make HOSTx86_64-w64-mingw32 -j4 cd .. ./configure --prefixpwd/depends/x86_64-w64-mingw32 make -j4平台相关的编译选项在depends/hosts/目录中按host_os命名维护如 depends/hosts/linux.mk、depends/hosts/darwin.mk、depends/hosts/freebsd.mk、depends/hosts/mingw32.mk。例如 Linux 目标默认CFLAGS-pipe、release 为-O3、debug 为-O0并在交叉编译时自动追加-idirafter /usr/host/include与-L/usr/host/libdepends/hosts/linux.mkmacOS 目标则通过clang -target ... --sysroot $(OSX_SDK)指定 SDK 路径并强制使用 SDK 内的 libc 头文件depends/hosts/darwin.mk。需要说明的是原 README 示例中的x86_64-apple-darwin18与系统内置的download-osx目标所用的x86_64-apple-darwin14见下文第六节存在版本差异实际使用时以你选择的 HOST 三元组为准二者都指向 macOS 目标。四、依赖选项用make FOObar定制构建下列选项在调用 make 时以make FOObar的形式传入depends/Makefile 给出了它们的默认值选项作用默认值SOURCES_PATH下载的源码压缩包存放位置depends/sourcesBASE_CACHE已构建包的缓存存放位置depends/builtSDK_PATHSDK 的查找路径macOS 构建使用depends/SDKsFALLBACK_DOWNLOAD_PATH上游源码下载失败时的备用镜像路径Zcash 官方维护的depends-sources镜像NO_WALLET不下载/构建/缓存启用钱包所需的库空构建钱包依赖DEBUG关闭部分优化并开启更多运行时检查空默认 release 构建典型用法# 复用已有源码与缓存避免重复下载/编译 make SOURCES_PATH/data/mirror/zcash-sources BASE_CACHE/data/ci/zcash-built # 构建不带钱包依赖的版本 make NO_WALLET1NO_WALLET 与 configure 选项传递若某些包未构建例如make NO_WALLET1对应的选项会自动传递给主项目的 configure。原文档明确说明在这种情况下会向 configure 传递--disable-wallet。从源码看depends/Makefile 通过wallet_packages_$(NO_WALLET) $(wallet_packages)这一技巧在NO_WALLET非空时把钱包相关包排除出packages列表并将NO_WALLET的值写入config.site-e s|no_wallet|$(NO_WALLET)|见 depends/Makefile供主项目 configure 读取。DEBUG 的具体影响默认所有构建均为 releaserelease_typerelease见 depends/Makefile。当设置DEBUG1后编译标志切换到 debug 档例如 Linux 目标从-O3降为-O0并追加-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC开启 libstdc 的调试容器检查depends/hosts/linux.mkmacOS 目标同样切换为-O0depends/hosts/darwin.mk。五、附加目标download 系列depends 提供了“只下载、不构建”的附加目标便于镜像源码或离线预置make download # 拉取全部目标平台所需源码 Rust crate make download-osx # 仅拉取 macOS 构建所需源码 make download-win # 仅拉取 Windows 构建所需源码 make download-linux # 仅拉取 Linux 构建所需源码从 depends/Makefile 的实现看三个平台目标分别是download-osx: $(MAKE) -s HOSTx86_64-apple-darwin14 download-one download-linux: $(MAKE) -s HOSTx86_64-pc-linux-gnu download-one download-win: $(MAKE) -s HOSTx86_64-w64-mingw32 download-onedownload-one依赖check-sources与$(all_sources)前者校验已缓存源码的 checksum缺失或损坏则强制重新下载depends/Makefile后者逐一触发每个包的fetch步骤。Zcash 特有的 crate 下载make download还会额外执行download-cratesdepends/Makefile先构建native_rust再用 cargo 依据仓库根目录的 Cargo.toml 执行cargo vendor --locked将全部 Rust 依赖打包为vendored-crates.tar.gz归档供后续构建离线使用。六、原理深度构建 ID、缓存与流水线这一节解开“为什么依赖会按需重建、结果可缓存”的谜底核心实现全部位于 depends/funcs.mk。步骤化流水线每个包都被拆分为fetched → extracted → preprocessed → configured → built → staged → postprocessed → cached多个 make 目标每个目标以.stamp_*文件作为完成标记depends/funcs.mk。目标之间存在严格依赖链例如configured依赖preprocessed且配置前会先把该包全部依赖的缓存 tarball 解压到宿主前缀目录保证“每次构建只暴露声明的依赖”depends/funcs.mk。build-id 的计算int_get_build_recipe_hash先对主 makefile、funcs.mk、平台配置以及该包的补丁文件做 SHA-256得到recipe_hashdepends/funcs.mk随后int_get_build_id递归收集全部依赖将每个依赖的package-version-recipe_hash串起来再次哈希截取前 11 个字符作为该包的build_iddepends/funcs.mkHASH_LENGTH:11定义于 depends/Makefile。因此包配方或补丁变化 → 该包及其所有下游依赖的 build-id 变化 → 全部重建主构建文件变化 → 所有包的recipe_hash变化 → 全量重建。缓存与校验构建产物以package-version-build_id.tar.gz形式存放于$(BASE_CACHE)/host/package/并生成同名.hash校验文件depends/funcs.mk。make check-packages会对缓存逐一做 SHA-256 校验不一致则强制重建depends/Makefile。同一 build-id 的缓存可被复用也可随构建结果一起分发。源码获取与校验fetch_file先检查源码是否已存在于SOURCES_PATH否则下载临时文件并在下载后立即用包定义的 sha256 校验失败则回退到FALLBACK_DOWNLOAD_PATHdepends/funcs.mk。解压前还会再做一次校验depends/funcs.mk确保任何一次构建都用经过验证的源码。七、包配方结构如何添加一个包depends/packages.md 定义了每个包配方packages/package.mk的三部分结构标识符identifiers→ 构建变量build variables→ 构建命令build commands。必填标识符$(package)_version、$(package)_download_path、$(package)_file_name、$(package)_sha256_hash。可选标识符$(package)_build_subdir配置/构建前进入的子目录、$(package)_download_file本地存储名与上游文件名不一致时使用、$(package)_dependencies依赖的其他包、$(package)_patches补丁文件列表、$(package)_extra_sources通过make download一并获取校验的附加文件。构建变量在define $(package)_set_vars ... endef中定义cc/cxx/ar/ranlib/nm、cflags/cxxflags/ldflags/cppflags、config_env/build_env/stage_env、build_opts/config_opts等。所有变量都支持按 host、架构或两者组合进行平台化覆盖如$(package)_linux_cc、$(package)_x86_64_cc、$(package)_x86_64_linux_cc也支持 debug/release 后缀如$(package)_cflags_release-O3。默认 build 的 release_type 为 release除非用户设置DEBUG1。构建命令每个包可自定义fetch_cmds、extract_cmds、preprocess_cmds、config_cmds、build_cmds、stage_cmds分别在不同目录下运行且均有默认行为。配方内可用的路径变量包括$(1)_staging_dir、$(1)_staging_prefix_dir、$(1)_extract_dir、$(1)_build_dir、$(1)_patch_dir。autotools 项目可直接使用$($(package)_autoconf)自动生成配置命令内部展开为./configure --host... --prefix... CC... CXX...并追加各 flags见 depends/funcs.mk安装阶段推荐$(MAKE) DESTDIR$($(package)_staging_dir) install。输出约定包的输出不应包含 libtool archive.la文件而是尽量输出.pcpkg-config文件避免过度链接引发不必要的级联重建。静态链接约定相对于 Zcash 二进制/库的“次级依赖”即不在contrib/devtools/symbol-check.py的ALLOWED_LIBRARIES中的依赖应构建为静态库。理由是便于安全更新、保证共识兼容、简化调试复现并避免共享库-rpath依赖链带来的链接问题。以 depends/packages/libsodium.mk 为例一个真实配方的骨架如下packagelibsodium $(package)_version1.0.20 $(package)_download_pathhttps://download.libsodium.org/libsodium/releases/ $(package)_file_name$(package)-$($(package)_version).tar.gz $(package)_sha256_hashebb65ef6ca439333c2bb41a0c1990587288da07f6c7fd07cb3a18cc18d30ce19 $(package)_dependencies $(package)_patches1.0.15-pubkey-validation.diff 1.0.15-signature-validation.diff \ 1.0.20-immintrin-conflict.diff 1.0.22-evex512-fix.patch define $(package)_preprocess_cmds patch -p1 $($(package)_patch_dir)/1.0.15-pubkey-validation.diff \ ... cd $($(package)_build_subdir); DO_NOT_UPDATE_CONFIG_SCRIPTS1 ./autogen.sh endef define $(package)_config_cmds $($(package)_autoconf) --enable-static --disable-shared endef define $(package)_build_cmds $(MAKE) endef define $(package)_stage_cmds $(MAKE) DESTDIR$($(package)_staging_dir) install endef它完整演示了“定义标识符 → 打补丁 → autoconf 配置静态链接→ 编译 → DESTDIR 安装”的标准模板。八、平台与工具链配置hosts 与 buildersdepends 把配置拆为三层depends/hosts/host_os.mk目标平台配置编译标志、链接器、SDK 等例如 darwin 目标定义OSX_MIN_VERSION10.14、OSX_SDK路径以及native_cctools作为原生 binutils/工具链depends/hosts/darwin.mk。depends/builders/build_os.mk构建机配置例如 Linux 构建机的build_CC等工具链查找逻辑以及download、sha256sum等构建侧工具depends/builders/default.mk。depends/packages/*.mk各依赖包配方。工具链本身也被建模为包native_clang.mk、native_cctools.mk、native_rust.mk等见 depends/packages/ 目录。其中 depends/packages/native_rust.mk 展示了 Zcash 对 Rust 工具链的深度集成定义rust_target宏完成 GCC canonical host 到 Rust target 的映射例如x86_64-w64-mingw32 → x86_64-pc-windows-gnullvm并在交叉编译时额外下载目标平台的rust-std同时按build_os区分宿主 Rust 与目标 Rust 的获取与安装。Rust 版本更新时需运行 contrib/devtools/update-rust-hashes.sh 同步哈希该脚本的用法注释即写在配方头部。九、与主项目构建的衔接config.site 与 cargo vendor构建完成后depends 在$(host_prefix)/share/config.site生成一份由 depends/config.site.in 模板展开的配置depends/Makefile内容包含交叉编译器完整路径CC、CXX指向工具链前缀下的 clang/gccbinutils 路径AR、RANLIB、NM、STRIP各平台的CFLAGS/CXXFLAGS/CPPFLAGS/LDFLAGSRust targetrust_targetno_wallet、debug等透传变量。当主项目执行./configure --prefixdepends 输出的 host 目录时autoconf 会自动加载该config.site从而让 Zcash 主构建透明地使用这套交叉工具链与依赖库无需手工指定每个编译器路径。这也是原文档“No other options are needed, the paths are automatically configured”的底层实现。此外若vendored-crates.tar.gz存在构建 host 前缀时会直接解压预制的 crate 归档否则执行cargo vendor --locked现场收集 Rust 依赖depends/Makefile保证zcashd所依赖的 Rust 组件如 librustzcash 系列可离线、可复现地构建。十、延伸阅读depends/description.mddepends 系统的总体设计理念与特性depends/packages.md添加新包的完整规范与变量说明depends/Makefile选项默认值、download目标与config.site生成逻辑depends/funcs.mkbuild-id、stamp 流水线与缓存机制的核心实现depends/hosts/ 与 depends/builders/各平台与构建机配置depends/packages/全部依赖包配方可作编写新配方的参考模板contrib/devtools/symbol-check.pyALLOWED_LIBRARIES定义处决定哪些依赖应静态链接。【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表