- 编程语言
- 语言运行时
- 编译器
- 解释器
- 标准库
【免费下载链接】racket
The Racket repository
本指南围绕 Racket 仓库内 ChezScheme 所捆绑的 LZ4 压缩库(源码位于 racket/src/ChezScheme/lz4)中的 build/visual 目录展开,讲解如何借助 CMake 一键生成 VS2015~VS2022 的 Visual Studio 解决方案,以及如何通过CMAKE_PATH环境变量控制所用 CMake 版本。读完本文,你将掌握这些批处理脚本的调用链、参数语义、底层 CMake 配置行为,以及生成后如何在 Visual Studio 中集成 LZ4 库与 DLL。
一、visual 目录的定位:从脚本生成解决方案,而非手写 .sln
在 LZ4 的build目录下(racket/src/ChezScheme/lz4/build/README.md),官方提供了多种 IDE 构建入口:
cmake—— CMake 工程(也是visual脚本的底层支撑);meson—— Meson 工程;visual—— 基于 CMake 自动生成 Visual Studio 解决方案的脚本集合;VS2022—— 一个已经内置的lz4.sln,官方注明该方案"将很快废弃,推荐改用visual生成器"。
也就是说,visual目录的作用不是维护一份固定的.sln文件,而是在本地机器上动态生成与所装 Visual Studio 版本相匹配的解决方案,从而免去人工维护多份工程文件的负担。这在将 LZ4 作为第三方源码捆绑进 Racket / ChezScheme 这类大型项目时尤其有价值:无需把各版本 IDE 的工程文件全部纳入版本库,只需脚本化生成即可。
二、前置条件:两个必须本地安装的东西
visual/README.md 明确了两条运行前提:
- CMake必须已安装(并可由脚本定位,详见下文
CMAKE_PATH一节); - 与目标生成器对应的 Visual Studio 版本必须已安装,因为 CMake 在生成解决方案时要探测对应的 VS 安装与工具链。
两条缺一不可:CMake 负责"生成工程",Visual Studio 负责"提供 IDE 与编译器"。需要特别说明,visual脚本只负责生成.sln/.vcxproj,不负责编译;真正调用 MSBuild 编译的是VS2022目录下_setup.bat/_build.bat一类的脚本(后面章节会展开)。
三、脚本清单与 GENERATOR 参数映射
visual目录共包含 5 个脚本(目录一览):
| 脚本文件 | 行为 |
|---|---|
generate_solution.cmd | 核心脚本,接收一个参数GENERATOR,完成 CMake 定位、建目录、执行生成 |
generate_vs2015.cmd | 转发调用generate_solution.cmd "Visual Studio 14 2015" |
generate_vs2017.cmd | 转发调用generate_solution.cmd "Visual Studio 15 2017" |
generate_vs2019.cmd | 转发调用generate_solution.cmd "Visual Studio 16 2019" |
generate_vs2022.cmd | 转发调用generate_solution.cmd "Visual Studio 17 2022" |
每个版本脚本都只是对核心脚本的一行包装,例如 generate_vs2022.cmd 的全部内容就是:
@echo off :: Call the central script with the specific generator for VS2022 call generate_solution.cmd "Visual Studio 17 2022"这里的"Visual Studio 14 2015"、"Visual Studio 17 2022"等字符串正是 CMake 官方的生成器名称,会原样传给cmake -G。因此,如果未来微软推出新版本 Visual Studio,只需仿照现有脚本新增一个generate_vsXXXX.cmd,填入对应的 CMake 生成器名即可,核心逻辑完全复用。
四、generate_solution.cmd 核心逻辑逐段剖析
generate_solution.cmd 是全部生成流程的中枢,其执行顺序可以拆成五步:
4.1 参数校验
if "%~1"=="" ( echo No generator specified as first parameter exit /b 1 ) set "GENERATOR=%~1"没有传入生成器名称时直接以退出码 1 结束,防止后续误生成。
4.2 CMake 可执行文件的定位优先级
脚本按以下优先级寻找cmake.exe(这是 README 中CMAKE_PATH约定的实际落地逻辑):
- 用户显式指定:若已定义环境变量
CMAKE_PATH,则直接使用%CMAKE_PATH%\cmake.exe,并打印Using user-defined cmake at %CMAKE_PATH%; - 系统 PATH 查找:否则用
where cmake探测 PATH; - 默认安装目录回退:若 PATH 中找不到,回退到
C:\Program Files\CMake\bin这一标准安装位置,并打印提示。
if defined CMAKE_PATH ( set "CMAKE_EXECUTABLE=%CMAKE_PATH%\cmake.exe" echo Using user-defined cmake at %CMAKE_PATH% ) else ( where cmake >nul 2>&1 if %ERRORLEVEL% neq 0 ( set "CMAKE_PATH=C:\Program Files\CMake\bin" echo CMake not in system PATH => using default CMAKE_PATH=%CMAKE_PATH% set "CMAKE_EXECUTABLE=%CMAKE_PATH%\cmake.exe" ) else ( set "CMAKE_EXECUTABLE=cmake" echo CMake found in system PATH. ) )这正是 README 所说"若 CMake 安装于非标准目录,或想测试特定版本 CMake,可通过环境变量CMAKE_PATH指定目标目录"的源码级印证。实用场景包括:
- 多版本 CMake 并存,想固定用某个版本生成工程;
- 便携版 CMake 解压在任意目录,不想写入 PATH。
使用方法示例(在命令提示符中):
set CMAKE_PATH=D:\tools\cmake-3.30.0-windows-x86_64\bin generate_vs2022.cmd4.3 生成目录的创建
set "BUILD_DIR=%BUILD_BASE_DIR%\%GENERATOR%" if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%"以生成器名称作为子目录名(如visual\Visual Studio 17 2022\),实现不同 VS 版本互不干扰的并行构建目录。
4.4 执行 CMake 生成
pushd "%BUILD_DIR%" "%CMAKE_EXECUTABLE%" -G "%GENERATOR%" "%CMAKELIST_DIR%" if %ERRORLEVEL% neq 0 goto :error其中CMAKELIST_DIR被定义为..\..\cmake,即 build/cmake 目录。也就是说,visual 脚本生成的解决方案完全由该 CMake 工程驱动,解决方案里的每个项目(lz4、liblz4等)都来自 CMakeLists.txt 的定义。
4.5 成功与失败分支
:error echo Failed to configure build for %GENERATOR%. exit /b 1 ... :end popd endlocal @echo on成功则打印Build configuration successful for %GENERATOR%.,失败则以退出码 1 结束,便于 CI 或批处理链判断结果。
五、生成背后的 CMake 工程:visual 脚本指向的配置层
visual脚本只是"入口",真正的工程定义在 build/cmake/CMakeLists.txt。理解它,才能知道生成的解决方案里到底有什么、以及各选项如何影响产物。
5.1 最低版本与版本号自动解析
cmake_minimum_required(VERSION 3.5)脚本要求 CMake 不低于 3.5。工程版本号不是硬编码,而是通过正则从lib/lz4.h中解析LZ4_VERSION_MAJOR / MINOR / RELEASE宏拼出(见 CMakeLists.txt 的parse_lz4_version函数),并以project(LZ4 VERSION ...)生效。
5.2 关键构建选项
| 选项 | 默认值 | 含义 |
|---|---|---|
LZ4_BUILD_CLI | ON | 是否构建命令行程序lz4 |
BUILD_SHARED_LIBS | 独立构建时ON,捆绑模式(LZ4_BUNDLED_MODE=ON)时强制OFF | 是否构建动态库 |
BUILD_STATIC_LIBS | OFF(由CMAKE_DEPENDENT_OPTION与BUILD_SHARED_LIBS联动) | 是否构建静态库 |
LZ4_POSITION_INDEPENDENT_LIB | ON | 静态库是否启用位置无关代码(PIC) |
LZ4_BUNDLED_MODE | 由"是否为子项目"自动推断 | 捆绑模式关闭安装/CPack,避免污染宿主项目 |
特别注意捆绑模式逻辑:当 LZ4 作为其他项目(比如 ChezScheme/Racket 这类宿主)的子项目被add_subdirectory引入时,LZ4_BUNDLED_MODE自动为ON,此时不生成安装规则与 CPack 包,且静态库成为默认选择——这对以源码形式内嵌 LZ4 的仓库尤为重要。
5.3 MSVC 专属细节
- 调试构建附加
/W4警告级别; - 动态库目标在 MSVC 下定义
LZ4_DLL_EXPORT=1,控制导出符号; - 当"共享库 + 静态库"同时构建时,静态库产物改名为
lz4_static,避免与动态库导入库lz4.lib冲突(CMakeLists.txt 中set(STATIC_LIB_NAME lz4_static)的逻辑)。这一点与 build/README.md 中"liblz4静态库编译为liblz4_static.lib"的描述完全吻合; - 共享库与静态库均通过
XXH_NAMESPACE=LZ4_前缀化内部 xxhash 符号,规避链接冲突。
六、生成结果与解决方案内的项目构成
运行generate_vsXXXX.cmd后,在对应生成器子目录下会得到.sln与各项目的.vcxproj。参考同仓库 VS2022/lz4.sln 的既有构成(build/README.md 有逐项说明),解决方案通常包含以下目标:
| 项目 | 说明 |
|---|---|
lz4 | 命令行压缩工具,支持 gzip 风格参数 |
datagen | 可参数化的合成数据生成器,用于测试 |
frametest | 校验 lz4frame 完整性/稳定性的测试工具 |
fullbench | 逐函数精确测量 LZ4 各内部例程速度的基准工具 |
fuzzer | 模糊测试工具,用于校验 LZ4 完整性 |
liblz4 | 静态库(产物liblz4_static.lib) |
liblz4-dll | 动态库(产物liblz4.dll及导入库liblz4.lib) |
fullbench-dll | 链接导入库构建的 fullbench,运行期依赖 LZ4 DLL |
产物输出目录约定为build\bin\$(Platform)_$(Configuration)(build/README.md原文沿用了build\VS2010\bin\...的历史路径写法;VS2022目录的 _build.bat 实际实现为.\bin\!Platform!_!Configuration!)。例如以x64+Release构建lz4,可执行文件位于build\bin\x64_Release\lz4.exe。
若需要从命令行直接编译生成好的解决方案,可参考VS2022目录的既有辅助脚本:_setup.bat 通过vswhere.exe定位最新 Visual Studio 并调用vcvars64.bat初始化环境;_build.bat 则以msbuild lz4.sln /p:Configuration=... /p:Platform=... /t:Clean,Build执行构建并校验各产物文件是否齐全。
七、在 Visual C++ 项目中集成 LZ4(DLL 用法)
build/README.md提供了把 LZ4 动态库接入自有 Visual C++ 工程的完整步骤,这是生成解决方案之外最常见的下游操作:
- 引入头文件:将
lib\lz4.h、lib\lz4hc.h、lib\lz4frame.h(源码位于 racket/src/ChezScheme/lz4/lib)所在目录加入工程的项目属性 → C/C++ → 常规 → 附加包含目录(Additional Include Directories); - 链接导入库:把
liblz4.lib加入链接器 → 输入 → 附加依赖项(Additional Dependencies); - 指定库搜索路径:若依赖项中只写库名
liblz4.lib而未写完整路径,则需要把库所在目录加入链接器 → 常规 → 附加库目录(Additional Library Directories); - 运行期分发:编译出的可执行文件运行时需要
liblz4.dll,请将其与可执行文件放置于同一目录或加入系统 DLL 搜索路径。
八、常见问题与排错速查
| 现象 | 原因与处理 |
|---|---|
提示No generator specified as first parameter | 直接运行了generate_solution.cmd而未带参数;请运行版本化脚本(如generate_vs2022.cmd)或补上生成器名 |
提示CMake not in system PATH => using default CMAKE_PATH=...后仍失败 | PATH 中没有 cmake 且默认目录C:\Program Files\CMake\bin下也没有;请安装 CMake 或通过set CMAKE_PATH=<目录>指向实际安装位置 |
| 想固定使用某个 CMake 版本 | 设置CMAKE_PATH指向该版本bin目录后重跑脚本(见 4.2 节) |
提示Failed to configure build for ... | CMake 生成失败,退出码 1;常见原因是本机未安装对应的 Visual Studio 版本或其 C++ 工作负载,可结合 CMake 在控制台输出的详细错误定位 |
| 生成成功但想清理 | 直接删除对应生成器名称的子目录即可,不会影响其他版本的生成目录 |
九、仓库内的其他构建路径(横向对照)
visual只是 LZ4 构建体系的一环,同仓库还提供:
- 纯 CMake 方式:在 build/cmake 直接执行
cmake .. && cmake --build .,不依赖 Visual Studio 生成器,可在非 Windows 平台使用; - Meson 方式:build/meson 提供 Meson 工程与
meson_options.txt配置; - VS2022 预置方案:build/VS2022 内置
lz4.sln,但官方已注明将废弃,新开发场景建议统一走visual生成器路径。
从整个 Racket 仓库的角度看,LZ4 作为 ChezScheme 运行时的一部分被内嵌于racket/src/ChezScheme/lz4(其自身又捆绑了 zlib、lz4 等第三方库,见 racket/src/ChezScheme/README.md 的整体说明)。在 Windows 上为这套源码树生成 Visual Studio 工程时,visual脚本 +CMAKE_PATH的组合提供了一个稳定、可复现、与 IDE 版本解耦的入口,也是理解该仓库 Windows 构建流水线的一个很好的起点。
- 编程语言
- 语言运行时
- 编译器
- 解释器
- 标准库
【免费下载链接】racket
The Racket repository
相关推荐
LZ4 构建工程指南:CMake、Meson 与 Visual Studio 多 IDE 构建方案详解(Racket 仓库内附源码)
LZ4 构建工程指南:CMake、Meson 与 Visual Studio 多 IDE 构建方案详解(Racket 仓库内附源码) 导读 本文围绕 Racke
编程语言语言运行时编译器解释器标准库LZ4 多 IDE 构建指南:CMake / Meson / Visual Studio 解决方案与 DLL 集成实战
LZ4 多 IDE 构建指南:CMake / Meson / Visual Studio 解决方案与 DLL 集成实战 本文以 LZ4 仓库中 build/RE
存储系统编程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考