文章

在 Windows 中部署和使用 WSL 并进行跨平台 C/C++ 开发

本文介绍了如何在 Windows 操作系统中适用微软官方提供的 WSL(Windows Subsystem for Linux) 工具部署 Linux 子系统。


1. 什么是 WSL

官方文档:https://learn.microsoft.com/zh-cn/windows/wsl/

适用于 Linux 的 Windows 子系统 (WSL) 可让开发人员直接在 Windows 上按原样运行 GNU/Linux 环境(包括大多数命令行工具、实用工具和应用程序),且不会产生传统虚拟机或双启动设置开销。

1.1. WSL 1 和 WSL 2

功能 WSL 1 WSL 2
托管 VM
完整的 Linux 内核
完全的系统调用兼容性
跨 OS 文件系统的性能

WSL 1 和 WSL 2 之间的主要区别在于,是否在托管 VM 内使用实际的 Linux 内核、支持完整的系统调用兼容性以及跨 Linux 和 Windows 操作系统的性能。 WSL 2 是安装 Linux 发行版时的当前默认版本,它使用最新最好的虚拟化技术在轻量级实用工具虚拟机 (VM) 内运行 Linux 内核。从上面的比较表中可以看出,WSL 2 架构在几个方面优于 WSL 1,但跨 OS 文件系统的性能除外,对于这种情况,可通过将项目文件存储在与处理项目时运行的工具相同的操作系统上进行处理。

https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps 注意!如果需要使用 Linux 的 GUI 程序,只能使用 WSL 2。

1.2. 例外情况(使用 WSL 1 而不是 WSL 2)

我们建议使用 WSL 2,因为它提供更快的性能和100% 的系统调用兼容性。 但是,在某些特定情况下,你可能会更倾向于使用 WSL 1。 在以下情况下,请考虑使用 WSL 1:

  • 你的项目文件必须存储在 Windows 文件系统中。 WSL 1 可以更快地访问从 Windows 装载的文件。 如果你将使用 WSL Linux 分发版来访问 Windows 文件系统上的项目文件,并且这些文件无法存储在 Linux 文件系统上,那么,通过使用 WSL 1,你将跨 OS 文件系统实现更快的性能。
  • 一个项目要求对相同的文件使用 Windows 和 Linux 工具进行交叉编译。 在 WSL 1 中,跨 Windows 和 Linux 操作系统的文件性能比 WSL 2 中更快,因此如果要使用 Windows 应用程序来访问 Linux 文件,则目前通过 WSL 1 可实现更快的性能。
  • 你的项目需要访问串行端口或 USB 设备。 但是,现在可通过 USBIPD-WIN 项目为 WSL 2 提供 USB 设备支持。 有关设置步骤,请参阅连接 USB 设备。
  • WSL 2 不支持访问串行端口。 有关详细信息,请参阅常见问题解答或 WSL GitHub 存储库中有关串行支持的问题。
  • 有严格的内存要求 WSL 2 的内存使用量会随使用而缩放。 当进程释放内存时,这会自动返回到 Windows。 但从现在开始,在关闭 WSL 实例前,WSL 2 还不会将内存中缓存的页面释放回 Windows。 如果你有长时间运行的 WSL 会话或访问非常大量的文件,此缓存可能会耗尽 Windows 内存。 我们通过 WSL GitHub 存储库问题 4166 跟踪工作以改善此体验。
  • 对于使用 VirtualBox 的用户,你可能需要考虑你正在运行的版本以及它是否与 WSL 2 兼容。 (有关完整讨论,请参阅 WSL GitHub 存储库问题 798。VirtualBox v6.1.16 似乎适用于 WSL 2,但其他版本可能遇到问题。)
  • 如果依赖 Linux 发行版在与主机相同的网络中拥有 IP 地址,则可能需要设置一种替代方法来运行 WSL 2。 WSL 2 作为 hyper-v 虚拟机运行。 这是对 WSL 1 中使用的桥接网络适配器的更改,这意味着 WSL 2 使用网络地址转换 (NAT) 服务作为其虚拟网络,而不是将其桥接到主机网络接口卡 (NIC),从而生成唯一的将在重启时更改的 IP 地址。 要详细了解将 WSL 2 服务的 TCP 端口转发到主机 OS 的问题和缓解措施,请参阅 WSL GitHub 存储库问题 4150,NIC 桥接模式(TCP 缓解措施)。

2. 安装 WSL

启动运行(Win+R)依次输入以下命令。

  • 开启 WSL 服务
1
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
  • 开启虚拟化服务
1
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  • 设置 WSL 的默认架构为 WSL 2,这将使你安装的任何新发行版初始化为 WSL 2 发行版(WSL 1 类似)。
1
wsl set-default-version 2
  • 选用下面两种命令中的一种直接安装 WSL

    • 直接安装 WSL(依赖系统更新来更新 WSL)

      1
      2
      
      wsl --install
      wsl --install -d Ubuntu-22.04    //<--可能需要指定distribution
      
    • 或者 直接安装 WSL 2(依赖 Windows Store 更新包来更新 WSL)

      1
      
      wsl.exe --install
      
    • 若提示 安全频道支持出错 则启动运行(Win+R)输入 inetcpl.cpl,在弹出的 Internet属性 窗口,切换至 高级 选项卡,找到设置中的 使用TLS 1.2 最后点 应用 保存,然后重新尝试上述命令安装即可。

  • 设置密码

    使用 WSL 安装 Linux 发行版的过程完成后,会弹出一个新的控制台窗口,创建 Linux 账户和密码。若没有自动弹出,可以使用 “开始” 菜单打开该发行版(默认情况下为 Ubuntu)。 系统将要求你为 Linux 发行版创建“用户名”和“密码”。

    • 此用户名和密码特定于安装的每个单独的 Linux 分发版,与 Windows 用户名无关。
    • 请注意,输入 密码时,屏幕上不会显示任何内容。 这称为盲人键入。 你不会看到你正在键入的内容,这是完全正常的。
    • 创建用户名和密码后,该帐户将是分发版的默认用户,并将在启动时自动登录。
    • 此帐户将被视为 Linux 管理员,能够运行 sudo (Super User Do) 管理命令。
    • 在 WSL 上运行的每个 Linux 发行版都有其自己的 Linux 用户帐户和密码。 每当添加分发版、重新安装或重置时,都必须配置帐户。
    • 忘记用户账户密码可以通过在 Windows 下进入 root 账户重新设置
      1
      2
      
      wsl.exe --user root
      passwd [your_user_name]
      
  • 更新 WSL(若要使用GUI程序请务必更新)

在 Windows 下

1
2
wsl --update
wsl --shutdown

在 WSL 中

1
sudo apt update && sudo apt upgrade

2.1. 安装 C/C++ 开发环境依赖

在 WSL 控制台(VScode远程模式下的终端)安装如下程序包,配置 Linux 下的 C/C++ 开发环境:

1
2
3
sudo apt-get install build-essential
sudo apt-get install gdb
sudo apt-get install cmake

2.2. 安装 Python 开发环境依赖

2.2.1. 依靠第三方安装(推荐)

参考官网(https://docs.conda.io/projects/miniconda/en/latest/) 安装 miniconda 环境

1
2
3
4
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm -rf ~/miniconda3/miniconda.sh

安装完毕后输入以下命令初始化控制台

1
~/miniconda3/bin/conda init bash

查询 conda 版本,确认是否安装成功

1
conda -V

换源

1
nano ~/.condarc

然后在弹出的编辑界面粘贴以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
channels:
  - defaults
show_channel_urls: true
channel_alias: https://mirrors.tuna.tsinghua.edu.cn/anaconda
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

最后使用 CTRL + X 保存退出,然后更新缓存

1
sudo apt-get update

然后依次执行以下常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 更新conda
conda update conda
 
# 查看虚拟环境列表
conda env list

# 创建虚拟环境
conda create --name <env_name> [python_version] [package_name]
conda create --name li python=3.9 # 例子

# 启动环境(注意以后安装包都要先启动环境)
conda activate li

# 查看--安装--更新--删除包
conda list
conda search <package_name> # 查询包
conda install <package_name>
conda install package_name=1.5.0
conda update package_name
conda remove package_name

# pytorch 可以用pip安装,方便快捷,默认gpu版本
pip3 install torch

2.2.2. 在系统环境下安装

如果要从 Python 源代码开始编译 Python 解释器,则需要安装如下依赖

1
sudo apt install zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libbz2-dev liblzma-dev sqlite3 libsqlite3-dev tk-dev uuid-dev libgdbm-compat-dev

如果从第三方 PPA(Personal Package Archive)安装 Python

1
sudo add-apt-repository ppa:deadsnakes/ppa

然后再次更新 apt

1
sudo apt update

可以看到新增的 PPA 也加入更新来源列表了

1
2
3
4
5
6
7
8
9
Hit:1 http://security.ubuntu.com/ubuntu jammy-security InRelease
Hit:2 http://archive.ubuntu.com/ubuntu jammy InRelease                           
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease                   
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease                 
Hit:5 https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

然后就可以安装 Python,以 3.9 版本为例(PYthon 3.10 是 Ubuntu 22.04 LTS 自带的默认 Python 3 版本因此不提供下载,但 WSL2 默认似乎没有 Python)

1
sudo apt install python3.9

然后通过以下命令确认安装是否成功(成功的话应该能看到 Python 版本号)

1
python3.9 --version

以后即可用 python3.9 来运行脚本,而不是使用 python 或者 python3

2.3 配置 GUI 开发环境

安装 mesamesa 可以支持 glxinfo 命令,这个命令可以查看很多与显卡、OpenGL 相关的信息

1
sudo apt-get install mesa-utils

然后查看显卡是否能够识别

1
glxinfo | grep rendering

获取显卡 OpenGL 版本信息

1
glxinfo | grep OpenGL
1
sudo apt-get install libglfw3-dev

3. 配置 VSCode

https://learn.microsoft.com/zh-cn/windows/wsl/tutorials/wsl-vscode Visual Studio Code以及 WSL 扩展使你能够直接从 VS Code 将 WSL 用作全职开发环境。

通过下面两种方式中的一种在 WSL 下启动 VSCode:

  • 在启动运行(Win+E)中输入 wsl 然后输入 code . 启动远程模式下的 VScode。
  • 在Windows 中打开 VScode 然后点击左下角蓝色的 打开远程窗口 按钮。

注:在 WSL 中打开 Windows 本地的项目,Windows 中的所有路径默认在 /mnt/ 下。

指令检查版本确认是否安装成功

1
2
3
4
gcc -v
g++ -v
cmake --Version
gdb -v

在 WSL 中安装需要的扩展(与 Windows 本地扩展不共享,因此需要重新安装)。根据项目需要自行选择安装:

  • Chinese Simplifed
  • WSL
  • C/C++
  • CMake
  • Cmake Tools
  • Python

4. 跨系统文件存储和访问

  • 若要在 Windows 文件资源管理器中打开 WSL 项目,请输入:explorer.exe . 请确保在命令的末尾添加句点以打开当前目录。

  • 将项目文件与计划使用的工具存储在相同的操作系统上。 若想获得最快的性能速度,请将文件存储在 WSL 文件系统中,前提是使用 Linux 工具在 Linux 命令行(Ubuntu、OpenSUSE 等)中处理这些文件。 如果是使用 Windows 工具在 Windows 命令行(PowerShell、命令提示符)中工作,请将文件存储在 Windows 文件系统中。 可以跨操作系统访问文件,但这可能会显著降低性能。

例如,在存储 WSL 项目文件时:

  • 使用 Linux 文件系统根目录:\\wsl$\<DistroName>\home\<UserName>\Project(比如 \\wsl$\Ubuntu-22.04\home\zhangsan
  • 而不使用 Windows 文件系统根目录:C:\Users\<UserName>\Project/mnt/c/Users/<UserName>/Project$

5. 参考文献

[1] Reichtum. 【知乎】vscode wsl子系统 c++环境配置基础篇

[2] 东庭揽月. 【知乎】WSL+VSCode食用指南

[3] Ethan Shen. 【知乎】搭配 VS Code Remote 远程开发扩展在 WSL 下开发

[4] luckyum. 【知乎】在Windows下通过VSCode和WSL编译C++程序

本文由作者按照 CC BY 4.0 进行授权