【VS2017】 一个使用 cl 和 link 命令例子

编译脚本 build_windows_x86.bat

bash 复制代码
@echo off

:: 初始化 VS2017 x86 编译环境
call "%VS2017%\vcvars32.bat"
if errorlevel 1 (
    echo [ERROR] 无法初始化 VS2017 编译环境,请检查安装路径
    pause
    exit /b 1
)

:: 5. 编译测试程序 (必须 /MD + ENABLE_DEEP_PLC/DRED/OSCE)
echo [5/5] 编译测试程序 test_opus_plc_multi_dred.exe...
cl /c /Fotest_opus_plc_multi_dred.obj /nologo /MD /O2 ^
  /DENABLE_DEEP_PLC /DENABLE_DRED /DENABLE_OSCE ^
  .\test_opus_plc_multi_dred.c ^
  /I . /I include/opus
if errorlevel 1 goto error

link /OUT:test_opus_plc_multi_dred.exe ^
  test_opus_plc_multi_dred.obj .\libopus.lib
if errorlevel 1 goto error

echo.
echo ============================================
echo  编译完成!
echo  测试  : test_opus_plc_multi_dred.exe
echo ============================================
goto end

:error
echo.
echo [ERROR] 编译失败!
pause

:end

逐行解释这个完整的批处理文件,并结合提供的环境变量截图说明关键配置。


📄 完整代码解析

第 1 行:关闭命令回显

batch 复制代码
@echo off
  • 执行时不显示命令本身,只显示命令的输出结果
  • 让控制台输出更整洁

第 3-9 行:初始化 VS2017 编译环境

batch 复制代码
:: 初始化 VS2017 x86 编译环境
call "%VS2017%\vcvars32.bat"
if errorlevel 1 (
    echo [ERROR] 无法初始化 VS2017 编译环境,请检查安装路径
    pause
    exit /b 1
)
内容 说明
call 调用另一个批处理脚本,执行完后返回当前脚本继续
%VS2017% 系统环境变量,值来自您截图中的配置
vcvars32.bat VS2017 自带的 x86 环境初始化脚本
if errorlevel 1 如果初始化失败,显示错误并暂停
🔑 环境变量关联(您的截图)
复制代码
变量名:  VS2017
变量值:  C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build

所以实际调用的是:

复制代码
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars32.bat"

vcvars32.bat 的作用

  • cl(编译器)、link(链接器)等工具添加到当前命令行的 PATH 中
  • 设置 INCLUDELIB 等环境变量
  • 这是必须的一步 ,否则直接运行 cl 会提示"找不到命令"

第 11-17 行:编译(生成目标文件)

batch 复制代码
:: 编译测试程序 (必须 /MD + ENABLE_DEEP_PLC/DRED/OSCE)
echo [5/5] 编译测试程序 test_opus_plc_multi_dred.exe...
cl /c /Fotest_opus_plc_multi_dred.obj /nologo /MD /O2 ^
  /DENABLE_DEEP_PLC /DENABLE_DRED /DENABLE_OSCE ^
  .\test_opus_plc_multi_dred.c ^
  /I . /I include/opus
if errorlevel 1 goto error

详细参数

参数 含义
cl MSVC C/C++ 编译器
/c 只编译,不链接 (生成 .obj 文件)
/Fotest_opus_plc_multi_dred.obj 指定输出文件名
/nologo 不显示编译器版本横幅
/MD 使用多线程 DLL 运行时库(必须匹配 libopus.lib 的编译方式)
/O2 速度优化(Release 级别优化)
/DENABLE_DEEP_PLC 定义宏,启用 Deep PLC 代码块
/DENABLE_DRED 定义宏,启用 DRED 代码块
/DENABLE_OSCE 定义宏,启用 OSCE 功能
/I . 头文件搜索路径:当前目录
/I include/opus 头文件搜索路径:include/opus 子目录
^ 批处理续行符,将多行拼接成一条命令

执行结果

复制代码
.\test_opus_plc_multi_dred.c  →  test_opus_plc_multi_dred.obj

第 19-21 行:链接(生成可执行文件)

batch 复制代码
link /OUT:test_opus_plc_multi_dred.exe ^
  test_opus_plc_multi_dred.obj .\libopus.lib
if errorlevel 1 goto error
参数 含义
link MSVC 链接器
/OUT:test_opus_plc_multi_dred.exe 指定输出可执行文件名
test_opus_plc_multi_dred.obj 上一步编译生成的目标文件
.\libopus.lib Opus 静态库文件(包含 opus_encode、opus_decode 等实现)

链接过程

  • .obj 中的代码与 libopus.lib 中的 Opus API 实现合并
  • 解析所有函数调用,生成最终的 .exe 文件

第 23-28 行:成功处理

batch 复制代码
echo.
echo ============================================
echo  编译完成!
echo  测试  : test_opus_plc_multi_dred.exe
echo ============================================
goto end
  • 打印成功信息
  • goto end 跳过错误处理代码,直接到脚本末尾结束

第 30-33 行:错误处理标签

batch 复制代码
:error
echo.
echo [ERROR] 编译失败!
pause
  • :error 是一个标签(Label)
  • 编译或链接失败时跳转到这里
  • pause 暂停,等待用户按任意键(方便查看错误信息)

第 35 行:脚本结束标签

batch 复制代码
:end
  • 空标签,作为 goto end 的跳转目标
  • 脚本执行到这里自然结束

🔄 执行流程图

复制代码
开始
  │
  ▼
初始化 VS2017 环境 (vcvars32.bat)
  │
  ├── 失败 ──→ 显示错误 ──→ pause ──→ 退出
  │
  ▼
编译 test_opus_plc_multi_dred.c
  │
  ├── 失败 ──→ :error 标签 ──→ 显示"编译失败" ──→ pause
  │
  ▼
链接 .obj + libopus.lib
  │
  ├── 失败 ──→ :error 标签 ──→ 显示"编译失败" ──→ pause
  │
  ▼
显示"编译完成!"
  │
  ▼
结束

⚠️ 关键注意事项

问题 说明
必须先设置 VS2017 环境变量 您截图中的配置是正确的,脚本依赖它
必须在 VS 开发者命令提示符中运行? 不需要 ,因为脚本自己会调用 vcvars32.bat 初始化环境
/MD 必须匹配 libopus.lib 必须用 /MD 编译,否则链接会报错
源文件路径 脚本假设 test_opus_plc_multi_dred.clibopus.lib.bat 同目录

💡 如果要手动执行

直接在普通 CMD 或 PowerShell 中运行:

cmd 复制代码
cd c:\Users\lijian\Desktop\opus\windows_x86
build_windows_x86.bat

不需要先打开"Developer Command Prompt",因为脚本内部已经做了环境初始化。


相关推荐
水饺编程5 天前
第5章,[Win32 章节] :贝塞尔样条曲线(一)
c语言·c++·windows·visual studio
nicehuai6 天前
烧录、查变量、看日志、调驱动:H-FlashScope搞定嵌入式下载调试的瑞士军刀
ide·vscode·visual studio
Hhy_110710 天前
《C++深度解构02》类和对象(上)——定义规范、内存对齐与 this 指针全解
c语言·开发语言·c++·学习·visual studio
Lhan.zzZ15 天前
在 Visual Studio 2022 中打造可扩展的动态链接库模块:从零搭建到原理解析
开发语言·c++·visual studio
console.log('npc')16 天前
Mock 服务设计指南
前端框架·mock·react·visual studio·项目架构
C++ 老炮儿的技术栈17 天前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
Hhy_110717 天前
《C++深度解构01》C++入门基础
c语言·开发语言·c++·学习·visual studio
菜哥万岁万岁万万岁18 天前
Visual Studio 2022 社区版下载
ide·visual studio
Hhy_110719 天前
【从零开始学数据结构 ⑥】:二叉树之堆——打破规则的优先队列
c语言·开发语言·数据结构·学习·visual studio