使用 IDE 与构建系统编译集成 zstd:从 Visual Studio 到 CMake,以及它在 mold 链接器中的实际应用 📅 发布时间:2026/9/15 15:14:12 👁 浏览次数: 使用 IDE 与构建系统编译集成 zstd从 Visual Studio 到 CMake以及它在 mold 链接器中的实际应用【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/mold导读zstdZstandard是 Facebook 开源的高压缩率、高吞吐压缩库而本仓库mold——一个现代 ELF 链接器将其作为第三方依赖内置用于压缩 ELF 文件中的.debug_*调试信息节。本文以 zstd 发行包自带的构建目录third-party/zstd/build/为核心系统讲解如何在 Visual Studio 等 IDE 中编译 zstd、如何在自己的 MSVC/C 项目中链接libzstd并延伸介绍 CMake 与命令行脚本等无 IDE 构建方式最后结合 mold 仓库源码说明 zstd 库在真实链接器项目中的集成用法。读完本文你将掌握 zstd 全系列构建产物的用途、DLL 静态/动态链接配置方法以及--compress-debug-sectionszstd背后的压缩原理。zstd 为开发者准备了哪些构建项目zstd 发行版在 build 目录下收录了面向多种集成开发环境IDE与构建系统的工程文件。根据 build/README.md随 zstd 发行包含以下项目项目说明cmake由 Artyom Dymchenko 贡献的 CMake 工程现代跨平台构建的首选VS2005Visual Studio 2005 工程已移至 contrib 目录不再维护VS2008Visual Studio 2008 工程VS2010Visual Studio 2010 工程同样兼容 VS2012 / VS2013 / VS2015VS_scripts无需 IDE、纯命令行完成 Visual Studio 编译的批处理脚本meson基于 Meson 构建系统的工程含meson_options.txt选项文件single_file_libs将整个 zstd 合并为单一 C 源文件的聚合amalgamation方案在当前的 mold 仓库中实际存在的是VS2008、VS2010、VS_scripts、cmake、meson与single_file_libs六个子目录build。下文将依次讲解各方案的具体用法。使用 Visual Studio 编译 zstdGUI 方式原文档给出的完整流程如下可直接照做安装 Visual Studio例如 VS 2015 Community Edition免费版即可。下载最新版 zstd 的发行归档并解压 ZIP 包。进入解压后的目录再进入projects在当前仓库中对应 build/VS2010打开zstd.sln。Visual Studio 会询问是否将 VS2010 工程转换为当前版本如 VS2015选择同意转换。在工具栏把Debug切换为Release如果是 64 位 Windows再把Win32切换为x64。按F7或从菜单栏选择BUILD→Build Solution构建整个解决方案。编译成功后可执行文件位于build\VS2010\bin\x64\Release\zstd.exe原文档中的输出目录是projects\VS2010\bin\x64\Release\zstd.exe因目录结构历史变迁当前仓库以build/VS2010为基准。说明zstd 官方仓库在历史上的目录布局曾为projects/、visual/等本仓库所内置的版本将其统一收纳于 third-party/zstd/build 之下文档中出现的输出路径visual\VS2010\bin\$(Platform)_$(Configuration)\在当前仓库中对应third-party/zstd/build/VS2010/bin/$(Platform)_$(Configuration)/。zstd.sln 中包含哪些工程解决方案文件 zstd.sln 会把这些工程全部编译到bin\$(Platform)_$(Configuration)目录例如选择x64Release时输出到bin\x64_Release。各工程的用途如下zstd命令行工具CLI支持类似 gzip 的命令行参数即日常压缩/解压用的zstd可执行文件。datagen可参数的合成数据生成器用于生成测试数据。fullbench精确测量 zstd 每个内部函数运行速度的基准测试工具。fuzzer目标平台上的完整性测试工具用于校验 zstd 在该平台的正确性。libzstd静态库工程编译产物为libzstd_static.lib。libzstd-dll动态库工程编译产物为libzstd.dll同时生成导入库libzstd.lib。fullbench-dll基于导入库编译的 fullbench 程序运行该可执行文件时需要 ZSTD DLL 在场。在自己的 MSVC 工程中使用 ZSTD DLL要在 Visual C 工程中链接 zstd需要两个文件头文件 lib/zstd.h 与导入库bin\$(Platform)_$(Configuration)\libzstd.lib。配置步骤如下添加头文件路径在 Visual Studio 的“项目属性 →C/C→常规→ 附加包含目录Additional Include Directories”中加入lib/zstd.h所在的目录。添加导入库在“项目属性 →链接器→输入→ 附加依赖项Additional Dependencies”中加入libzstd.lib。补充库搜索路径如果在附加依赖项中只写库名libzstd.lib而不写完整路径还需要在“链接器 → 常规 → 附加库目录Additional Library Directories”中指定导入库所在目录。编译出的可执行文件运行时需要 ZSTD DLL该 DLL 位于bin\$(Platform)_$(Configuration)\libzstd.dll需确保它随程序一起分发或在 PATH 中可被找到。命令行方式VS_scripts 免 IDE 编译如果不想打开 IDEbuild/VS_scripts/README.md 提供了纯命令行编译方案。这些脚本统一调用通用脚本build.generic.cmd参数格式为build.generic.cmd VS版本 架构 配置 平台工具集一条命令同时构建Release Win32和Release x64两个版本build.VS2013.cmd构建结果分别位于对应的bin\Release\{ARCH}\目录。只构建单个架构以 VS2013 为例build.generic.cmd VS2013 Win32 Release v120 build.generic.cmd VS2013 x64 Release v120Debug 构建把参数中的Release换成Debug即可build.generic.cmd VS2013 Win32 Debug v120 build.generic.cmd VS2013 x64 Debug v120脚本名称中的工具集后缀对应不同的 CRT 版本v120对应msvcr120.dllVS2013v140对应msvcr140.dllVS2015。因此可以用 VS2015 编译出面向msvcr120.dll的版本build.generic.cmd VS2015 Win32 Release v120 build.generic.cmd VS2015 x64 Release v120针对 VS2017build.VS2017.cmd会按Enterprise Professional Community的优先级自动探测本机安装的第一个 VS2017 变体并同时构建Release Win32与Release x64若要锁定具体版本可使用形如build.VS2017Enterprise.cmd的专用脚本。CMake 构建方式与可配置选项对于跨平台开发CMake 是更现代的选择其工程位于 build/cmake。该子目录还自带若干 CMake 模块CMakeModules例如GetZstdLibraryVersion.cmake用于从源码中提取 zstd 版本号、AddZstdCompilationFlags.cmake用于按平台附加编译选项。推荐的 out-of-source 构建CMake 没有cmake clean命令官方推荐“源外构建”out-of-source build这样只需删除构建目录即可清理全部缓存cd build/cmake mkdir builddir cd builddir cmake .. make清理缓存只需删除新创建的构建目录以仓库内路径为例rm -rf third-party/zstd/build/cmake/builddir当然也支持直接在源码目录内构建cd build/cmake cmake . make查看与设置构建选项用-LH列出全部构建选项cd build/cmake/builddir cmake -LH ..布尔型选项用-D[选项]ON/OFF设置。例如开启测试并关闭旧版格式支持cd build/cmake/builddir cmake -DZSTD_BUILD_TESTSON -DZSTD_LEGACY_SUPPORTOFF .. makeApple Framework 与 iOS 构建面向 iOS 等衍生平台时官方建议使用 3.14 以上版本的 CMake以便正确处理 toolchaincmake -S . -B build-cmake -DZSTD_FRAMEWORKON -DCMAKE_SYSTEM_NAMEiOSCMake 版本低于 3.14 时可借助 iOS-CMake toolchain 文件cmake -B build -G Xcode -DCMAKE_TOOLCHAIN_FILEPath To ios.toolchain.cmake -DPLATFORMOS64 -DZSTD_FRAMEWORKON通过 FetchContent 集成到自己的 CMake 项目zstd 支持以 CMakeFetchContent方式直接拉取并编译无需手动下载include(FetchContent) set(ZSTD_BUILD_STATIC ON) set(ZSTD_BUILD_SHARED OFF) FetchContent_Declare( zstd URL https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-1.5.5.tar.gz DOWNLOAD_EXTRACT_TIMESTAMP TRUE SOURCE_SUBDIR build/cmake ) FetchContent_MakeAvailable(zstd) target_link_libraries( ${PROJECT_NAME} PRIVATE libzstd_static ) # 在 Windows 和 macOS 上还需要显式添加头文件目录 target_include_directories( ${PROJECT_NAME} PRIVATE ${zstd_SOURCE_DIR}/lib )注意SOURCE_SUBDIR build/cmake指定 zstd 源码树中的 CMake 工程位置ZSTD_BUILD_STATIC ON与ZSTD_BUILD_SHARED OFF用于选择静态库、关闭共享库。完整的可配置选项以 build/cmake/lib/CMakeLists.txt 为准。CMake 代码风格约定build/cmake/README.md 还给出了向该项目提交 CMake 代码时的风格要求命令与变量命名遵循现代 CMake2.6 及以上惯例命令用小写变量用大写文件内保持大小写风格一致总体偏好全小写。例如推荐add_executable(foo foo.c)而不推荐ADD_EXECUTABLE(...)这类写法。if/else/endif、foreach/endforeach、while/endwhile、function/endfunction等块体正确缩进用空格缩进2/3/4 个空格均可且同一文件内保持一致不使用 Tab。块结束命令使用空参数形式以提升可读性推荐endif()、else()、endfunction()写法而不是endif(FOOVAR)这种带变量的旧式写法。单文件聚合库把整个 zstd 塞进一个 .cbuild/single_file_libs/README.md 介绍了另一种极具吸引力的集成方式用combine.py把 zstd 源码“聚合”amalgamate成单个源文件。它不是 header-only 库但集成复杂度与之相当——只需往项目里加一个文件用头文件的话是两个无需任何配置和额外构建步骤。仅解压库zstddeclib.c最常见解压库体积很小例如在 Emscripten 编译的 WebAssembly 项目中仅增加约 26 kB原生实现约增加 40–70 kB视编译器与平台而定。生成方式cd zstd/build/single_file_libs python3 combine.py -r ../../lib -x legacy/zstd_legacy.h -o zstddeclib.c zstddeclib-in.c脚本create_single_file_decoder.sh会执行上述命令生成zstddeclib.cbuild_decoder_test.sh则先生成再编译并测试。仓库中提供了现成的示例见 single_file_libs/examples如simple.c、emscripten.c。完整库zstd.c同样工具可以聚合完整 zstd 库压缩解压。示例 examples/roundtrip.c 使用原始zstd.h其余源码合并为zstd.c约 1.2 MB生成方式cd zstd/build/single_file_libs python3 combine.py -r ../../lib -x legacy/zstd_legacy.h -k zstd.h -o zstd.c zstd-in.c其中-k zstd.h表示保留keep该头文件而不并入。也可以生成仅压缩库——但鉴于解压器相对极小收益有限若确实需要直接删掉zstd-in.c末尾_decompress_一节的源码即可。create_single_file_library.sh负责生成zstd.cbuild_library_test.sh会生成、编译并测试。实战佐证mold 链接器如何利用 zstd 压缩调试信息本仓库之所以内置 zstd是为了实现 ELF 文件调试信息的压缩。mold 的命令行选项--compress-debug-sections支持 zlib 与 zstd 两种算法其取值在 src/cmdline.cc 中定义为--compress-debug-sections[none,zlib,zlib:0,...,zlib:9,zstd,zstd:1,...,zstd:22]在 src/cmdline.cc 的参数解析中可以看到zlib/zlib-gabi使用 ELFCOMPRESS_ZLIB即ELFCOMPRESS_ZLIB 1默认压缩级别为 1zlib:N允许指定 0–9 之间的级别超出即报错zlib level must be between 0 and 9。zstd使用 ELFCOMPRESS_ZSTDsrc/elf.h 中定义ELFCOMPRESS_ZSTD 2默认压缩级别为 3zstd:N允许指定 1–22 之间的级别超出即报错zstd level must be between 1 and 22。none不压缩。压缩实现位于 lib/compress.cc其核心是多线程分片压缩把输入按SHARD_SIZE 1024 * 10241 MiB切成多片split()函数再用 TBB 的tbb::parallel_for并行压缩每一片。zstd 路径调用ZSTD_compress()见 lib/compress.ccstatic std::spanu8 zstd_compress(std::spanu8 input, int level) { i64 bufsize ZSTD_COMPRESSBOUND(input.size()); u8 *buf new u8[bufsize]; size_t sz ZSTD_compress(buf, bufsize, input.data(), input.size(), level); assert(!ZSTD_isError(sz)); return {buf, sz}; }ZstdCompressor把各分片的压缩结果按偏移拼接到输出缓冲lib/compress.cc。分片压缩意味着每片的字典都会重置会略微牺牲压缩比但如文件头注释所述只要分片足够大这种损失在实践中可以忽略。对应的解压侧在 src/input-sections.cc当输入节是ELFCOMPRESS_ZSTD时mold 用流式 APIZSTD_createDCtx()/ZSTD_decompressStream()解压出错时通过ZSTD_getErrorName()输出错误信息。压缩后的节由CompressedSectionsrc/mold.h表示它持有ElfChdr头、解压数据与一个Compressor对象。测试方面test/compress-debug-sections-zstd.sh 验证--compress-debug-sectionszstd生成的.debug_info能被zstdcat正常解压test/compress-debug-sections-zstd-level.sh 验证级别边界zstd:1与zstd:22合法而zstd:0、zstd:23会被拒绝并提示zstd level must be between 1 and 22。小结如何按需选择 zstd 的构建与集成路线在 Windows 上快速得到zstd.exe命令行工具打开 build/VS2010/zstd.sln切到Release64 位系统再切x64按F7构建。在 Windows 上免 IDE 构建使用 build/VS_scripts 下的build.VS2013.cmd、build.VS2015.cmd或通用build.generic.cmd。在自有 CMake 项目中链接 zstd优先FetchContentlibzstd_static或直接 source 目录构建 build/cmake。追求极简集成用 build/single_file_libs 的combine.py生成单个.c文件仅解压选zstddeclib.c完整库选zstd.c。在 mold 链接器中使用 zstd直接通过-Wl,--compress-debug-sectionszstd[:级别]触发背后即是本文所述 lib/compress.cc 的分片并行压缩实现。/DSMLparameter /DSMLinvoke /DSMLtool_calls【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/mold创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考