【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",因为脚本内部已经做了环境初始化。


相关推荐
笨鸟先飞,勤能补拙10 小时前
密码学深度指南 — SecOps 工程师实战手册
人工智能·vscode·python·安全·github·密码学·visual studio
cgsthtm11 小时前
visual studio 2022 安装 .net framework 4.5
visual studio·vs2022·.net framework·.net 4.5
你的菊花 倾心恋仙1 天前
最锋利的Visual Studio Web开发工具扩展:Web Essentials详解
前端·ide·visual studio
脚踏实地皮皮晨4 天前
003006001_WrapPanel控件
开发语言·c#·.net·wpf·visual studio
霍霍的袁4 天前
【C++】模板从入门到进阶(函数模板 + 类模板 + 特化 + 分离编译)
开发语言·c++·visual studio
脚踏实地皮皮晨4 天前
003005002_WPF StackPanel 基类官方类定义逐行深度解析
开发语言·windows·算法·c#·wpf·visual studio
霍霍的袁4 天前
【C++】string类 从 入门使用 到 底层深浅拷贝模拟实现
开发语言·c++·visual studio
脚踏实地皮皮晨5 天前
003004002_UniformGrid控件的使用方法
开发语言·c#·.net·wpf·visual studio
脚踏实地皮皮晨5 天前
003003001_Grid控件
开发语言·windows·算法·c#·visual studio
脚踏实地皮皮晨6 天前
003003002_WPF Grid 基类官方类定义逐行深度解析
开发语言·windows·算法·c#·wpf·visual studio