はじめに
Zynqで動作するボードでNervesを動作させるために、奮闘していた時に、Buildrootのエラーに遭遇しました。
結果的には、対象のパッケージのバグだったんですが、調査した過程を記事にしておきます。
類似した問題に遭遇した方に、参考になれば幸いです。
状況
次のような比較的平凡な、buildrootの設定でu-bootのをビルドしていました。
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="xilinx_zynq_virt"
# BR2_TARGET_UBOOT_FORMAT_BIN is not set
BR2_TARGET_UBOOT_FORMAT_REMAKE_ELF=y
BR2_TARGET_UBOOT_PATCH="${NERVES_DEFCONFIG_DIR}/u-boot"
以下のエラーが発生しました。
/usr/bin/ld: cannot find -luuid: No such file or directory
collect2: error: ld returned 1 exit status
make[3]: *** [scripts/Makefile.host:95: tools/mkeficapsule] Error 1
make[2]: *** [Makefile:1894: tools] Error 2
make[1]: *** [package/pkg-generic.mk:283: /home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.1/build/uboot-2022.04/.stamp_built] エラー 2
make: *** [Makefile:23: _all] エラー 2
調査
ビルド時のログを確認してみます。
make V=1
でビルドすると、詳細なログが出力されます。
$ make V=1
~~~省略~~~
/usr/bin/make -f ./scripts/Makefile.build obj=tools
./scripts/check-of.sh .config ./scripts/of_allowlist.txt
/usr/bin/gcc -O2 -isystem /home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host/include -Wp,-MD,tools/.mkeficapsule.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -DCONFIG_FIT_SIGNATURE -DCONFIG_FIT_SIGNATURE_MAX_SIZE=0xffffffff -DCONFIG_FIT_CIPHER -include ./include/compiler.h -idirafterinclude -idirafter./arch/arm/include -I./scripts/dtc/libfdt -I./tools -DUSE_HOSTCC -D__KERNEL_STRICT_NAMES -D_GNU_SOURCE -o tools/mkeficapsule tools/mkeficapsule.c -lgnutls -luuid
/usr/bin/ld: cannot find -luuid: No such file or directory
collect2: error: ld returned 1 exit status
make[3]: *** [scripts/Makefile.host:95: tools/mkeficapsule] Error 1
make[2]: *** [Makefile:1894: tools] Error 2
make[1]: *** [package/pkg-generic.mk:283: /home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/build/uboot-2022.04/.stamp_built] エラー 2
make: *** [Makefile:23: _all] エラー
このコマンドが何をしているか整理してみます。
今回のビルドでは、クロスコンパイルを行っていています。ホストはX86_64で、ターゲットはARMです。
実行されているのは、/usr/bin/gcc
です。
ホスト用のコンパイラーです。
u-bootのツールで、ホストで実行するツールをコンパイルしている時に発生したもになります。
gccの引数に-luuid
が指定されていますが、-Lオプションみあたりません。
-L
オプションでライブラリーのパスを指定していないため、ライブラリーが見つからないようです。
原因
いろいろ試行錯誤の末、原因は分かったんですが、
原因を先に書いてしまうと、u-bootのMakefileに不備があるため、ビルド時にエラーになっていました。
ビルド環境の問題かと思ったんですが、そうではなかったです。
ビルド対象のu-bootは、uboot-2022.04
で、少し古いバージョンだからなんですかね?
https://github.com/Xilinx/u-boot-xlnx.git
のxilinx-v2024.1
で試してみたところ、問題なくビルドできたことから、違いを調べてみて、この結論に至りました。
xilinx-v2024.1
のtools/Makefile
の-luuid
に関する記述を調べてみると、以下のようになっていました。
HOSTLDLIBS_mkeficapsule += \
$(shell pkg-config --libs uuid 2> /dev/null || echo "-luuid")
ライブラリの場所をpkg-configで調べて、追加するようになっています。uboot-2022.04
には、この記述がありませんでした。
生成されたオブジェクトがリンクしてるファイルを調べると、ちゃんとlibuuidが含まれてます
libuuid.so.1 => <~~省略~~>/host/lib/libuuid.so.1
$ cd <path to builroot>/build/uboot-xilinx-v2024.1/tools
$ ldd mkeficapsule
linux-vdso.so.1 (0x00007ffddf3dd000)
libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007fa0e9835000)
libuuid.so.1 => /home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host/lib/libuuid.so.1 (0x00007fa0e982c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa0e9603000)
libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007fa0e94c8000)
libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007fa0e94a7000)
libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007fa0e92fb000)
libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007fa0e92e3000)
libnettle.so.8 => /lib/x86_64-linux-gnu/libnettle.so.8 (0x00007fa0e929d000)
libhogweed.so.6 => /lib/x86_64-linux-gnu/libhogweed.so.6 (0x00007fa0e9255000)
libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fa0e91d3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa0e9a37000)
libffi.so.8 => /lib/x86_64-linux-gnu/libffi.so.8 (0x00007fa0e91c6000)
ホストビルド時に使われるライブラリ
ホストビルド時に使われるライブラリは、host/lib/pkgconfig
に記述されています。
uuidについては、uuid.pcに記述されています。
$ cat host/lib/pkgconfig/uuid.pc
prefix=/home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host
exec_prefix=/home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host
libdir=/home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host/lib
includedir=/home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host/include
Name: uuid
Description: Universally unique id library
Version: 2.39.1
Requires:
Cflags: -I${includedir}/uuid
Libs: -L${libdir} -luuid
たしかに/host/lib
が指定されています。
pkg-configの動作を確認しておきます。
$ export PKG_CONFIG_PATH=$(pwd)/host/lib/pkgconfig
$ pkg-config --libs uuid
-L/home/masa/nerves/nerves_system_zynq_ebaz4205/.nerves/artifacts/nerves_system_zynq_ebaz4205-portable-0.0.2/host/lib -luuid
-L<ライブラリの場所>
となっています。これでうまくビルドできています。
ターゲットビルド時に使われるライブラリ
PKG_CONFIG_PATH
を設定しないで、./host/bin/pkg-config
を実行すると、以下のように表示され、ターゲット用のライブラリーが表示されるようです。
$ unset PKG_CONFIG_PATH
$ ./host/bin/pkg-config --libs uuid
-L./host/bin/../arm-buildroot-linux-gnueabihf/sysroot/usr/lib -luuid
まとめ
- 今回のエラーは、ビルドに使った、u-bootのMakefileに不備があって、ビルド時にエラーになっていました。
- 修正されたu-bootでは、問題なくビルドでき、修正内容から、ライブラリーの場所を指定していることがわかりました。
- クロス開発環境では、ホスト用とターゲット用の環境が区別されているので、どちらの問題かを見極めることが重要です。