# WSL+Manjaro+Xfce打造完美开发环境 ## 目标 + 基于WSL,运行具有图形界面的Linux程序 + 使用Manjaro避开Ubuntu等WSL发行版大版本升级容易产生的问题 + 使用`ssh`和`Visual GDB`,在Linux环编译境下用Visual Studio开发C++程序——有Linux上编译环境的省心,又可以利用Visual Studio这一宇宙第一IDE进行大型项目开发。 ## 安装 安装的过程主要参考了[WSL使用小结:从ArchLinux到Manjaro](https://www.cnblogs.com/wurui1994/p/7839777.html),但这篇文章还是有一些点没有讲到,这里补充一下。 首先,去控制面板开启`WSL`,然后去应用商店装个`Ubuntu`,这都属于常规操作。 应用商店装完`Ubuntu`后,启动之,这时会释放实际的`Ubuntu`文件,然后会让你新建用户。此时不要新建,直接`Ctrl+C`打断。随后从`cmd`运行`bash`,就以`root`权限进入了Linux子系统。 下面做的事比较复杂: ### 安装基础设施 >从开始菜单打开 Ubuntu。从[清华的ArchLinux镜像](https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/) 下载 Arch bootstrap .tar.gz 放在root用户的目录LocalState\rootfs\root下,然后解压【注:解压archlinux-bootstrap时在root目录,外面可能会出问题】: > $ tar -zxvf archlinux-bootstrap-2017.11.01-x86_64.tar.gz 注释:必须在Linux里面解压,不能在win中解压完了拖进去,权限会有问题。 >在 ~/root.x86_64/etc/pacman.d/mirrorlist 文件中,选择需要的服务器,取消注释。这一步直接换成Manjaro的 清华镜像: > Server = https://mirrors.tuna.tsinghua.edu.cn/manjaro/stable/$repo/$arch 注释:我觉得中科大的镜像更快 > 让 WSL 自动生成 /etc/resolv.conf 【注:或者 直接删除 /etc/resolv.conf文件】: >$ echo "# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line." > ~/root.x86_64/etc/resolv.conf > 退出所有打开的 Bash 命令行窗口。在 Windows 资源管理器中打开 %localappdata%\Packages,并找到 CanonicalGroupLimited.UbuntuonWindows_* (其中, * 表示随机字符串 )。 > 在 %localappdata%\Packages\CanonicalGroupLimited.UbuntuonWindows_*\LocalState\rootfs 中删除 bin, etc, lib, lib64, sbin, usr and var。然后从rootfs\root\root.x86_64移动(不要复制)相同的文件到 rootfs。 至此,之前安装的`Ubuntu`被替换为一个尚未安装完毕的`Arch`,且软件源被指向了`Manjaro`的软件仓库。 此时,“[WSL使用小结:从ArchLinux到Manjaro](https://www.cnblogs.com/wurui1994/p/7839777.html)”一文提到需要执行`pacman -Syu`升级当前软件,但实际上如此执行会报`key`错误,原因是当前安装的文件都是`Arch`的,但软件仓库中下载的包都是`Manjaro`签名的,不是一个系统。为此,首先尝试安装`manjaro-keyring`软件包: pacman -S manjaro-keyring 不出意外会报错,并询问你是否要删除已下载的文件。选择否,然后从本地强制安装此包: pacman -U /pat/to/manjaro-keyring/package 安装过程中应该会自动进行各种`key`的初始化,之后就可以`pacman -Syu`,如果还是不行,执行以下命令初始化刚刚安装的`key`: pacman-key --init pacman-key --populate archlinux manjaro 出错的话都有提示,仔细阅读按提示执行就好。 `Arch Wiki`中也有对于在WSL中安装`Arch`的描述,其中提到需要安装`fakeroot-tcp`和`glibc-wsl`。目前,`glibc-wsl`的问题已经被微软官方解决。`fakeroot-tcp`貌似主要是`yaourt`在用,不急安装。 一切搞定之后,`pacman -Syu`更新软件。更新可能覆盖之前的软件源设置,检查一下,否则后面又跑到国外下载软件去了。 ### 安装Manjaro 原作者提供了[一份好几百行的文件](https://github.com/wurui1994/MiscRecord/blob/master/Shell/WSL_ARCH/packages.txt),包含了`Manjaro`官方镜像所具有的包。实际上这些包很多有相互依赖关系,装一个就是全家桶。并且有一些是WSL中明显用不到的,所以我只挑选了一些看起来有用的,其他的用到时再装也不迟。我的初始安装只有下面两个组: pacman -S base-devel pacman -S xfce4 `pacman`会自动把依赖们装上,也有大几百兆,耐心。随后参考原文设置语言环境,设置`export DISPLAY=:0`等。 ### 默认用户调整 一切装完之后,需要首先新建一个常规用户,然后在WSL外面使用`ubuntu config --default-user username`命令设置新的默认用户。奇怪的是这一命令并不会当场生效,据我观察需要重启才行。这一命令对应的注册表是`计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{4xxxx2-2e4c-4b3b-9b40-1xxxxxx}\DefaultUid`,记录默认用户的`Linux User ID`。 ### 图形环境 图形环境由[VcXsrv](https://sourceforge.net/projects/vcxsrv/)呈现,这一点网上教程很多,不再详述,先把运行起来把GUI显示出来,后面还要改。 不用原文的`MobaXtem`原因是,经我测试,目前(2018年8月30日),对于高分屏,仅有`VcXsrv`可以可靠支持,这还是在修改了`VcXsrv`可执行文件的高DPI行为之后。其他包括`MobaXtem`、`XManager`在内都是模糊的,调不过来。 ### ssh服务 网上教程,包括本文的主参考文献,多是使用`export DISPLAY=:0`在本地运行图形服务,但我发现使用`ssh`服务,**远程登陆到本地WSL内执行图形任务**可能体验更好一些,原因包括: + 可以在使用`VcXsrv`的前提下实现双击打开Linux桌面 + 既然要用`Visual GDB`,后台总是要跑一个`ssh`服务的,空闲时又不占资源 + `ssh`服务可以[使用VBS脚本做到后台开机自启](https://www.jianshu.com/p/d8874d5a3027),很省心 这一阶段任务比较杂,仅写下要点: + 安装`openssh`包 + 最好使用使用`/usr/sbin/sshd -D`启动`ssh`服务 + 新建一个`VBS`文件丢到启动目录或者新建计划任务,开机执行`C:\Windows\System32\bash.exe -c 'sudo /usr/sbin/sshd -D'` + `ssh`最好设置成使用私钥登陆 + 使用`sudoer机制`实现`sudo /usr/sbin/sshd -D`的无密码执行。为防止手滑作死,其他命令最好还是要输密码才能执行,具体配置如下: root ALL=(ALL) ALL xxxx ALL=(ALL) ALL xxxx ALL=(root) NOPASSWD: /usr/sbin/sshd ### 双击进入图形界面 至此,应该有了一个开机自启、可以通过私钥登陆的`ssh`服务。使用`VcXsrv`的“启动远程程序来启动GUI”功能,可以配置出来一个双击启动即可登陆到`ssh`并启动`startxfce4`: 启动`VcXsrv`的`Xlaunch`,窗口设置无所谓,建议用无边框最大化窗口,`Display number`就留着默认自动选择,下一项选择`start a program`,再然后选择远程程序,用户名密码密钥什么的按需填写,启动的程序写`LANG=zh-CN.UTF-8;LC_ALL=zh_CN.UTF-8 /usr/sbin/startxfce4`,以保证仍然是中文环境。后面的选项基本无所谓,最后一步选择将配置保存到`xlaunch`文件。该文件可以用记事本打开编辑。举例如下: 双击此文件,即可打开一个`Xfce`工作环境,爽! 使用要点: + 要退出时,用`Xfce`的注销功能,然后关闭`VcXsrv`窗口 + 避免同时多个实例启动`Xfce`界面 ## 后期使用 ### 关于`yaourt`/`AUR`的使用 记得必须找到预编译的`fakeroot-tcp`手动安装进去。 ### 关于Visual Studio Code 使用`yaourt`安装过了,结论是基于此程序在图形界面响应速度上比原生程序(例如Qt程序)慢了一个数量级,怀疑是`Electron`底层作怪,无法解决,弃用,也没心情去尝试`Atom`会不会好一点了——印象中`Atom`本来就相对慢一些。 基础不牢,地动山摇。 ### 关于Qt的问题 刚装好时,一些依赖Qt的程序安装正常,但可能会无法打开。从命令行运行可以发现,这些程序报错的位置是统一的: ``` xxx程序xxx: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory ``` 这个错误出现了原因是WSL中的一个底层实现有问题,详细讨论可以关注下面这个链接: ``` https://superuser.com/questions/1347723/arch-on-wsl-libqt5core-so-5-not-found-despite-being-installed https://github.com/Microsoft/WSL/issues/3023 ``` 修正则比较简单: ``` sudo strip --remove-section=.note.ABI-tag /usr/lib64/libQt5Core.so.5 ``` ### 一个杯具 折腾`ssh`服务,一个很重要的原因(还好不是全部原因)是想用`Visual GDB`,折腾完了之后我发现,新版的`Visual GDB`已经专门提供了利用WSL编译的功能…… 不过`ssh`服务对于编程仍然是有意义的——貌似直接用WSL的话,`Visual GDB`中的程序只能以调试模式运行,不能直接运行. ### 使用Windows浏览器 浏览器这玩意儿相对于编辑器,反应速度更重要。恰好WSL具有一项神奇的能力:在Linux系统下可以直接调用Windows程序,并且可以正常传递命令行和标准输入输出。 [WSL(windows subsytem linux)下添加网络浏览器支持](https://www.smslit.top/2017/09/02/wsl-webbrowser/)一文利用此特性在`WSL/Ubuntu`下实现了从Linux的`jupyter`开启Windows下的Chrome浏览器。但`Xfce`的设置是不同的。 在`Xfce`下,浏览器需要通过`gio mime`命令或者`设置管理器-首选应用程序`来设置。同时,这套机制处理不了带空格的路径,加转义符也不行,所以首先需要做一个软连接把`Chrome`的可执行文件引入到`home`路径里面来(相当于把空格交给底层去处理): ➜ ~ ln -s /mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe winBrowser 然后在`设置管理器-首选应用程序`,将默认浏览器指向`/home/xxx/winBrowser`,系统会自动加上一个`%s`参数。这时再启动`jupyter`一类的东西,Windows下的`Chrome`浏览器就会自己弹出来。 ### 关于输入法 搜狗Linux输入法已经支持账户同步了,业界良心! 要安装它,首先需要安装`fcitx-im`软件组,记住要全部安装。然后从`yaourt`安装`fcitx-sogoupinyin`,然后修改上面的`XLaunch`文件,在远程命令里面多加入几个环境变量: ``` LANG=zh-CN.UTF-8 LC_ALL=zh_CN.UTF-8 XMODIFIERS=@im=fcitx GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx /usr/sbin/startxfce4 1 ``` 注销再登陆,应该没有问题了。有问题的话运行`fcitx-diagnose`仔细看报告,常见问题都能找出来。