关于利用 Windows 10 适用于 Linux 的 Windows 子系统 (WSL) 安装 Linux 在 Windows 平台直接运行而不依赖虚拟机并通过 Visual Studio Code 在 Windows 平台直接开发并调试Linux程序这件有趣的事情

1 前言

1.1 背景

  众所周知, 在 Windows 平台下做开发是一件不那么容易的事. 其一, Windows 属于商业闭源系统, 开发环境比较单一, 目前主流的开发环境只有 Visual Studio / Qt 等高度集成IDE. 虽然只要学过两天C/C++就能直接上手干, 跑个 “hello world” 鼓舞下士气. 那么, 然后呢? 对于C/C++这类需要编译的语言, 如何深入地去理解 ‘预处理-编译-汇编-链接’ 过程, 并针对每个过程的结果对C/C++代码进行优化, 在这类IDE上是一个巨大的难题. 其二, Windows 系统, 顾名思义是一个以界面为主的OS, 于是在开发时需要调节某个环节的参数时, 只能通过鼠标点点点点, 找一个参数需要点出四五层窗口来, 不仅操作繁杂, 而且不易记忆. 其三, 几乎每一种语言, 都对应一种最优的开发平台, 这就需要给电脑装一堆IDE, 占用系统资源, 而且大部分IDE收费, 像我们这种穷屌丝为了找个破解方法阅遍天下论坛而身心俱疲, 苦啊…

  自 Linux 诞生, 开源软件浩浩汤汤而来, 开源的思想根植于每个单纯的Programmer的内心深处, 让分享成为主流, 是大多数程序员的梦想. GCC / LVMM / CLANG等优秀的开源工具链的诞生, 更是给予了每个平凡人实现梦想的机会. 如题所述, Windows 居然也开始拥抱开源, 那么, 我们就排除微软CEO脑子有泡的设定, 让我们以开源的信念, 去拥抱这个世界吧!

1.2 开发平台的搭建

  如上所述, 集成 IDE 并不是一个Nice的选择, 那么我们是不是可以用一些优质的开源免费工具去自己构建一个开发环境呢? 当然是可以的啊! 据老夫多年的潜水各大论坛的经验, 代码编辑器+工具链即可实现.

1.2.1 编辑器

  对于代码编辑器, 诸如耳熟能详的 NotePad++ / Vim 等源于 Linux 的文本编辑器, 实现了大多数编程所需的快捷操作, 对于代码的维护来说, 广受群众好评. 但由于入门门槛较高, 且需要高度定制才能变得顺手, 所以这些是给大佬用的, 吾等小菜鸡觉得只学个皮毛够用即可. 除此之外还有一个功能强大如雷贯耳的编辑器, 想必大家都有所耳闻, 即Visio Code Studio. 虽然和 Visio Code 只相差一个单词, 但他俩完全是风马牛不怎么相及的两种东西. VS Code 开源, 而且有那么一帮闲着没事做的家伙为VS Code开发了海量的第三方插件, 开发人员不需做大量的准备工作, 即可搭建出丰富的功能.

1.2.2 工具链

  对于工具链, 上文提到了三种, 而作为 Linux 内核官方工具链, GCC同样是人民群众喜闻乐见的一种 toolchan. 但是呢, 想把 GCC 放到 Windows 上运行, 也是一件比较头痛的事, 目前有如下2种方式供选择:

名称简介
MinGW
用于开发原生Windows应用的开发环境
Cygwin
运行于Windows的类Linux环境

  以上两种方式可谓是挂羊头卖狗肉的办法, 正如中国人常说的那句谚语: 没有一个中间层解决不了的问题, 如果有, 那就加两个.

1.3 Windows+Linux平台

  那么有没有一种更加直接的方式去实现GCC的使用呢? 答案当然是有的. 对于Windows+Linux双系统方案, 有2种方式: 虚拟机方式, 以及 Windows 下 Linux 子系统方式.

1.3.1 虚拟机

  VMWare大家一定听说过, Linux 入门时, 听任何一个网上教程都是这么教的. 采用这种方式可以最大限度保留 Linux 的特性, 并且虚拟机安装的系统可以绝对独立地运行. 当然缺点也比较明显, 需要为虚拟机单独划分一个比较大的独立磁盘空间, 才能保证容纳 Linux 日渐臃肿的体积.

1.3.2 Lunux 子系统

  第二种方式 Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层.

  微软一年一度的build大会都是Windows开发者的盛会,往往发布酷炫的软硬件产品和新服务. 为期3天的build 2019抢在Google IO 2019之前于2019年5月6日召开,在首日的主题演讲中微软发布了一系列软件和服务,其中就包括新一代WSL——WSL2和微软自家的终端模拟器Windows Terminal.

  对于初代WSL, 总体上是在运行时将Linux System Call翻译为NT API调用, 从而在NT内核基础之上模拟实现Linux内核.

  LXSS Manager 是普通的win32进程, 相当于Linux子系统驱动的代理,还负责管理 Linux 进程. Linux Instance 不是普通的 win32 进程, 微软称为Pico Process, 是Linux EFL程序的宿主进程, 实现了沙盒技术中的一种机制.
  lxss / lscore 两个组件是 WSL1 的核心, 负责将Linux 程序中的 System Call "翻译"为等价的NT API调用, 如 fork 翻译为 NtCreateProcess, open 翻译为 NtOpenFile, kill翻译为NtTerminateProcess等. 这两个组件根据洁净室(clean room)原则构建, 完全不含 Linux 代码. 其实该种方案和上文提及的 Cywin 思路有很多类似的地方, Linux徒有其表, 内核完全是模拟出来的.

  对于WSL2, 与WSL1相比, 完全是两个东西, 也许是因为WSL1靠翻译 System Call 来模拟Linux内核的坑太大填不下去了, 这种黑科技思路此次被微软完全抛弃, 换成了虚拟机/容器的思路, WSL2将 Linux 内核塞到一个轻量级的虚拟机(Virtual Machine,VM)中运行, 使用过程与WSL1保持一致, VM的启动/管理都藏在背后.

功能WSL 1WSL 2
Windows 和 Linux 之间的集成
启动时间短
与传统虚拟机相比, 占用的资源量少
可以与当前版本的 VMware 和 VirtualBox 一起运行
托管 VM×
完整的 Linux 内核×
完全的系统调用兼容性×
跨 OS 文件系统的性能×

  由上表可以看出, WSL 2 在跨文件系统表现不够好之外, 其他方面均优于1代. 那么 WSL 2 是一个不错的选择.

2 WSL2 环境搭建及Linux安装

  枯燥的扯淡到此为止, 现在开始实操.

  Windows 提供了一站式安装过程, 即启用所需的可选组件, 下载最新的 Linux 内核,将 WSL 2 设置为默认值, 并安装 Linux 发行版(默认安装 Ubuntu, 请参阅下文更改此设置):

2.1 一站式安装方法

  方法为:

  • 右键开始菜单图标, 启用SowerShell(管理员)
  • 输入: wsl --install
  • 喝杯茶, 等待安装完成

  该种方式简单快捷, 但是, 会默认安装到C盘, 造成后续扩展的问题.

2.2 分步安装

Step 1–启用适用于 Linux 的 Windows 子系统

管理员方式运行PowerShell, 执行下文中的命令:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

  该条命令用于启动 Windows WSL服务, 一般情况下, 该服务为WSL1, 如果需要更新为WSL2, 建议现在转到Step2; 但如果只想安装 WSL1,现在可以重新启动计算机,然后继续执行 Step6 安装所选的 Linux 发行版.

Step 2–检查运行 WSL 2 的要求

  若要更新到 WSL2, 需要运行 Windows 10.

  • 对于 x64 系统: 版本 1903 或更高版本, 采用内部版本 18362 或更高版本.
  • 对于 ARM64 系统: 版本 2004 或更高版本, 采用内部版本 19041 或更高版本.
  • 低于 18362 的版本不支持 WSL2. 使用 Windows Update 助手更新 Windows 版本.

  值得一提的是, WSL2 本质上也是一种虚拟机, 依赖于Hyper-V服务, 而该服务需要直接和CPU/Memory等外设对接. 某些旧版本驱动(比如用心做产品, 用脚写驱动的AMD)会存在一些兼容性问题. 对于我们公司使用的机械革命 Code 01笔记本, BIOS 和 WLAN 驱动旧版本存在兼容性问题, 所以需要更新这两个驱动, 方可消灾免难, 离苦得乐, 远离蓝屏(如果出现蓝屏, 不要慌张, 心中默念般若波罗蜜心经, 等待重启3次后, Windows 10 进入修复模式, 选择安全模式启动, 不出意外的话, 系统会回滚之前的修改).

Step 3–启用虚拟机功能

  安装 WSL2 之前, 必须启用"虚拟机平台"可选功能.

  以管理员身份打开 PowerShell 并运行:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

  重新启动计算机, 以完成 WSL 安装并更新到 WSL2.

Step 4–下载 Linux 内核更新包

  下载更新包: 适用于 x64 计算机的 WSL2 Linux 内核更新包并安装.

Step 5–将 WSL2 设置为默认版本

  打开 PowerShell, 然后在安装新的 Linux 发行版时运行以下命令, 将 WSL 2 设置为默认版本:

wsl --set-default-version 2
Step 6–安装所选的 Linux 分发

  建议直接下载发布版本文件, 而不是通过 Microsoft Store 来安装, 理由很简单, 我不喜欢.

Step 7 手动安装 Linux

  不出意外的话, 你闲得蛋疼把这篇文章看到这里, 你也许已经下载了一个后缀为 .AppxBundle 的文件, 那么好, 不要, 千万千万不要双击点开它, 让我们调戏一下它: 用你趁手的解压缩软件打开它, 那么你会看到若干个后缀 .appx 的文件, For Example:

选中红框标出(后缀为 x64.appx)文件拖出来, 再用解压软件打开拖出来的文件:

  然后我们可以在你喜欢的地方新建一个你希望 Linux 安装的位置, 将上图中所有文件拖入你刚刚新建的文件夹中, 运行 *.exe 文件, 然后喝杯茶吗静静等待, 当看到如下图所示窗口时, 大功告成(Linux 安装完成需要输入用户名和密码, 尽量选个简单点便于记忆且输入方便的, 不然之后每次安装应用时都需要输密码, 搞长了, 烦死你<U•ェ•*U>).

3 Linux 开发环境搭建

  编译一段代码, 需要如下四个步骤:

  • 预处理–将宏定义展开, 以及一些调用关系及声明实例化.
  • 编译–整个过程中最重要的一步, 也是一个toolchan的核心, 将高级语言转换为汇编语言, 本是上还是一堆字符串(高级语言)向另一堆字符串(汇编语言, 包括助记符和伪指令)的过程, 相当于翻译.
  • 汇编–将汇编代码转换为二进制, 所有代码及变量全部变成了一堆数字, 当然还有一些少量的字符串, 包括全局变量和可被调用的函数, 称之为Symbol.
  • 链接–汇编后的结果也是一堆单独的文件, 和 *.c 名称对应, 通过链接, 以Symbol为媒介, 将所有汇编结果整合成一个可被执行的文件.

  那么我们需要什么工具呢? 以gcc-toolchan为例, gcc是 Linux 下官方的编译器, 需要怎样做呢?

3.1 Linux更新

  和 Windows 一样, Linux 发布版虽然可以下载到最新版, 但有些许功能是需要不断维护和更新的, 那么, 我建议使用前将 Linux 保持最新. 但是, 原生 Linux 更新镜像一般为国外服务器, 想要在合法的情况下使用更新功能, 我建议更换为国内镜像.

  镜像路径为: etc\apt\source.list, 使用vim打开, 将所有网址用以下任意一个替换即可:

PS-我用的是清华的源, 简言之, 我是清华的<U•ェ•*U>

之后, 使用下列指令更新Linux

sudo apt update

等待完成.

3.2 gcc工具链安装

输入如下指令:

sudo apt-get install gcc g++
sudo apt-get install gnu
sudo apt-get install cmake
sudo apt-get install vim

3.3 测试

  万事万物从helloworld开始, vim编辑新建一个文件vim ./HelloWorld.c, vim 不能直接编辑, 需要键入输入命令ai等,然后输入:

#include<stdio.h>
int main() 
{ 
    printf("Hello world!\n");
    return 0;
} 

  按Esc, 然后输入命令: :wq保存.

  然后gcc编译:

gcc HelloWorld.c -o HelloWorld.o

  如果一切正常的话, 说明程序安装正确, 如果有啥问题的话, emmmm, 请google一下.然后执行一下:

./HelloWold.o

  你会看到如下结果:

4 Windows 环境搭建

4.1 安装 VS code

  这一步不再赘述, 一般情况下有手就会(注意选择添加到系统PATH).

4.2 安装插件

Step 1 安装 Remote Development 插件

  在 VS Code 界面按Ctrl+Shift+X组合键, 在 Extention 侧边栏输入Remote, 弹出好多, 你可以选择Remote Development(包含整个远程开发工具包, WSL支持只是其中1项)或Remote - WSL(如果没有其他远程调试需求的话)

Step 2 通过 Remote - WSL 连接 Linux

  在此之前, 强烈建议先在 Linux 通过 mkdir FolerName建一个文件夹, 我这里起了个名字VS_Code_Test_Folder

  • 方法 1 在 Linux 窗口定位到所需的文件夹, 输入code .从 Linux 端启动VS Code
  • 方法 2 打开 VS Code, 按组合键Ctrl+Shift+P, 在搜索框输入Remote-WSL, 或点击窗口左下角, 见下图, 然后选择Remote-WSL: New WSL Window或者你需要的方式, 然后选择你所需要的路径.

  上述操作完成后, 可以看到下图中的界面.

Step 3 在Linux端安装相关插件

  我们已经通过 VS Code 打开了 Linux, 如果需要通过 VS Code 调试代码, 我们还需要安装如下插件:

  • [C/C++] 这个肯定是编译C/C++程序必不可少的
  • [Code Runner] 这个也是必不可少的,代码运行插件, 用于调试
  • [CMake] CMake 语法支持
  • [CMake Tools] CMake 工具, 可在窗口底部直接点击以进行编译/调试操作

  至此, 平台已经搞好了, 可以敲代码, 可以调试程序, 不用像 Cywin 和 MinGW 那样, 调试过程中, 程序如果在运行的情况下, 连断点都大不了, 气人. 之后感兴趣的同学可以了解下 makefile 和 CMake, 以实现多文件编译. 相比于 makefile, CMake 语法更简单, 通用性更强, 很多开源代码都采用该种方式, 如嵌入式常用的 CMSIS(Cortex Microcontroller Software Interface Standard, 这里面有好多有用并值得借鉴的东西, 等老夫哪天有空了, 唉, 会有空吗? )等.

以上

参考:

Logo

更多推荐