WSL2+Ubuntu 20.04でGUIアプリを動かす

2020年8月3日WSL 2Linux,Ubuntu,Windows,WSL2

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

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

事前準備:WindowsにWSL 2をインストール

Windows 10へのWSL2のインストールはこちらの記事にまとめています。まだWSL 2をインストールされていない方は、こちらの記事を参考にインストールしてください。

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

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

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

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

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

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

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

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

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

最終行に次の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

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

正しく「目玉」が表示されたら完了です!

日本語フォントを扱えるようにする

この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アプリで日本語が扱えるようになりました。

おすすめの記事

今回用意したGUIアプリ実行環境を使って、Google Chromeをインストールしてみました。

ここまでの情報だとChrome(やその他のGUIアプリ)上で日本語入力ができません。日本語入力もしたい場合は、こちらの記事をご覧ください。

また、コマンドライン・GUIアプリともに、WSL2上から音声を出すには追加で設定が必要です。音声を出す方法はこちらの記事にまとめました。

デスクトップ環境(Ubuntu Desktop)もインストールしてみました。

参考サイト

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

参考サイト[1]

参考サイト[2]

参考サイト[3]

記事の更新履歴

VcXsrvの追加パラメーター変更(2020/8/3)

VcXsrvの設定の「Additional parameters for VcXsrv」に「-nowgl」を追加しました。私の環境だと、一部のGTKアプリでエラーが出てきたので、対策として追加しています。

日本語フォントを呼び込む設定を追加(2020/8/5)

日本語フォントを表示できるように、UbuntuからWindows側のフォントフォルダを参照する設定を追記しました。

日本語フォントを追加しておかないと、アプリ中の日本語が文字化けします。

export文を.bashrcから.profileに移動(2020/8/14)

Bash環境変数のexport文を、.bashrcから.profileに移動しました。

UbuntuのBashを立ち上げていない状態でも、Windows上のコマンドプロンプトやショートカットからwsl.exe -d "Ubuntu-20.04" <Ubuntu上のコマンド>を実行すればUbuntu上のアプリが起動できます。例えば、Ubuntu 20.04にインストールしたGoogle Chromeを起動するなら、wsl.exe -d Ubuntu-20.04 bash -lc google-chromeというショートカットをつくっておけば、ダブルクリックで起動できます。

ただし、この起動方法だと.bashrcは読み込まれないため、.bashrcにexport DISPLAY文を入れていると「Xサーバーが見つからない」というエラーが出てしまいます。この対策として、export DISPLAY文を.profileに移しました。

Waylandが移植され、RDP経由で使えるようになるらしい (2020/9/30)

現在、WSL上のLinuxでGUIアプリを動かすには、本記事で説明したとおりXサーバーを動かしてそこに表示する、という方法をとらなければなりません。

それが下記の記事によると、将来的にはXサーバー不要でGUIアプリが動かせるようになるらしいです。技術的には、Waylandを移植してRDP経由でGUIアプリを表示するらしく、IDEやブラウザを動かすことも確認できているそうです。

2ヶ月以内くらいでベータ版が配信されるとのことなので、配信されたらWayland経由でのGUIアプリ表示もやってみたいと思います。

created by Rinker
SB Creative
¥2,970(2020/10/28 03:05:59時点 楽天市場調べ-詳細)
著者・三宅英明
Bashシェルスクリプトをイチから学べる本です。よく見かけるものの一見トリッキーな「ifの条件式にコマンドを書く」、「&&や||でコマンドをいくつか並べる」などの書き方も、一つ一つ細かく動きを解説していて分かりやすかったです。また、grep、sed、xargs、getoptなどの使い方や正規表現についても、詳細に説明があります。
網羅的に書かれており、辞書的に使えるおすすめの書籍です。