前回は、QEMU のビルドに必要な xpm について学びました。
今回は、QEMU をビルドしていきます。途中でエラーが出ますが、そこを解決していきたいと思います。
それでは、やっていきます。
参考文献
はじめに
「QEMUを動かす」の記事一覧です。良かったら参考にしてください。
・第2回:STM32(ARM Cortex-M)をQEMUで動かす(ソースコード確認編)
・第3回:STM32(ARM Cortex-M)をQEMUで動かす(スタートアップルーチン編)
・第4回:STM32(ARM Cortex-M)をQEMUで動かす(リンカスクリプト編)
・第5回:STM32(ARM Cortex-M)のELFファイルの内容を確認する
・第6回:STM32(ARM Cortex-M)のELFファイル→バイナリ、バイナリ→ELFファイルに変換する
・第7回:STM32(ARM Cortex-M)のバイナリから構築したELFファイルをQEMUで動かす
・第8回:QEMUのビルドに必要なxpm(xPack Project Manager)について学ぶ
・第9回:QEMUをソースからビルドして動かす ← 今回 ・第10回:QEMUのソースコードを変更してSTM32の動作を変える
QEMUをソースからビルド
QEMU をソースからビルドしていきます。以下のページに従って進めます。
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 を作り、手動で、インストールしようと考えました。
以下の記事を参考にすれば、これらを作ることが出来そうです。
$ 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 の動きを変えてみたいと思います。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。