WSL+Manjaro+Xfce打造完美开发环境
目标
- 基于WSL,运行具有图形界面的Linux程序
- 使用Manjaro避开Ubuntu等WSL发行版大版本升级容易产生的问题
- 使用
ssh
和Visual GDB
,在Linux环编译境下用Visual Studio开发C++程序——有Linux上编译环境的省心,又可以利用Visual Studio这一宇宙第一IDE进行大型项目开发。
安装
安装的过程主要参考了WSL使用小结:从ArchLinux到Manjaro,但这篇文章还是有一些点没有讲到,这里补充一下。
首先,去控制面板开启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”一文提到需要执行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
原作者提供了一份好几百行的文件,包含了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呈现,这一点网上教程很多,不再详述,先把运行起来把GUI显示出来,后面还要改。
不用原文的MobaXtem
原因是,经我测试,目前(2018年8月30日),对于高分屏,仅有VcXsrv
可以可靠支持,这还是在修改了VcXsrv
可执行文件的高DPI行为之后。其他包括MobaXtem
、XManager
在内都是模糊的,调不过来。
ssh服务
网上教程,包括本文的主参考文献,多是使用export DISPLAY=:0
在本地运行图形服务,但我发现使用ssh
服务,远程登陆到本地WSL内执行图形任务可能体验更好一些,原因包括:
- 可以在使用
VcXsrv
的前提下实现双击打开Linux桌面 - 既然要用
Visual GDB
,后台总是要跑一个ssh
服务的,空闲时又不占资源 ssh
服务可以使用VBS脚本做到后台开机自启,很省心
这一阶段任务比较杂,仅写下要点:
- 安装
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
文件。该文件可以用记事本打开编辑。举例如下:
<?xml version="1.0" encoding="UTF-8"?> <XLaunch WindowMode="Nodecoration" ClientMode="StartProgram" LocalClient="False" Display="-1" LocalProgram="xcalc" RemoteProgram="LANG=zh-CN.UTF-8 LC_ALL=zh_CN.UTF-8 /usr/sbin/startxfce4 1>/dev/null 2>/dev/null" RemotePassword="" PrivateKey="C:\Users\metor\.ssh\PuTTY.ppk" RemoteHost="127.0.0.1" RemoteUser="metorm" XDMCPHost="" XDMCPBroadcast="False" XDMCPIndirect="False" Clipboard="True" ClipboardPrimary="True" ExtraParams="" Wgl="True" DisableAC="False" XDMCPTerminate="False"/>
双击此文件,即可打开一个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)下添加网络浏览器支持一文利用此特性在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
仔细看报告,常见问题都能找出来。