WSL2でGUIアプリを動かす

2020年8月3日コンピューターLinux,Ubuntu,Windows,WSL

Windows 10のWSL2(Windows Subsystem for Linux)にインストールしたUbuntu 20.04で、GUIアプリが動くように環境を構築してみます。

大まかな手順としては、「Windows側にXサーバーをインストール」→「WSL2のUbuntuにGUI関連ソフトをインストール」→「UbuntuにDISPLAY環境変数を設定して、Windows側Xサーバーに出力させる」という感じです。

この記事では、後述の参考サイト[1]を参考にして設定を行いました。参考サイトではWSL2にUbuntu 18.04をインストールして設定していますが、Ubuntu 20.04でも全く同じ方法で設定できました。

Windows 10へのWSL2のインストールは別の記事にまとめています。この記事が終わった状態からGUI環境を構築します。

Windows側にXサーバーをインストール

WSL2上のUbuntuでGUIアプリを動かしますが、その画面表示やマウス入力は、Windows側にインストールしたXサーバーを経由して行います。

Windows用のXサーバーアプリとして、VcXsrvをインストールします。

上のサイトからVcXsrvのインストーラーをダウンロードして実行します。インストールの設定はそのままで大丈夫だと思いますが、私はデスクトップのショートカットはオフにしました。

インストールが終わったら、スタートメニューからXLaunchを開きます。ここで、VcXsrvの起動オプションを設定します。起動オプションですが、Display numberは後ほど指定する必要がありますので、自動(-1)ではなく明示的に「0」にしておきます。また、Additional parameters for VcXsrvに「-ac」を指定します。この追加パラメーター「-ac」は、localhostで接続を受ける場合は不要らしいですが、WSL2は違うIPでネットワークにつながっていて別端末扱いのため、必要になるらしいです。

2020/08/03追記:GTKアプリを動かそうと思ったところ、警告が出てしまいました。調べたところ、追加パラメーターに「-nowgl」を追加すれば良いそうです。ということで、私は追加パラメーターに「-ac -nowgl」を指定しています。

起動すると、Windowsのファイアウォールから警告があります。WSL2は、通常の物理イーサネットとは別のIPアドレス範囲でWindows側とつながっていますので、「パブリックネットワーク」にもチェックを入れてアクセスを許可します。(WSL用の仮想イーサネットがパブリックネットワーク扱いになっているのだと思います)

タスクバーにVcXsrvのアイコンが表示されたら完了です。アイコンにマウスを乗せると、「PC名:0.0」などと表示されます。このうち、「0.0」の部分は後の設定で必要ですので、覚えておきます。

WSL2 UbuntuでのGUIアプリを常用するなら、VcXsrvの設定を保存しておいて(Save configurationボタンで保存できます)、そのファイルをスタートアップに登録すると便利だと思います。ちなみに、スタートアップフォルダはWin+Rからshell:startupで開けますので、このフォルダにconfig.xlaunchファイルを保存すればOKです。

Ubuntu側にGUIアプリをインストール

Windows側の用意が済んだら、次にWSL2上のUbuntu側でもGUIアプリを動かすための準備をします。

コマンドプロンプトやPowerShellからwslコマンドを実行して、Ubuntuを起動します。

PS C:\> wsl

bashのプロンプトが表示されたら、GUI関連のソフトをインストールします。参考サイト1によると、最低限sudo apt install libgl1-mesa-dev xorg-devをインストールすれば良いそうです。依存アプリも一緒にインストールするよう表示されますので、yを入力して進めます。

username@host:/mnt/c$ sudo apt install libgl1-mesa-dev xorg-dev
[sudo] password for username:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libdmx-dev libdmx1 libdrm-dev libegl-dev libegl-mesa0 libegl1 libfontconfig1-dev libfontenc-dev libfreetype-dev
  libfreetype6-dev libfs-dev libfs6 libgbm1 libgl-dev libgles-dev libgles1 libgles2 libglvnd-dev libglx-dev libice-dev
  libopengl-dev libopengl0 libpciaccess-dev libpixman-1-0 libpixman-1-dev libpng-dev libpng-tools
  libpthread-stubs0-dev libsm-dev libwayland-server0 libx11-dev libxau-dev libxaw7-dev libxcb-xfixes0 libxcb1-dev
  libxcomposite-dev libxcursor-dev libxcursor1 libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxfont-dev
  libxfont2 libxft-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmu-headers libxmuu-dev libxpm-dev
  libxrandr-dev libxrender-dev libxres-dev libxres1 libxss-dev libxss1 libxt-dev libxtst-dev libxv-dev libxvmc-dev
  libxvmc1 libxxf86dga-dev libxxf86vm-dev mesa-common-dev pkg-config uuid-dev x11proto-core-dev x11proto-dev
  x11proto-input-dev x11proto-randr-dev x11proto-record-dev x11proto-scrnsaver-dev x11proto-xext-dev
  x11proto-xf86dga-dev x11proto-xf86vidmode-dev x11proto-xinerama-dev xorg-sgml-doctools xserver-xorg-dev xtrans-dev
Suggested packages:
  freetype2-doc libice-doc libsm-doc libx11-doc libxaw-doc libxcb-doc libxext-doc libxt-doc
The following NEW packages will be installed:
  libdmx-dev libdmx1 libdrm-dev libegl-dev libegl-mesa0 libegl1 libfontconfig1-dev libfontenc-dev libfreetype-dev
  libfreetype6-dev libfs-dev libfs6 libgbm1 libgl-dev libgl1-mesa-dev libgles-dev libgles1 libgles2 libglvnd-dev
  libglx-dev libice-dev libopengl-dev libopengl0 libpciaccess-dev libpixman-1-0 libpixman-1-dev libpng-dev
  libpng-tools libpthread-stubs0-dev libsm-dev libwayland-server0 libx11-dev libxau-dev libxaw7-dev libxcb-xfixes0
  libxcb1-dev libxcomposite-dev libxcursor-dev libxcursor1 libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev
  libxfont-dev libxfont2 libxft-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmu-headers libxmuu-dev
  libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxres1 libxss-dev libxss1 libxt-dev libxtst-dev libxv-dev
  libxvmc-dev libxvmc1 libxxf86dga-dev libxxf86vm-dev mesa-common-dev pkg-config uuid-dev x11proto-core-dev
  x11proto-dev x11proto-input-dev x11proto-randr-dev x11proto-record-dev x11proto-scrnsaver-dev x11proto-xext-dev
  x11proto-xf86dga-dev x11proto-xf86vidmode-dev x11proto-xinerama-dev xorg-dev xorg-sgml-doctools xserver-xorg-dev
  xtrans-dev
0 upgraded, 83 newly installed, 0 to remove and 0 not upgraded.
Need to get 6772 kB of archives.
After this operation, 29.6 MB of additional disk space will be used.
Do you want to continue? [Y/n]

続いて、.bashrcにDISPLAY環境変数を設定します。WSL2から見てlocalhostのXサーバーに接続する場合は「:0」だけで良いらしいですが、WSL2はWindowsとは別IPでLANにつながっていますので、WSL2から見たWindows側のIPアドレスを指定しなければいけません。

その上、WSL2を起動するたびにWindows側のIPアドレスが変わるらしいので、起動ごとに適切なIPアドレスを指定するようにします。

まず、.bashrcを開きます。nano ~/.bashrcを実行します。

username@host:/mnt/c$ nano ~/.bashrc

最終行に次の1行を書き足します。末尾の0.0は、VcXsrvアイコンにマウスを乗せたときの表示に合わせます。0.0でなければ、書き換えてください。

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0.0

良ければ、保存して閉じるため、Ctrl+X → y → Enterと入力します。

GUIアプリの起動を試してみる

上記で初期設定が済んだら、環境変数を反映するため一度Ubuntuのbashを閉じて、もう一度wslコマンドでUbuntuを起動します。

サンプルアプリをインストールするため、sudo apt install x11-appsを実行します。

username@host:/mnt/c$ sudo apt install x11-apps
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  xbitmaps
Suggested packages:
  mesa-utils
The following NEW packages will be installed:
  x11-apps xbitmaps
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 685 kB of archives.
After this operation, 2763 kB of additional disk space will be used.
Do you want to continue? [Y/n]

インストールが終わったら、xeyesを実行します。

username@host:/mnt/c$ xeyes

目玉が表示されたら完了です。

日本語フォントを扱えるようにする(2020/08/05追記)

このWSL2環境には英字フォントが6個しか入っていませんので、GUIで日本語を表示しようとすると文字化けしてしまいます。そのため、日本語GUIアプリを使いたい場合は、何らかの方法でWSL2環境に日本語フォントを追加する必要があります。

今回は、参考サイト[3]に従って、Windows側にインストールされているフォントをWSL2のUbuntu 20.04側でも使えるように設定してみたいと思います。

先に、デフォルトでWSL2に用意されているフォントを一覧表示してみます。

username@host:~$ fc-list
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book

この通り、6個しか入っていません。

WSL2のGUIアプリが使えるフォントの情報は、/etc/fonts/内にあります。このフォルダにlocal.confという名前のXMLファイルを作成して、Windows側のフォントフォルダも参照するように設定すればOKです。

sudo nano /etc/fonts/local.confで新規ファイルを作成します。

username@host:~$ sudo nano /etc/fonts/local.conf

nanoテキストエディターが開きますので、次の内容をコピペします。WindowsのCドライブは、WSL2上では/mnt/cにマウントされていますので、要はC:\Windows\Fontsフォルダを参照するように設定しています。

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <dir>/mnt/c/Windows/Fonts</dir>
</fontconfig>

Ctrl+X → y → Enterで、保存して閉じます。

これで設定完了です。もう一度、GUIアプリで扱えるフォント一覧を表示してみると、見覚えのあるフォントも含めてたくさん表示されるようになります。(ここでは一部抜粋して掲載しています)

username@host:~$ fc-list
/mnt/c/Windows/Fonts/NotoSerifHebrew-Bold.ttf: Noto Serif Hebrew:style=Bold
/mnt/c/Windows/Fonts/verdana.ttf: Verdana:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/mnt/c/Windows/Fonts/EmojiOneColor-SVGinOT.ttf: EmojiOne Color:style=Regular
/mnt/c/Windows/Fonts/msmincho.ttc: MS Mincho,MS 明朝:style=Regular,標準
/mnt/c/Windows/Fonts/msgothic.ttc: MS PGothic,MS Pゴシック:style=Regular,標準
/mnt/c/Windows/Fonts/meiryob.ttc: Meiryo,メイリオ:style=Bold,Negreta,tučné,fed,Fett,Έντονα,Negrita,Lihavoitu,Gras,Félkövér,Grassetto,ボールド,Vet,Halvfet,Pogrubiony,Negrito,Полужирный,Fet,Kalın,Krepko,Lodia
/mnt/c/Windows/Fonts/yuminl.ttf: Yu Mincho,游明朝,Yu Mincho Light,游明朝 Light:style=Light,Regular
/mnt/c/Windows/Fonts/YuGothM.ttc: Yu Gothic,游ゴシック,Yu Gothic Medium,游ゴシック Medium:style=Medium,Regular

これで、WSL2上のGUIアプリで日本語が扱えるようになりました。

参考サイト

参考サイト[1]

参考サイト[2]

参考サイト[3]