之前一直在Ubuntu下编写C/C++程序,体验十分良好,工具链一应俱全。然而,Linux下的办公和通讯软件少之又少,日常用起来的体验太差。WSL(Windows Subsystem Of Linux)一代虽然充满黑科技,但是看微软团队的意思,应该是技术难度过大,只好妥协一下,采用类虚拟机的方式来实现WSL2,技术上和虚拟机无差,也正好满足我的需求,常用软件的适配也十分积极,最近尝试了一下WSL2,内核轻量化,启动非常快,使用起来比虚拟机要方便。刚开始使用时按照以前Linux的使用经验去配置,出现了一些问题,网上搜到的一些文章要么莫名其妙,要么漏洞百出,踩了一些坑,浪费了很多时间才解决。这里记录下WSL2的配置以及后续配置C/C++环境的方法。

WSL2的安装和基本配置

安装

WSL2的安装方式有两种。

  • 打开Win10的应用商店搜索Ubuntu关键字,根据个人喜好选择Ubuntu版本即可(其他发行版类似,下面的配置都默认发行版为Ubuntu20.04版本)。(推荐的方式)
  • 去微软官网下载独立的软件包,然后在自己想要安装的位置点击安装即可,这时你安装的WSL2是在你安装它的位置,可以避免占用C盘空间,但是这样安装的话会存在一些问题,比如CLion无法检测到你系统内安装在C盘以外的WSL,而且VSCode连接WSL后的智能检测也会出问题,自动补全也会出错。所以不推荐这样安装

配置软件源

WSL2的微软商店评论区中有人评论说:“不要更换官方的软件源,更新后会出问题”。我按照正常的方法去配置后没有发现问题,可能是微软官方已经修复了。这里软件源的配置和单系统的Ubuntu没有任何区别。

1
2
3
4
5
cd /etc/apt/ # 进入镜像文件所在的目录
ls
sudo rm sources.list # 这里图方便直接选择删除镜像文件,也可以先备份一下,备份方法 sudo cp ./sources.list ./sources.list.backup
sudo touch sources.list # 新建镜像文件
sudo nano sources.list # 选择自己习惯的镜像源,复制镜像然后粘贴并保存即可,我自己选用的是阿里的源

阿里的Ubuntu软件源(这里是ubuntu20.04版本的软件源,其他版本的自行搜索

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

最后通过sudo apt update更新软件源即可。

配置Git

1
2
git config --global user.name "你的用户名"
git config --global user.email "你的邮箱"

配置网络代理

一般在Linux发行版上使用代理,通过一些代理软件即可实现。WSL2没有GUI,且网络和Windows是分开的,配置网络代理不方便,而且Windows对于WSL而言其ip是动态的,因此想要实现代理比较麻烦,这里提供一个小脚本来实现**(前提是Windows配置了代理)**。

微软官方提供了WSL2获取Windows IP的方式,相关信息存储在了/etc/resolv.conf文件中,通过cat查看文件内容

1
cat /etc/resolv.conf

文件格式如下所示

1
2
3
4
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.31.176.1

可以看到提供了一个nameserver字段来对应Windows的IP地址。有了IP地址事情就变得简单了。

1
cat /etc/resolv.conf|grep nameserver|awk '{print $2}'

上述命令可以直接获取IP值,配合Windows的Socks代理端口即可实现WSL的网络代理(我设置的端口号为12000,可根据个人情况自行配置)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export windows_host=`cat /etc/resolv.conf|grep nameserver|awk '{print $2}'`
export ALL_PROXY=socks5://$windows_host:10808
export HTTP_PROXY=$ALL_PROXY
export http_proxy=$ALL_PROXY
export HTTPS_PROXY=$ALL_PROXY
export https_proxy=$ALL_PROXY

if [ "`git config --global --get proxy.https`" != "socks5://$windows_host:10808" ]; 
then git config --global proxy.https socks5://$windows_host:10808
fi

上述命令同时配置了终端代理与git代理,后续根据个人情况复制到.bashrc或者.zshrc文件的底部即可。更多细节可参考这篇文章

配置ZSH(可选)

zsh是一个相当实用的shell,在兼容bash语法与易用性之间达到了平衡,我个人推荐是使用zsh,至于bash shell或者fish shell则依据个人喜好选择即可。这里提供zsh的配置方式。

首先安装zsh

1
sudo apt install zsh

之后切换到zsh并更改默认shell(可选,后续安装oh-my-zsh会提供切换默认shell的选项)

1
2
zsh
chsh

安装oh-my-zsh

1
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

这里需要注意的是,如果是安装到当前用户,无需添加sudo参数,否则会安装到root用户上,而WSL对root提供的操作很少,一般都是使用在安装WSL时新建的用户来进行日常操作,这里推荐安装到当前用户。(如果没有配置代理的话,安装过程会非常的不顺利,可以选择去Gitee上寻找oh-my-zsh的国内仓库,按照文档自行安装。)

安装好oh-my-zsh时,会提示你是否将zsh为默认的shell,这里选择y即可。

安装插件

oh-my-zsh不仅帮你简化了zsh的配置,也给你提供了插件的选项,这里推荐git(zsh内置的插件)、zsh-autosuggestionszsh-syntax-highlighting这三个插件,自行安装插件后在.zshrc文件的plugin选项后面用空格分开插件名即可。

  • 安装zsh-autosuggestions
1
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
  • 安装zsh-syntax-highlighting
1
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my- zsh/custom}/plugins/zsh-syntax-highlighting

安装后对.zshrc文件中的plugin选项进行设置即可,如下所示

1
plugins=(git zsh-syntax-highlighting zsh-autosuggestions)

使用powerlevel10k主题

这是一个非常好用且启动速度超快的oh-my-zsh主题(Github仓库地址),按照作者提供的文档内容自行配置即可。

WSL内置的VSCode支持

WSL作为微软的产品,几乎无缝对接自家的VSCode Editor,在WSL中使用VSCode非常简单,第一次使用需要先安装VSCode的支持。

1
sudo apt install code

之后想要在WSL里使用VSCode打开、创建与编写文件,只需要用code指令即可,使用起来类似vimnano

注意:无法以sudo的方式使用code命令,想要对一些根目录下的文件进行操作的话,可以先chown到当前用户,对文件操作完成后再改回root,例如:

1
sudo chown myuser /path/to/file

对文件操作完成后,再更改文件持有者为root

1
sudo chown root /path/to/file

C/C++环境配置

安装C/C++工具链

工具链的配置和原生Linux没有什么区别,根据自身需求安装好cmake、make、gdb、gcc等工具即可。

1
sudo apt install cmake make gdb gcc

IDE配置

VisualStudioCode

VSCode对WSL的本地支持通过插件实现,在扩展商店搜索Remote Development关键字即可看到扩展包合集,按需安装即可(其中Remote-WSL必须安装)。

插件市场中的Remote Development合集

安装完成后,就可以通过左下角的按钮来进入WSL环境进行开发了。

CLion

CLion已经对WSL提供了原生支持,本质上其实是对原本SSH的开发方式进行了二次封装。在配置CLion前需要先配置WSL中的SSH服务,手动配置的话稍微有点麻烦,好在Jetbrains公司提供了一个脚本进行自动化配置。

在终端里自建.sh格式的脚本文件,复制下面的脚本内容并保存然后执行即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash
set -e

SSHD_LISTEN_ADDRESS=127.0.0.1

SSHD_PORT=2222
SSHD_FILE=/etc/ssh/sshd_config
SUDOERS_FILE=/etc/sudoers
  
# 0. update package lists
sudo apt-get update

# 0.1. reinstall sshd (workaround for initial version of WSL)
sudo apt remove -y --purge openssh-server
sudo apt install -y openssh-server

# 0.2. install basic dependencies
sudo apt install -y cmake gcc clang gdb valgrind build-essential

# 1.1. configure sshd
sudo cp $SSHD_FILE ${SSHD_FILE}.`date '+%Y-%m-%d_%H-%M-%S'`.back
sudo sed -i '/^Port/ d' $SSHD_FILE
sudo sed -i '/^ListenAddress/ d' $SSHD_FILE
sudo sed -i '/^UsePrivilegeSeparation/ d' $SSHD_FILE
sudo sed -i '/^PasswordAuthentication/ d' $SSHD_FILE
echo "# configured by CLion"      | sudo tee -a $SSHD_FILE
echo "ListenAddress ${SSHD_LISTEN_ADDRESS}"	| sudo tee -a $SSHD_FILE
echo "Port ${SSHD_PORT}"          | sudo tee -a $SSHD_FILE
echo "UsePrivilegeSeparation no"  | sudo tee -a $SSHD_FILE
echo "PasswordAuthentication yes" | sudo tee -a $SSHD_FILE
# 1.2. apply new settings
sudo service ssh --full-restart
  
# 2. autostart: run sshd 
sed -i '/^sudo service ssh --full-restart/ d' ~/.bashrc
echo "%sudo ALL=(ALL) NOPASSWD: /usr/sbin/service ssh --full-restart" | sudo tee -a $SUDOERS_FILE
cat << 'EOF' >> ~/.bashrc
sshd_status=$(service ssh status)
if [[ $sshd_status = *"is not running"* ]]; then
  sudo service ssh --full-restart
fi
EOF
  

# summary: SSHD config info
echo 
echo "SSH server parameters ($SSHD_FILE):"
echo "ListenAddress ${SSHD_LISTEN_ADDRESS}"
echo "Port ${SSHD_PORT}"
echo "UsePrivilegeSeparation no"
echo "PasswordAuthentication yes"

保存后执行该脚本

1
sh ./ubuntu_setup_env.sh

该脚本实际上是配置了一个端口号为2222的本地SSH服务。

之后打开一个CLion项目并进入设置界面,找到Toolchains选项,点击+号选择WSL即可出现下面的窗口

点击Credentials最右边的设置按钮进入SSH Configurations界面,输入WSL的用户名和密码即可。

配置完成后即可正常编写C/C++代码。如检测到缺少诸如cmake、gcc等工具,请在WSL中自行安装。