一、MSVC介绍
MSVC工具链集成于VS2019里面:
1.1 MSVC工具链主要组成:
- 编译器(cl.exe):将C/C++源码转换为.obj文件(源码编译阶段)
- 连接器(link.exe):整合.obj文件与静态库生成.exe/DLL (构建可执行文件)
- 打包(lib.exe):将.obj文件打包成静态库
- 调试套件(devenv.exe/cdb.exe):图形化/命令行调试工具。
- 二进制文件分析(dumpbin.exe):参考PE文件结构,分析符号表和导入表。
- 包管理(vcpkg): 管理1200+开源库的依赖关系,支持二进制缓存。
- 构建系统(msbuild.exe):解析.sln/.vcxproj文件,管理编译依赖链
1.2 启动MSVC
通过"x64 Native Tools Command Prompt for VS 2019"启动命令行,自动配置环境变量。
二、编译 单个C文件
hello.c 代码:
#include <stdio.h>
int main()
{
printf("hello ffmpeg \r\n");
return 0;
}
2.1 编译阶段
cl.exe /c /Fohello.obj hello.c
/c
表示只编译不链接/Fo
指定目标文件名- 在Linux上是用“-”,而在Windows上是使用“/”
编译过程中的中间文件:
.obj
:目标文件。.lib
:静态库,或者是 动态库的 import 库。.dll
:动态库。
目标文件格式:
- Windows 的.obj、.lib、.dll文件格式都是基于COFF
- PE格式(exe文件格式)与Linux ELF 格式都是基于COFF发展而来。
2.2 链接阶段
link.exe /DEBUG /OUT:hello.exe hello.obj
/DEBUG
指定编译类型/OUT
是指定输出文件名。
2.3 分析exe依赖
默认静态链接C运行时库libcmt.lib,动态链接时使用/MD选项。
dumpbin /dependents hello.exe
指定C运行时库类型(要在编译阶段指定):
/MT
:静态链接C运行时库(默认)/MD
:动态链接C运行时刻。- 不同文件使用不同的C运行时库选项(如部分使用/MD,部分使用/MT)会导致链接冲突。
三、编译 多个C文件
多个C文件编译:和Linux的gcc 类似,也是先单个C文件编译,然后再链接。
源码下载地址:universe.zip
3.1 编译阶段
cl.exe /c earth.c
cl.exe /c moon.c
cl.exe /c sun.c
cl.exe /c zeus.c
或者:
cl.exe /c earth.c moon.c sun.c zeus.c
3.2 链接阶段
link.exe /DEBUG /OUT:zeus.exe earth.obj moon.obj sun.obj zeus.obj
四、编译静态库
和Linux的gcc编译静态库类似,先编译,再打包。
4.1 编译阶段
cl.exe /c earth.c moon.c sun.c
4.2 打包静态库
lib.exe /OUT:star_static.lib earth.obj moon.obj sun.obj
4.3 使用静态库
cl.exe /c zeus.c
link.exe /DEBUG /OUT:zeus.exe zeus.obj star_static.lib
4.4 静态库命名规则
MSVC没有统一的命名规则。
- 静态库:x265.lib,没有lib前缀,后缀是.lib
- 区分静态库和动态库导入库:
- 普通规范:静态库以
lib库名.lib
命名,如:libstar.lib
- CUDA规范:静态库以
库名_static.lib
命名,如star_static.lib
- 普通规范:静态库以
五、编译动态库
5.1 手写导出函数
编译源文件:
cl /c earth.c moon.c sun.c
编译动态库:
link /DLL /DEBUG /EXPORT:sun_rotate /EXPORT:moon_rotate /EXPORT:earth_rotate /OUT:star.dll earth.obj moon.obj sun.obj
使用动态库:
cl.exe /c zeus.c
link.exe /DEBUG /OUT:zeus.exe zeus.obj star.lib
注意:上面的star.lib
是动态库的导入库,不包含任何代码,只是给链接器提供信息。
5.2 使用DEF文件指定导出函数
star.def文件:
EXPORTS
sun_rotate
moon_rotate
earth_rotate
编译动态库:
cl /c earth.c moon.c sun.c
link.exe /DLL /DEBUG /DEF:star.def /OUT:star.dll earth.obj moon.obj sun.obj