使用VisualStudio自带的MSVC编译C/C++

使用MSVC编译C/C++

最近看到项目里换了个解析protobuf的新库,刚好自己也看完了一遍《链接、装载与库》,基于理论结合实践的学习原则,便心血来潮就想要不自己也编一下搞个demo用一下试试看。很自然地来到该库作者的Github主页,然后照着readme就开始了。因为自己没手动编过(都是直接用编好的库= =),所以在这个过程中难以避免地碰到不少与编译相关的问题,特在此记录一下。

一、通过命令行进行编译(失败)

我打算先使用命令行构建该库。首先自然是要确认我的MSVC编译器能够正常使用(我装的是VisualStudio2017,它有自带的MSVC),这通过自己先编一个简单的HelloWorld就行。
搜了一下使用MSVC编译时需要设置的环境变量,根据教程一步步设置,然后得到了如下错误fatal error LNK1104:无法打开文件"uuid.lib"
uuid.lib草,我不知道uuid.lib是什么库。
然后就开始猜测:要么是我在测试代码里包含的输入输出流头文件iostream使用到了uuid.lib内的函数或变量,要么它就是一些必备的系统库(比如kernel32.lib)之一,但是链接器找不到它,后者的可能性大一些。那我只要找到uuid.lib所在的路径并把它写入到环境变量LIB里就行
通过C盘全局搜索我只找到了一个同名的uuid.lib(其实还有很多同名但大小写不一致的uuid.lib,但是出于严谨我很自然地忽略了大小写的问题),然后就顺理成章地把它所在的路径加到了环境变量LIB里,继续尝试编译HelloWorld,又得到了以下错误fatal error LNK1112:模块计算机类型ARM64与目标计算机类型x64冲突
arm64这个kernel32.lib和上述的uuid.lib处于同一目录下,但是它是基于ARM64指令集下编译得到的,而我将要运行的程序是基于x64平台的,用不了,牛逼。也就是说我刚刚指定的系统库路径是错的。
可是老子电脑里没其他uuid.lib了呀?上哪去找×64的uuid.lib和kernel32.lib?
然后我就想是不是当初装VisualStudio的时候少下载了一些东西,接下来就是漫长的修改重启VisualStudio的过程…就这么折腾了一天没结果,我选择放弃。

二、通过VisualStudio进行编译(成功)

稍作调整后决定改用强大的IDE VisualStudio2017跑HelloWorld(是的,一切又回到原点)。不过这次出发点不同,我需要验证的是一个假设:
假如VisualStudio可以跑通x64平台的HelloWorld,那就说明它能通过某种方法找到我前面所缺失的正确的基于x64指令集类型所编译得到的kernel32.lib以及uuid.lib库,毕竟它和我在命令行里操作的一样,都是用的自己的MSVC编译和链接C/C++代码的。
也就是说,只要我知道VisualStudio是如何找到那些64位的系统库的,问题就解决了。
VisualStudio牛逼,一下就弹出了熟悉的HelloWorld。基于以上假设,我在项目–>属性–>VC++目录–>库目录里找到了一项**$(WindowsSDK_LibraryPath_x64)**,这应该是VisualStudio自己定义的一个宏,它的名字看起来像是我们想要的。
果然,根据stackOverFlow上这个提问的指引,这个宏指向的正是链接x64程序时所需的系统库路径,如下图:
x64
那么把它加到系统环境变量LIB里,再通过命令行直接用MSVC编译HelloWorld,结果自然是成功了。能跑通HelloWorld之后,再试着用了下开头提到的解析protobuf的新库,也没啥问题。
牛逼。

三、分析(猜测)原因

首先当然是去看了下$(WindowsSDK_LibraryPath_x64)目录下的文件,确实是有kernel32与uuid两个静态库,但是名字有些区别,一个是kernel32.Lib,一个是Uuid.Lib。
。。。。。我寻思MSVC链接时在这目录下搜索静态库时还不区分大小写的???出于好奇我把该目录下的kernel32.Lib的名字改成了kerneL32.lib,果然还是能编出HelloWorld。
原来我一开始就忽略了这些同名的库,就因为出于严谨所做的一次大胆假设(库名会区别大小写)。
当然,以上也只是我所做的又一次假设,具体它是采用什么策略搜索这些库的我暂时无从得知。
做一个简单的总结:
1.若想进一步理解原理,那就以最原始的方式自己尝试一遍,毕竟编程这东西在大部分情况下是一通百通的。如果我上来直接就用VisualStudio,那就失去了碰上这些问题的机会;
2.你碰上的问题十有八九前人都已经帮你踩过坑了,这也是为什么VisualStudio这类IDE诞生的原因之一(为了帮助程序员省去编译链接的麻烦)。所以有时可以试着换个角度看问题,从现象中反窥历史,采用逆向思维寻找解决方案
3.基础很关键。假如我对程序编译链接的过程完全不了解,看到这些问题是一脸懵逼的。
4.对我而言,算法和数据结构是最需要加强的。在操作系统之上,是成千上万的静态和动态库构成了软件世界,而算法和数据结构又是创造这些库的必备技能之一(就连编译器在做词法分析、语法分析等工作时也需要用到算法和数据结构)。
5.耐心

四、可供查阅的相关链接

以下资料仅供参考,如有报错自己负责:)
1.使用MSVC编译程序时正确的系统环境变量设置方法
2.关于以上各个环境变量的一个合理解释(内含一键傻瓜式的设置方法)
3.查看VisualStudio内所有诸如$(WindowsSDK_LibraryPath_x64)等神秘宏的具体内容的方法
4.以上实践过程中的理论来源《程序员的自我修养》

### 如何配置MSVC用于C/C++开发环境搭建 #### 安装Visual Studio并选择工作负载 为了配置Microsoft Visual C++ (MSVC) 编译器进行C/C++开发,需下载并安装最新版本的Visual Studio。在安装过程中,应选择“使用C++的桌面开发”这一工作负载[^1]。 #### 设置编译器路径 完成Visual Studio安装之后,在命令提示符下可以通过`cl.exe`调用编译器。对于集成开发环境(IDE),如希望在VSCode中利用该编译器,则需要正确设置其路径。这通常涉及到更新系统的PATH环境变量以包含MSVC工具链的位置,或者是在VSCode的任务配置文件(`tasks.json`)内指定完整的编译器路径[^3]。 ```json { "version": "2.0.0", "tasks": [ { "label": "build hello world", "type": "shell", "command": "\"${env:ProgramFiles(x86)}\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\"", "args": ["amd64"], "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" }, "group": { "kind": "build", "isDefault": true } } ] } ``` 上述JSON片段展示了如何创建一个构建任务来初始化MSVC编译环境;注意这里的路径可能依据个人安装情况有所不同,请根据实际情况调整。 #### 调试配置 除了能够成功编译程序外,良好的调试体验也是必不可少的一部分。可以在`.vscode/launch.json`中定义启动配置以便于断点调试: ```json { "version": "0.2.0", "configurations": [ { "name": "(Windows) Launch", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}/hello.exe", // 替换成实际可执行文件位置 "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "console": "externalTerminal" } ] } ``` 这段代码指定了当点击运行按钮时所使用的参数和选项,其中特别重要的是选择了适合Windows平台上的C++调试适配器类型`cppvsdbg`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值