在前文《MSVC编译静态库》已经稍微提及了一下 vs2019 的一些使用技巧。本文打算直接把 vs2019 讲透。
以之前的 hello.c 单文件项目为例,之前我们是手动使用 cl.exe 跟 link.exe 来编译链接的,本次我将用 vs2019 来实现这些操作。
首先,打开 vs2019 ,创建一个空项目,命名为 c-single,如下:
这里我们再创建一个 C++ 控制台项目,命名为 c-single2,比较这两个 项目文件有什么区别?
用 git 来比较一番,项目根目录下的 sln 文件,只是名字不一样,实际上没有差别。
其他文件的差异如下:
因此,虽然 vs2019 创建项目的时候,有很多类型的项目可以选择,看起来好像很复杂,但是实际上,就是配置一下 xml 文件。
通常情况,vs2019 创建一个项目,会生成 4 个文件,如下:
1,.sln
,解决方案文件,一个解决方案里面可以有多个项目的(.vcxproj
)
2,.vcxproj
,项目文件,全称是 Visual C++ Project,主要负责配置使用哪个编译器,编译器的选项,链接器的选项等等信息,相关的格式介绍,推荐阅读《.vcxproj
and .props
file structure》
3,.vcxproj.filters
,分类配置文件,主要负责在 vs2019 里面把哪些文件显示在哪个分类下面,推荐阅读《vcxproj.filters files》
4,.vcxproj.user
,本地用户的信息文件,这个文件通常不需要加到 Git 里面。
更多 vs2019 的文件介绍,推荐阅读《Project and Solution Files》
现在回到 c-single 项目,右键项目,点击 Add ➜ New Item,这个按钮实际上就是创建一个新的文件并且加进去项目的 xml 配置文件里面。
直接输入 hello.c 即可,如下:
然后把以下代码复制进去:
#include <stdio.h> int main() { printf("hello ffmpeg \r\n"); return 0; }
然后点击 菜单栏的 Build ➜ Rebuild Solution ,如下:
从 vs2019 输出的日志可以看到 编译参数,如下:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.24.28314\bin\HostX86\x64\CL.exe /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"x64\Debug\\" /Fd"x64\Debug\vc142.pdb" /Gd /TC /FC /errorReport:prompt hello.c
上面的日志中cl.exe 使用了 /MDd 选项,所以是动态链接 C运行时库。
然后链接参数如下:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.24.28314\bin\HostX86\x64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\loken\source\repos\c-single\x64\Debug\c-single.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FASTLINK /PDB:"C:\Users\loken\source\repos\c-single\x64\Debug\c-single.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\loken\source\repos\c-single\x64\Debug\c-single.lib" /MACHINE:X64 x64\Debug\hello.obj
上面 vs2019 会给我的 hello.obj 加很多 静态库选项 ,例如 gdi32.lib,uuid.lib,虽然 hello.obj 没使用这些静态库的函数,但是 vs2019 为了方便还是全加上了,因为是静态库,你没用到的函数就不会拷贝进去 exe。
扩展知识:如果我们想 vs2019 调用 cl.exe 的使用不要用 /MDd ,而是使用 /MTd,那该如何办?
因为 cl.exe 是编译阶段的操作,所以直接打开项目配置, C/C++ ➜ Code Generation ,设置为 /MTd 即可,如下:
再次 rebuild 一下项目,就会发现,日志里面 cl.exe 使用的是 /MTd 了。
这个 /MTd 其实也是保存在 xml 配置文件里面的,如下:
vs2019 界面上的大部分属性,配置,都是用xml 保存的,然后 vs2019 解析这些xml配置,传递参数给 cl.exe 跟 link.exe。
至此,vs2019 的讲解就完了,其实只要学会看 vs2019 的输出日志,掌握编译链接的一些知识,无论多么庞大的 C/C++ 项目,都能轻松编译通过。
vs2019 无非就是管理跟解析 xml文件,然后传递参数给 cl.exe ,lib.exe ,link.exe。
扩展知识:vs2019 是调 msbuild.exe 来管理跟解析 xml 的。