摘要:在 Windows 环境下,通过 WSL (Windows Subsystem for Linux) 配合 VS Code,可以获得接近原生的 Linux 开发体验。本文记录如何在 WSL 中配置高效的 C/C++ 开发环境。
目录
前言
WSL 是 Windows Subsystem for Linux(Windows 的 Linux 子系统)的缩写,是 Windows 上的一项原生功能。通过该功能,你可以实现在 Windows 系统上运行 Linux 环境而不需要开启虚拟机,可谓十分方便。
鉴于 Linux 环境下进行 C/C++ 开发极其友好,本文主要探讨通过 VS Code + WSL 配置 C/C++ 开发环境的可行性。
为什么选择 WSL?
相较于在 Windows 上使用 MinGW 进行编译开发,基于 WSL 的开发环境主要有以下优点:
-
配置过程更简洁: MinGW 方案在配置过程中通常需要手动处理复杂的系统环境变量,且正确下载并安装 MinGW 本身就是一项挑战。而 WSL 可以通过在 CMD 或 PowerShell 中敲几行命令实现。
-
编译支持更完整: 根据 VS Code 官方文档,自 2024 年 11 月 3 日起,MSYS2 已默认禁用 mingw-w64 的通配符支持。这直接影响了构建命令中对
*.cpp等通配符的处理方式。“Starting November 3, 2024, MSYS2 has disabled wildcard support for mingw-w64 by default. This affects how wildcards such as '*.cpp' are handled in build commands.”
而 WSL 由于内置 GCC 编译器仍然支持对诸如
g++ *.c -o main的命令,这使得其在编译多文件时更为方便。
WSL 的配置
参阅 WSL 的官方文档,我们开始在 Windows 上配置 WSL。
配置前的准备
接下来我来演示从零开始安装 WSL。
1. 检查设备是否开启虚拟化
在 CMD 或者 PoweShell 中输入这个命令检查设备是否开启了 CPU 虚拟化:
Get-ComputerInfo -Property "HyperV*"
输入之后输出结果中
HyperVRequirementVirtualizationFirmwareEnabled
返回值应该是True(如下图所示)
2.系统准备工作
在 PowerShell里面执行以下命令:
# 开启 WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
# 开启虚拟机平台
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
之后系统会要求你重启,或者你可以手动重启。
除此之外还可以通过控制面板来开启这两个功能: 在 Windows 搜索里面搜索“控制面板”并打开
然后在控制面板中寻找并打开“启用或关闭Windows功能”(如图所示)
将 Hyper-v 、Windows 的 Linux 子系统、虚拟机平台全部勾选上点击确定,
之后系统会要求重启,至此准备工作全部完成。
安装 WSL
在前面的准备工作完成之后,接下来的 WSL 安装极为简单。 在 CMD 或者 PowerShell 中执行以下命令:
wsl --install
在科学上网工具的帮助下通常几秒就可以完成下载并开始安装
官方文档中表示执行命令后会默认下载 Ubuntu 系统(然鹅我在实践过程中并非如此),那么在安装完成之后执行wsl -l -v可以查看已安装的 Linux 发行版。
之后弹出的命令框会要求你设置用户名和命名,注意:在设置密码时密码不会显示!
安装好 WSL 之后我们在 Window 终端中执行 wsl 就可以转换到 Linux 环境,路径提示符会从类似
C:\Users\Name
变成
user@hostname:/mnt/c/Users/Name
这样的。
我们在终端中执行以下命令来检查更新:
sudo apt update && sudo apt upgrade
输入密码之后就开始跑码了
至此,WSL 的核心安装已经完成,我们已经具备基本的 Linux 开发环境。但是为了后续工作我们还需要进一步设置(如果 Linux 发行版是 Ubuntu 的话是可以直接跳到下一步的)
进一步的工作
这里给出一些 WSL 常用命令
# 安装默认的 Ubuntu 发行版(需重启后生效)
wsl --install
# 在当前目录打开 WSL
wsl
# 查看已安装发行版及其运行版本 (WSL 1/2),简写为`wsl -l -v`
wsl --list --verbose
# 删除 WSL 所有数据(危险操作)
wsl --unregister <发行版名>
# 列出可下载的 Linux 发行版
wsl --list --online
# 下载特定 Linux 发行版
wsl --install -d <发行版名>
这是执行wsl --list --online的输出
接下来我们在 Linux 环境检查 C/C++ 编译链: 我们在终端中执行以下命令
# 检查 GCC 编译器版本
gcc --version
# 检查 G++ 编译器版本
g++ --version
# 检查 GDB 调试器版本
gdb --version
输出结果如下图则说明编译链完整
如果输出结果显示command not found说明你需要安装工具链,那么请执行以下命令
# 首先更新软件源索引
sudo apt update
# 安装 build-essential 工具包(包含 gcc, g++, make 等)
sudo apt install build-essential gdb
然后再次检查即可,至此我们在 WSL 的配置工作就全部完成了
VS Code 的安装与基础配置
VS Code 的安装
VS Code 的官方下载地址如下
https://code.visualstudio.com/Download
下载页面如图所示:
选择 Windows x64 版本下载
下载完成之后运行安装程序
勾选“同意”之后点击“下一步”,选择合适的安装路径并点击“下一步”
注意一定要勾选添加到PATH
点击“下一步”之后开始安装,并完成安装
这样 VS Code 就安装到你的电脑上了
VS Code 的基础配置
1.设置简体中文(可选)
现在你看到的界面是全英文的,为了方便,我们为 VS Code 配置简体中文
我们点击“Extension”或者使用快捷键Ctrl + Shift + X打开扩展市场
在搜索框中搜索“Chinese”,选择“Chinese(Simplified)” 点击“Install” 重启应用即可应用更改
可以看到界面已经变成了中文
2. 插件安装以及连接 WSL
我们在扩展市场中搜索“C/C++ (Microsoft)”,安装对应扩展
为了实现 WSL 连接到 VS Code 我们还要下载“Remote - WSL”、“WSL (Microsoft)”(推荐)这两个扩展,我们在扩展市场中搜索“wsl”,下载这两个扩展。
随后我们在设备上创建一个文件夹存放我们的源代码,打开文件夹,在上方地址栏中输入“cmd"并回车在该路径打开终端,在终端中输入“wsl”转换为 Linux 环境,在终端中输入这个命令
code .
连接 VS Code
首次连接 WSL 会自动下载连接 VS Code 所需文件
待进度条跑完后会自动打开 VS Code
至此 WSL 成功连接至 VS Code,而环境配置工作也基本完成了!
C/C++ 开发环境的配置
到了这一步我们的工作已然完成了 90% !接下来我会介绍如何配置 C/C++ 开发环境
单文件的编译与运行
我们在文件夹里面新建一个文件夹,命名为“test”,打开文件夹,在里面新建一个文件,命名为“helloWorld.c”,将以下这段代码复制进去
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
点击右上角的“运行C/C++文件”,接下来他会要求你选择编译器,选择“gcc” 接下来就会编译并运行,如果在下方的终端输出“Hello World!”说明已经成功运行了。
随后会在创建的文件夹里面创建一个“.vscode”文件夹,打开你会发现里面有一个名为“tasks”的 json 配置文件。这是VS Code 的编译配置文件。
接下来就是实现多文件的编译与运行
多文件的编译与运行
这里给出三个 C 文件
"test.c"
#include <stdio.h>
#include "max.h"
int main()
{
int a = 10;
int b = 20;
int c = findMaxNum(a, b);
char d = 97;
printf("%c\n", d);
return 0;
}
"max.h"
#ifndef __MAX_H__
#define __MAX_H__
#include <stdio.h>
int findMaxNum(int num1, int num2);
#endif // __MAX_H__
"max.c"
#include "max.h"
int findMaxNum(int num1, int num2)
{
return num1 > num2 ? num1 : num2;
}
在文件夹里创建一个新文件夹命名为“test2”并在里面创建这三个文件 这时你会发现你点击运行要不没有输出要不报错,这实际上不是开发环境出现什么问题,因为编译器默认只编译当前文件,而不会自动链接其他源文件,但是运行“test.c”这个程序需要把“max.c”、“max.h”都编译完成。
这时候就要配置控制台的json文件。 然鹅实际上,你还可以在终端中执行命令
gcc test.c max.c -o main
可以对源代码进行正确编译,
你也可以自己学习如何配置“launch.json”和“tasks.json”,不过我想来你也是乐于抄代码的,所以我把代码附在下面
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C: gcc 生成活动文件",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${fileDirname}/*.c",//决定单文件还是多文件编译,现在是多文件,单文件是 ${file},空间命名不要用空格,空格会用作分割参数,这样可能导致路径不完整
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "编译器: /usr/bin/gcc"
}
]
}
对于 ${fileDirname}/*.c:由于 WSL 使用的是 Linux 的 Shell(如 bash),它原生支持通配符 *.c,可以匹配当前目录下的所有 .c 文件;而 Windows 下的 MinGW 默认并不支持这种通配符展开。因此,这里使用 *.c 的作用是一次性编译当前目录中的所有 C 源文件,这是实现多文件编译的关键方法。
launch.json
// 此文件主要用于.c或.cpp文件的调试
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug", // 配置名称
"type": "cppdbg", // 配置类型,cppdbg对应cpptools提供的调试功能;可以认为此处只能是cppdbg
"request": "launch", // 请求配置类型,可以为launch(启动)或attach(附加)
"program":"${fileDirname}/${fileBasenameNoExtension}",// 将要进行调试的程序的路径
"args": [],// 程序调试时传递给程序的命令行参数,这里设为空即可
"stopAtEntry": false, // 设为true时程序将暂停在程序入口处,相当于在main上打断点
"cwd": "${fileDirname}", // 调试程序时的工作目录,此处为源码文件所在目录
"environment": [],
"externalConsole": false,// 为true时使用单独的cmd窗口,跳出小黑框;设为false则是用vscode的内置终端,建议用内置终端
"internalConsoleOptions": "neverOpen",// 如果不设为neverOpen,调试时会跳到“调试控制台”选项卡,新手调试用不到
"MIMode": "gdb", // 指定连接的调试器,gdb是minGW中的调试程序
"miDebuggerPath": "/usr/bin/gdb", // 指定调试器所在路径,,则要改成你自己的路径
"preLaunchTask": "C: gcc 生成活动文件" ,// 调试开始前执行的任务,我们在调试前要编译构建。与tasks.json的label相对应,名字要一样
"miDebuggerArgs": "-q -ex quit; wait() { fg >/dev/null; }; /bin/gdb -q --interpreter=mi"
}]
}
在.vscode文件夹中创建launch.json并保存,再回到“test.c”中运行文件会发现它会自动一键编译
写在最后
本文基于 WSL 这个 Windows 原生功能,通过 VS Code 远程连接实现了在 Windows 平台上获得了 Linux 的开发环境。
前面我们已经知道了该方案的诸多优点,然鹅该方案实际上也是存在不少缺点的,首先就是若非借助科学上网工具下载 WSL 相关组件就比较困难(虽然实际上是有离线部署的方案,不过鉴于题主并未实践过在此就不再赘述了),另外由于本方案实际上是通过远程连接的方式连接 WSL 所以相对于原生开发环境它可能会有连接不稳定或启动较慢以及性能损耗等问题。此外在文件系统跨界访问上:虽然在 /mnt/c/ 下开发很方便,但由于跨文件系统的 I/O 性能损耗,官方通常建议将代码放在 WSL 的主目录下(如 ~/projects)以获得更快的编译速度。
至于通配符问题,题主采用本方案原因很大一部分原因就是因为此。但是实际上更好的解决方案是学习使用 CMake 。
不管怎么样,对于题主来说这都是一个充满艰难、激动的一个复杂历程。