WSL2とDockerを用いた、Windows環境におけるYocto環境構築の入門

はじめに

元々Qiitaに記事を書いておりましたが、Noteに移行しました。
移行に伴い筆者環境で再度記事の手順で環境構築したところ、うまくいかなかったところがあったため、コード類は一部更新しております。

本記事読者のターゲット

Windows環境へのYoctoビルド環境構築を記事にしている方があまりいなかったため、最近構築したWSL2とDockerを用いたYocto@Windows環境の構築手順をまとめてみました。下記に該当する方向けの記事になります。

  • はじめてWindows環境でYoctoの開発環境を構築したい人

  • Yoctoをあまり理解していないため、Yocto環境をぐちゃぐちゃにしてもすぐに復元できる環境を構築したい人

  • VirtualBoxなどの仮想環境上でYocto環境を構築しているが、動きが遅く嫌気がさしている人

前提条件

動作環境はSurface Laptop3(OS:Windows11,CPU:Core i5-1035G7,RAM:16GB)です。

手順1: WSL2環境の導入

  • 成功ケース: wsl.exeを用いる方法
    現在はwsl.exeの実行だけでWSL/Linuxディストリビューションの導入まで自動でやってくれます。

    • 再起動後、管理者権限PowerShell上で`wsl --install`を実行し、完了後再起動

  • 失敗ケース: WindowsアップデートからWSL2環境をインストールする方法
    一応WSL2がうまく起動しなかった事例も下記に記載しておきます。

    1. コントロールパネル>プログラムと機能>Windowsの機能の有効または無効化`で下記を有効化

    • Linux用Windowsサブシステム

    • 仮想マシンプラットフォーム

    1. MS Storeで`WSL`で検索し、Ubuntu 20.04 LTSをインストール

    • インストール後、Ubuntuを実行してみると下記エラー

    • Power Shell上で`wsl --install -d Ubuntu-20.04`でインストールしてもエラー変化なし(インストール先のリポジトリが変わると思ったがMS Storeと同じリポジトリを参照している?)

     Installing, this may take a few minutes...WslRegisterDistribution failed with error: 0x800701bc
     Error: 0x800701bc WSL 2 ???????????? ?????????????????
     ????? https://aka.ms/wsl2kernel ?????????
     
     Press any key to continue...

手順2: WSL2の設定

  • ユーザディレクトリに.wslconfigを作成し、WSLの使用メモリ上限を設定

    • メモリ上限を抑えるとYoctoビルド時にメモリリークするため、多めに割り当てたほうが良いと思います。

    • ここでは2GB割り当てでメモリリークしていたため、8GBに設定

[wsl2]
 memory=8GB

手順3: Ubuntu@WSL2の起動とDocker環境の導入

  • WSLはPowerShell上で実行してもよいのですが、毎回コマンドを打ってUbuntuを実行するのは面倒なので、ここではWindows Terminalを用います。WindowsTerminalではタブのプルダウンリストからUbuntuを選択することで、Ubuntu@WSL2のターミナルが開きます。これ以降は通常のUbuntu操作と同様です。

その後は下記の流れでDockerをインストールしていきます。

  • まずはDockerパッケージをaptリポジトリに追加し、aptリポジトリを更新します。

sudo apt-get update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add 
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt-get update
  • Dockerの起動: sudo service docker start

  • Dockerの起動状態の確認(任意): sudo service docker state

手順4: Yoctoビルド環境用のDockerfileの作成

Yoctoの実行で必要なパッケージを入れたUbuntu18.04環境を構築します。
※ 2022年10月現在、Yocto公式ではUbuntuだと22.04までサポートとなっておりましたが、筆者環境ではビルドうまくいかないBSPがいくつかありました。Ubuntu 20.04 or 18.04のコンテナを立てるのが良いと思います。

  • まずDockerfileを下記のように作成します。

    • この時ポイント: Dockerの場合標準ではRootユーザのみの環境が生成されてしまうのですが、Yoctoは一般ユーザでないとビルド作業ができません。

    • そのため、Dockerfileの2-1 Create non-root user...下で通常ユーザの生成やsudoでのパスワード入力不要の処理を入れています。

FROM ubuntu:18.04

# 0. TimeZone Config
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 1. Install Required Packages

# 1-1. Reference Package
RUN apt-get update && \
  apt-get -y upgrade
RUN apt-get install -qy git mc tig tree
RUN apt-get install -qy sudo
RUN apt-get install -qy texinfo
RUN sudo apt-get install -qy gawk
RUN sudo apt-get install -qy wget
RUN sudo apt-get install -qy diffstat
RUN sudo apt-get install -qy unzip
RUN sudo apt-get install -qy locales
RUN sudo apt-get install -qy gcc-multilib
RUN sudo apt-get install -qy build-essential
RUN sudo apt-get install -qy chrpath
RUN sudo apt-get install -qy socat
RUN sudo apt-get install -qy libsdl1.2-dev
RUN sudo apt-get install -qy xterm
RUN sudo apt-get install -qy python-crypto
RUN sudo apt-get install -qy cpio
RUN sudo apt-get install -qy python
RUN sudo apt-get install -qy python3
RUN sudo apt-get install -qy python3-pip
RUN sudo apt-get install -qy python3-pexpect
RUN sudo apt-get install -qy python3-jinja2
RUN sudo apt-get install -qy pylint3
RUN sudo apt-get install -qy libegl1-mesa
RUN sudo apt-get install -qy xz-utils
RUN sudo apt-get install -qy debianutils
RUN sudo apt-get install -qy iputils-ping
RUN sudo apt-get install -qy libssl-dev
RUN sudo apt-get install -qy vim
RUN sudo apt-get install -qy file
RUN sudo apt-get install -qy git
RUN sudo apt-get install -qy git-core
RUN sudo apt-get install -qy rsync
RUN sudo apt-get install -qy quilt
RUN sudo apt-get install -qy curl
RUN sudo apt-get install -qy screen
RUN sudo apt-get install -qy libncurses5-dev
RUN sudo apt-get install -qy less
RUN sudo apt-get install -qy libxml-xpath-perl
# 1-2. Packages for QEMU Env on Docker
RUN sudo apt-get install -qy qemu-kvm
RUN sudo apt-get install -qy qemu-utils
RUN sudo apt-get install -qy bridge-utils
RUN sudo apt-get install -qy dnsmasq
RUN sudo apt-get install -qy uml-utilities
RUN sudo apt-get install -qy iptables
RUN sudo apt-get install -qy net-tools

# 2. Non-root User Setting 
# 2-1. Create non-root user that will perform the build of the images
RUN ln -sf /bin/bash /bin/sh
RUN useradd --shell /bin/bash build && mkdir -p /home/build && chown -R build /home/build
RUN usermod -G sudo build
RUN echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

# 2-2. Run as the following user
USER build
ENV HOME=/home/build
WORKDIR $HOME

# 3. UTF-8 Setting
RUN sudo locale-gen en_US.UTF-8
RUN sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
RUN export LANG=en_US.UTF-8

ENTRYPOINT ["/bin/bash"]

下記の流れでDockerイメージを実行します。実行後Docker環境のターミナルに自動で遷移します。間違えてDocker環境から出てしまった場合には、docker exec -it docker4yocto bashで入りなおしてください。

 cd <Dockerfileの保存先ディレクトリ>
 docker build . -t allegg/build-yocto
 docker run -itd -p 8081:8080 --mount type=bind,src=<Hostの共有ディレクトリの絶対パス>,dst=/home/build --name="container-yocto" allegg/build-yocto

YoctoでビルドしたイメージファイルをHost側で後から取り出せるように、--mountで共有ボリュームを設定しておきます。

手順5: Yocto環境の準備

それではYocto環境を準備していきます。今回は少し古いバージョンで申し訳ありませんが、Yocto(rocko)を試してみます。内容も豊富にGitの設定はここでは飛ばします。

  • まずはYocto標準環境を取得します。

git config --global user.name "ユーザ名"
git config --global user.email "***@gmail"
git init
git clone -b rocko git://git.yoctoproject.org/poky
cd poky && git pull --all -prune

これでYocto環境まで準備できましたので、いよいよLinuxディストリビューションのビルドです。今回は最も軽量な`core-image-minimal`をビルドしていきま。「bitbakeにはtime:ビルドにかかった時間の出力」と「-k:ビルド中にエラーが起きても止めずにエラー対象のレシピと依存関係のないレシピのビルドを進める」オプションを付けるのがおすすめです。自環境ではビルドに1.5h~2hくらいかかったので、何か別の作業をしながら待ちましょう。

# Setting Env for Bitbake
source ~/shared/poky/oe-init-build-env ~/build
# Bitbake (time: Show Buildtime after bitbake, -k: Non-Stop Build in case oferror)
time bitbake -k core-image-minimal

...need to be rerun and all succeeded.が出れば正常にビルド完了です!

付録1: 環境構築で苦戦したところ

bitbake時に下記のエラーが出て対応に苦戦しました。エラーは長いのでSummary周辺の出力です。ここだけ読むとbinutils-cross_<version>.bbのdo_compile(コンパイル処理)でエラーがでているように見えていたため、レシピ周りの修正をしまくっていました...

      ERROR: Task 377 (/home/build/shared/poky/meta/recipes-devtools/binutils/binutils-cross_2.25.1.bb, do_compile) failed with exit code '1'
      WARNING: Failed to fetch URL http://distfiles.gentoo.org/distfiles/v86d-0.1.10.tar.bz2, attempting MIRRORS if available
      WARNING: Failed to fetch URL ftp://ftp.debian.org/debian/pool/main/n/netbase/netbase_5.3.tar.xz, attempting MIRRORS if available
      NOTE: Tasks Summary: Attempted 1327 tasks of which 8 didn't need to be rerun and 1 failed.
      No currently running tasks (1327 of 2050)

      Summary: 1 task failed:
        /home/build/shared/poky/meta/recipes-devtools/binutils/binutils-cross_2.25.1.bb, do_compile

ただエラーを再度入念に読んだところ、コンパイル処理が途中で強制終了している文字が...メモリが足りず落とされていたみたいです。このエラーが出ている際は前述したように、.wslconfigやdockerへのメモリ割り当て数を修正したら直りました。

g++: internal compiler error: Killed (program cc1plus)

付録2: [Yocto初心者向け情報] Yoctoビルド後を少しだけ解説

Yocto初心者の方のために少しだけYoctoの解説をしておきます。pokyディレクトリ内は迷宮のようにフォルダが入り乱れておりますので、フォルダ構成に関して少しだけ記載いたします。

  • bitbakeでビルドしたファイル類(ログデータやパッケージ含め)はすべてpoky/build/tmp下にあります。bitbakeでビルドしたcore-image-minimalイメージはpoky/build/tmp/qemux86/に入っています。今回はqemu向けにビルドしたためありませんが、BSPを取り込んでビルドすると、ブートローダー(u-bootなど)やデバイスツリーもここに入ります。

  • ビルド中に行われた作業はすべてpoky/build/tmp/work下に入っています。例えば作成イメージに取り込んだパッケージ類やビルドログはここで確認できます。

今回の構築環境の課題

  1. WSL2のイメージファイル格納先を探します。自環境では、C:\Users<ユーザ名>\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx

  2. diskparkコンソール上で対象の仮想ドライブを選択し、空のディスク領域を解放します。

select vdisk file="C:\Users\<ユーザ名>\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"
attach vdisk readonly   
compact vdisk
detach vdisk
exit

これでディスク領域が解放されますが、docker rmする度に(あるいはROM容量が厳しくなった際にまとめて)この作業は面倒なのが現状の課題です。良い対策がございましたらコメントいただけると幸いです。

この記事が気に入ったらサポートをしてみませんか?