daisukeの技術ブログ

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

QEMUをソースからビルドして動かす

前回は、QEMU のビルドに必要な xpm について学びました。

今回は、QEMU をビルドしていきます。途中でエラーが出ますが、そこを解決していきたいと思います。

それでは、やっていきます。

参考文献

はじめに

「QEMUを動かす」の記事一覧です。良かったら参考にしてください。

QEMUを動かすの記事一覧

QEMUをソースからビルド

QEMU をソースからビルドしていきます。以下のページに従って進めます。

github.com

xPack QEMU Arm のプロジェクトをクローンします。

$ rm -rf ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
git clone https://github.com/xpack-dev-tools/qemu-arm-xpack.git \
  ~/Work/xpack-dev-tools/qemu-arm-xpack.git

Cloning into '/home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git'...
remote: Enumerating objects: 2951, done.
remote: Counting objects: 100% (352/352), done.
remote: Compressing objects: 100% (122/122), done.
remote: Total 2951 (delta 233), reused 344 (delta 225), pack-reused 2599
Receiving objects: 100% (2951/2951), 628.10 KiB | 4.30 MiB/s, done.
Resolving deltas: 100% (2046/2046), done.

共通のヘルパーソースをクローンします。

$ rm -rf ~/Work/xpack-dev-tools/xbb-helper-xpack.git && \
mkdir -p ~/Work/xpack-dev-tools && \
git clone \
  --branch xpack-develop \
  https://github.com/xpack-dev-tools/xbb-helper-xpack.git \
  ~/Work/xpack-dev-tools/xbb-helper-xpack.git && \
xpm link -C ~/Work/xpack-dev-tools/xbb-helper-xpack.git

Cloning into '/home/daisuke/Work/xpack-dev-tools/xbb-helper-xpack.git'...
remote: Enumerating objects: 9991, done.
remote: Counting objects: 100% (9991/9991), done.
remote: Compressing objects: 100% (2509/2509), done.
remote: Total 9991 (delta 7533), reused 9904 (delta 7449), pack-reused 0
Receiving objects: 100% (9991/9991), 2.28 MiB | 3.70 MiB/s, done.
Resolving deltas: 100% (7533/7533), done.
@xpack-dev-tools/xbb-helper -> '/home/daisuke/Work/xpack-dev-tools/xbb-helper-xpack.git'

次はビルドです。長い時間がかかります。私の環境では、45分ぐらいかかりました。ディスクの容量も、一時的に 10GB ぐらいは準備していた方がいいと思います。

あと、git コマンドの -C オプションは、cd しなくても任意のリポジトリを操作できるオプションです。

$ rm -f ~/Work/xpack-dev-tools/qemu-arm-xpack.git/package-lock.json && \
git -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git pull && \
xpm run install -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
git -C ~/Work/xpack-dev-tools/xbb-helper-xpack.git pull && \
xpm link -C ~/Work/xpack-dev-tools/xbb-helper-xpack.git && \
xpm run link-deps -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
\
xpm run deep-clean --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
xpm run docker-prepare --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
xpm run docker-link-deps --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git && \
xpm run docker-build-develop --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git

(ログは省略)
Library ncursesw found: NO
Library cursesw found: NO

../../../sources/qemu-8.2.2.git/meson.build:1222:6: ERROR: Problem encountered: curses library not found

A full log can be found at /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/x86_64-pc-linux-gnu/build/qemu-8.2.2/meson-logs/meson-log.txt

ERROR: meson setup failed

エラーが発生しました。

QEMUのビルドエラー対策

QEMUのビルドのエラー解析

ncursesw と cursesw と curses が無いと言われているようです。

Docker のコンテナ上でビルドされてるはずなので、ローカルに不足のパッケージをインストールしても解決しないと思います。

qemu-arm-xpack.git の package.json を見てみます。ちょっと長いので、前回(QEMUのビルドに必要なxpm(xPack Project Manager)について学ぶ - daisukeの技術ブログ)見たように、"xpack" の "properties" と "actions" から見ていきます。

実行している "actions" は、"deep-clean"、"docker-prepare"、"docker-link-deps"、"docker-build-develop" の4つです。

  • "deep-clean":一時ファイルを全て削除しているようです
  • "docker-prepare":たくさんコマンドが発行されていて、Docker コンテナの作成と環境構築してそうです
  • "docker-link-deps":xpm のリンクを実行してそうです
  • "docker-build-develop":xpm のビルドを実行してそうです
{
  "xpack": {
    "properties": {
      "appName": "QEMU Arm",
      "appLcName": "qemu-arm",
      "platforms": "linux-x64,linux-arm64,linux-arm,darwin-x64,darwin-arm64,win32-x64",
      "LIQUIDJS": "liquidjs --context '{ \"XBB_APPLICATION_NAME\": \"{{ properties.appName }}\", \"XBB_APPLICATION_LOWER_CASE_NAME\": \"{{ properties.appLcName }}\", \"platforms\": \"{{ properties.platforms }}\" }'",
      "buildFolderRelativePath": "{{ 'build' | path_join: configuration.name | to_filename | downcase }}",
      "buildFolderRelativePathPosix": "{{ 'build' | path_posix_join: configuration.name | downcase }}",
      "commandBashBuild": "bash {{ properties.dbg }} scripts/build.sh --target {{ configuration.name }} --build-folder {{ properties.buildFolderRelativePathPosix }}",
      "xpm-version": "0.18.0",
      "xpm-install-loglevel": "trace",
      "dbg": ""
    },
    "actions": {
      "npm-install": "npm install",
      "npm-pack": "npm pack",
      "npm-version-patch": "npm version patch",
      "npm-version-minor": "npm version minor",
      "deep-clean": [
        "rm -rf build xpacks node_modules package-lock.json",
        "rm -rf ${HOME}/Work/xpack-dev-tools-build/{{ properties.appLcName }}-[0-9]*-*"
      ],
      "install": [
        "npm install",
        "xpm install"
      ],
      "link-deps": [
        "xpm link @xpack-dev-tools/xbb-helper"
      ],
      "git-pull-helper": [
        "git -C ${HOME}/Work/xpack-dev-tools/xbb-helper-xpack.git pull"
      ],
      "git-log": "git log --pretty='%cd * %h %s' --date=short",
      "generate-workflows": [
        "mkdir -p .github/workflows/",
        "cp xpacks/@xpack-dev-tools/xbb-helper/templates/body-github-pre-releases-test.md .github/workflows/",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-liquid.yml > .github/workflows/build-all.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-xbbli-liquid.yml > .github/workflows/build-xbbli.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-xbbla32-liquid.yml > .github/workflows/build-xbbla32.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-xbbla-liquid.yml > .github/workflows/build-xbbla.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-xbbmi-liquid.yml > .github/workflows/build-xbbmi.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/build-xbbma-liquid.yml > .github/workflows/build-xbbma.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/test-prime-liquid.yml > .github/workflows/test-prime.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/test-docker-linux-intel-liquid.yml > .github/workflows/test-docker-linux-intel.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/test-docker-linux-arm-liquid.yml > .github/workflows/test-docker-linux-arm.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/publish-release-liquid.yml > .github/workflows/publish-release.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/test-xpm-liquid.yml  > .github/workflows/test-xpm.yml",
        "{{ properties.LIQUIDJS }} --template @xpacks/@xpack-dev-tools/xbb-helper/templates/deep-clean-liquid.yml  > .github/workflows/deep-clean.yml",
        "cp xpacks/@xpack-dev-tools/xbb-helper/templates/dot.gitignore .gitignore",
        "cp xpacks/@xpack-dev-tools/xbb-helper/templates/dot.npmignore .npmignore",
        "cp xpacks/@xpack-dev-tools/xbb-helper/templates/build.sh scripts/",
        "cp xpacks/@xpack-dev-tools/xbb-helper/templates/test.sh scripts/"
      ],
      "trigger-workflow-build-all": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-build-xbbmi": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --machine xbbmi --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-build-xbbma": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --machine xbbma --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-build-xbbli": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --machine xbbli --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-build-xbbla": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --machine xbbla --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-build-xbbla32": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-build.sh --machine xbbla32 --xpm-version {{ properties.xpm-version }} --loglevel {{ properties.xpm-install-loglevel }}",
      "trigger-workflow-test-prime": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-test-prime.sh",
      "trigger-workflow-test-docker-linux-intel": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-test-docker-linux-intel.sh",
      "trigger-workflow-test-docker-linux-arm": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-test-docker-linux-arm.sh",
      "trigger-travis-macos": "bash xpacks/@xpack-dev-tools/xbb-helper/travis/trigger-travis-macos.sh",
      "trigger-workflow-publish-release": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-publish-release.sh",
      "generate-jekyll-post": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/generate-jekyll-post.sh",
      "update-package-binaries": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/update-package-binaries.sh",
      "trigger-workflow-test-xpm": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-test-xpm.sh",
      "trigger-workflow-deep-clean": "bash xpacks/@xpack-dev-tools/xbb-helper/github-actions/trigger-workflow-deep-clean.sh",
      "test-native": "bash {{ properties.dbg }} scripts/test.sh",
      "test-pre-release": "bash {{ properties.dbg }} scripts/test.sh --base-url pre-release --develop --cache",
      "test-xpm": "bash {{ properties.dbg }} scripts/test.sh --xpm",
      "build-native": "bash {{ properties.dbg }} scripts/build.sh",
      "build-native-develop": "bash {{ properties.dbg }} scripts/build.sh --develop",
      "build-native-develop-debug": "bash {{ properties.dbg }} scripts/build.sh --develop --debug",
      "build-native-win": "bash {{ properties.dbg }} scripts/build.sh --windows",
      "build-native-win-develop": "bash {{ properties.dbg }} scripts/build.sh --develop --windows"
    },
    "buildConfigurations": {
      "common-docker": {
        "actions": {
          "docker-prepare": [
            "mkdir -pv ${HOME}/Work/xpack-dev-tools/xbb-helper-xpack.git",
            "mkdir -pv ${HOME}/.local/xPacks ${HOME}/.cache/xPacks ${HOME}/Work/cache",
            "mkdir -pv ${HOME}/.wine",
            "docker rm --force {{ properties.containerName }}",
            "docker create --name {{ properties.containerName }} --tty --hostname docker --volume $(pwd):$(pwd) --volume ${HOME}/Work/xpack-dev-tools/xbb-helper-xpack.git:${HOME}/Work/xpack-dev-tools/xbb-helper-xpack.git --volume ${HOME}/.cache/xPacks:${HOME}/.cache/xPacks --volume ${HOME}/Work/cache:${HOME}/Work/cache --volume ${HOME}/.wine:${HOME}/.wine --workdir $(pwd) {{ properties.dockerImage }}",
            "docker start {{ properties.containerName }}",
            "docker exec {{ properties.containerName }} {{ properties.force32 }} npm install --location=global xpm@{{ properties.xpm-version }}",
            "docker exec {{ properties.containerName }} {{ properties.force32 }} userdel node",
            "docker exec {{ properties.containerName }} {{ properties.force32 }} groupadd --gid $(id -g) --force $(id -gn)",
            "docker exec {{ properties.containerName }} {{ properties.force32 }} useradd --home-dir ${HOME} --uid $(id -u) --gid $(id -g) $(id -un) --create-home",
            "docker exec {{ properties.containerName }} {{ properties.force32 }} chown --recursive $(id -u):$(id -g) ${HOME}",
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} bash -c 'lsb_release -sd && whoami && pwd && ls -lLA && ls -l ${HOME}'",
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm install",
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm install --config {{ configuration.name }}"
          ],
          "docker-link-deps": [
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm link -C ${HOME}/Work/xpack-dev-tools/xbb-helper-xpack.git",
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm run link-deps"
          ],
          "docker-build": [
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm run build --config {{ configuration.name }}"
          ],
          "docker-build-develop": [
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm run build-develop --config {{ configuration.name }}"
          ],
          "docker-build-develop-debug": [
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm run build-develop-debug --config {{ configuration.name }}"
          ],
          "docker-build-develop-tests-only": [
            "docker exec --user $(id -un) {{ properties.containerName }} {{ properties.force32 }} xpm run build-develop-tests-only --config {{ configuration.name }}"
          ],
          "docker-remove": [
            "docker stop {{ properties.containerName }}",
            "docker rm {{ properties.containerName }}"
          ]
        }
      },
    }
  },
}

QEMUのビルドの間違ったエラー対策

この方法では、エラーは対策できません。一応、内容を残しておきます。

docker exec で、Dockerコンテナ上に、不足しているパッケージをインストールすれば、先に進みそうです。

$ docker exec qemu-arm-8.2.2-1.1-linux-x64  apt install -y libncurses5-dev
$ docker exec qemu-arm-8.2.2-1.1-linux-x64  apt install -y libncursesw5-dev

先に進みましたが、また、エラーが出ました。

$ xpm run docker-build-develop --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git

(ログは省略)
processing libdl.so.2 of /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/application/libexec/libncursesw.so.5.9
libdl.so.2 is allowed sys so

processing libtinfo.so.5 of /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/application/libexec/libncursesw.so.5.9
>>> "/home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/application/libexec/libncursesw.so.5.9" has no rpath, patchelf may damage it!
rpath /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/x86_64-pc-linux-gnu/install/lib
patch_linux_elf_add_rpath: /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/application/libexec/libncursesw.so.5.9 has no rpath!

よく分かりませんが、追加で入れたはずの「libncursesw.so.5.9」が良くないようです。

QEMUのビルドのエラー解析のやり直し

ビルドログをよく見ると、ncurses-6.4.tar.gz を使って、libncurses.so.6.4、libncurses++.so.6.4 を作っていました。

分かりませんが、バージョンが古いことが原因かもしれません。

もしくは、何らかの理由で、libncursesw.so.6.4、libncurses++w.so.6.4 が生成できていないことが原因かもしれません。

QEMUのビルドのエラー対策

~/Work/cache に、ncurses-6.4.tar.gz が保存されているので、これをビルドして、libncursesw.so.6.4、libncurses++w.so.6.4 を作り、手動で、インストールしようと考えました。

以下の記事を参考にすれば、これらを作ることが出来そうです。

stackoverflow.com

$ mkdir ~/Work/ncurses
$ cp ~/Work/cache/ncurses-6.4.tar.gz ~/Work/ncurses/
$ cd ~/Work/ncurses/
$ tar zxvf ncurses-6.4.tar.gz
$ cd ncurses-6.4/
$ ./configure  --enable-widec --with-shared  --with-cxx-shared
$ make
$ ls lib/
libformw.a       libmenuw.a       libncurses++w.a       libncursesw.a       libpanelw.a
libformw.so      libmenuw.so      libncurses++w.so      libncursesw.so      libpanelw.so
libformw.so.6    libmenuw.so.6    libncurses++w.so.6    libncursesw.so.6    libpanelw.so.6
libformw.so.6.4  libmenuw.so.6.4  libncurses++w.so.6.4  libncursesw.so.6.4  libpanelw.so.6.4
libformw_g.a     libmenuw_g.a     libncurses++w_g.a     libncursesw_g.a     libpanelw_g.a

無事に、不足していたライブラリを作ることが出来ました。

これを、全て、インストールディレクトリにコピーします。

$ cp lib/* ~/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/x86_64-pc-linux-gnu/install/lib/

では、再度ビルドします。

$ xpm run docker-build-develop --config linux-x64 -C ~/Work/xpack-dev-tools/qemu-arm-xpack.git

package.json xpack.bin definitions:
      "qemu-system-aarch64": "./.content/bin/qemu-system-aarch64",
      "qemu-system-arm": "./.content/bin/qemu-system-arm",
      "qemu-system-gnuarmeclipse": "./.content/bin/qemu-system-gnuarmeclipse",

[ls -l /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/deploy]
total 38408
-rw-r--r-- 1 daisuke daisuke 39325691 May 19 11:59 xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
-rw-r--r-- 1 daisuke daisuke      106 May 19 11:59 xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz.sha

The xPack QEMU Arm (qemu-arm) project - linux-x64
Script "scripts/build.sh" completed at Sun May 19 11:59:45 UTC 2024
Duration: 10 minutes

Make the build folder writable by all...

[chmod -R a+w /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build]

Make the xpacks folder writable by all...

[find /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/xpacks -type d -exec chmod a+w {} ;]

ビルドできたようです。さらっと書いてますが、解決するまで、5、6時間はかかりました(笑)。

では、ビルドした QEMU で、動かしていきたいと思います。

ソースは変えてないので、挙動は変わらないはずです。

ソースからビルドしたQEMUで動かす

ビルドが完了したログに、ビルドした QEMU を圧縮した xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz のパスが書かれています。

そこで解凍します。

$ cd /home/daisuke/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/deploy
$ tar zxvf xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
$ ls xpack-qemu-arm-8.2.2-1/bin/
qemu-system-aarch64  qemu-system-arm  qemu-system-gnuarmeclipse

ちゃんと、QEMU が入っていました。

では、QEMU を動かしていきます。

$ cd ~/eclipse-workspace/stm32f4discovery_sample/Debug/
$ ~/Work/xpack-dev-tools/qemu-arm-xpack.git/build/linux-x64/deploy/xpack-qemu-arm-8.2.2-1/bin/qemu-system-gnuarmeclipse -S --nographic --verbose --board STM32F4-Discovery --mcu STM32F407VG --image stm32f4discovery_sample_bin2elf_entry.elf --gdb tcp::1234 -d unimp,guest_errors --semihosting-config enable=on,target=native --semihosting-cmdline stm32f4discovery_sample

GDB も動かします。

$ cd eclipse-workspace/stm32f4discovery_sample/Debug/
$ ~/Downloads/xpack-arm-none-eabi-gcc-13.2.1-1.1/bin/arm-none-eabi-gdb stm32f4discovery_sample_bin2elf_entry.elf
(gdb) target remote :1234

無事に動きました。

ソースからビルドしたQEMUで動かすことが出来た
ソースからビルドしたQEMUで動かすことが出来た

おわりに

今回は、だいぶ苦労して、QEMU のビルドが出来ました。

次回は、QEMU のソースコードを変更、ビルドして、QEMU の動きを変えてみたいと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。