hiroの長い冒険日記

主にコンピュータ周辺の興味を持った内容を綴ります

【長文注意】qemu for windows を debian で cross build (通常編)

linuxSSD 120GB に入れた目的は、configure option を変更して qemu for windows を build する事である。

配布されている binary は whpx 無効となっているので、Hyper-V を活用した状態で qemu を使ってみたいと考えていた。先ずは、option を変更しない条件で binary が作成できるか試してみた。

https://qemu.weilnetz.de/doc/BUILD.txt

debootstrap 後に chroot するので、環境を汚さないのが良いね。この手順の通りにやってみた。

debootstrap

debootstrap が入っていなかったので入れてから amd64 の buster を入れた。de じゃなくて jp が良かったかも。

# apt install debootstrap
# debootstrap --arch=amd64 buster amd64/buster http://ftp.de.debian.org/debian
I: Retrieving InRelease 
I: Checking Release signature
... 略 ...
I: Configuring systemd...
I: Base system installed successfully.

chroot & mount proc, sys

amd64 以下で chroot して、/proc と /sys を mount した。

# chroot amd64/buster
# mount proc /proc -t proc
# mount sys /sys -t sysfs

chroot を抜ける前に両方とも umount しておく。再開する場合には、この項目のみ実施すれば良い。

Weil さんの apt line を使えるようにする

wget 等の install。途中で locale 絡みの warning が出ていたが最後まで終了した。

# apt-get install --no-install-recommends wget ca-certificates gnupg
Reading package lists... Done
Building dependency tree... Done
... 略 ...
Running hooks in /etc/ca-certificates/update.d...
done.

gpg key の入手と apt line を追加して update した。

# wget -O - https://qemu.weilnetz.de/debian/gpg.key | apt-key add -
--2019-02-14 10:04:53--  https://qemu.weilnetz.de/debian/gpg.key
... 略 ...
2019-02-14 10:04:54 (35.9 MB/s) - written to stdout [3614/3614]

OK
# echo deb https://qemu.weilnetz.de/debian/ testing contrib >/etc/apt/sources.list.d/cygwin.list
# apt update
Hit:1 http://ftp.de.debian.org/debian buster InRelease   
Get:2 http://ftp.de.debian.org/debian buster/main Translation-en [6008 kB]
Get:3 https://qemu.weilnetz.de/debian testing InRelease [3764 B]               
Get:4 https://qemu.weilnetz.de/debian testing/contrib all Packages [150 kB]
Fetched 6162 kB in 5s (1306 kB/s)                                        
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.

まだ de だった。jp に変更して再度 apt update を実施した。

参考にした Weil さんのサイトを紹介されている次のリンク先では、gpg の取り込みに失敗したと書かれていたが、今回は問題なく完了できた。
blog.kmckk.com

必要な software の install、source 入手

locale 絡みの error が出ないように LANG と LC_ALL を C にして、git が入っていなかったので追加で入れた。

それ以外は手順の通りに実行した。Optional となっている物も念の為入れておいた。以下、log は略。

# export LANG=C
# export LC_ALL=C
# apt-get install --no-install-recommends gcc libc6-dev make mingw-w64 mingw-w64-tools nsis python
# apt-get install --no-install-recommends texinfo
# apt-get install --no-install-recommends git
# git clone git://repo.or.cz/qemu/ar7.git /qemu
Cloning into '/qemu'...
remote: Counting objects: 440599, done.
remote: Compressing objects: 100% (109883/109883), done.
remote: Total 440599 (delta 363420), reused 400508 (delta 329584)
Receiving objects: 100% (440599/440599), 158.96 MiB | 5.60 MiB/s, done.
Resolving deltas: 100% (363420/363420), done.
# apt-get install --no-install-recommends mingw64-x86-64-curl
# apt-get install --no-install-recommends mingw64-x86-64-gnutls
# apt-get install --no-install-recommends mingw64-x86-64-gtk3 mingw64-x86-64-libxml2
# apt-get install --no-install-recommends mingw64-x86-64-ncurses mingw64-x86-64-sdl2
# apt-get install --no-install-recommends mingw64-x86-64-libusb1.0 mingw64-x86-64-usbredir
# apt-get install --no-install-recommends mingw64-x86-64-glib2.0 mingw64-x86-64-pixman
  • pts 絡みの error も出ていた。元環境の /dev/pts を mount した方が良い?
  • 既に install 済のものもあった。mingw64-x86-64-glib2.0 と mingw64-x86-64-pixman は実行しても install されず。

多少の引っかかりはあるが、ここまでの間で trouble はなかった。

普通に build

configure

まずは configure option 等は変更せずに、手順通りに実行してみた。

# mkdir -p /qemu/bin/ndebug/x86_64-w64-mingw32
# cd /qemu/bin/ndebug/x86_64-w64-mingw32
# ../../../configure --cross-prefix=x86_64-w64-mingw32- --disable-guest-agent-msi --disable-werror
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building
Please install dpkg-dev to use pkg-config when cross-building

ERROR: glib-2.40 gthread-2.0 is required to compile QEMU

ん? dpkg-dev が必要? glib-2.40 と gthread-2.0 が必要? dpkg-dev を入れても状況は変わらず。

Please install dpkg-dev ... の message を出しているのは、pkg-config の代わりに使用する x86_64-w64-mingw32-pkg-config の中。configure の中で pkg-config が呼ばれる度に Please ... と表示されているので、正常に機能していない。

/usr/bin/x86_64-w64-mingw32-pkg-config:

#! /bin/sh
# pkg-config wrapper for cross-building
# Sets pkg-config search path to search multiarch and historical cross-compiling paths.

# If the user has already set PKG_CONFIG_LIBDIR, believe it (even if empty): 
# it's documented to be an override
if [ x"${PKG_CONFIG_LIBDIR+set}" = x ]; then
  # GNU triplet for the compiler, e.g. i486-linux-gnu for Debian i386,
  # i686-linux-gnu for Ubuntu i386
  basename="$(basename "$0")"
  triplet="${basename%-pkg-config}"
  # Normalized multiarch path if any, e.g. i386-linux-gnu for i386
  multiarch="$(dpkg-architecture -t"${triplet}" -qDEB_HOST_MULTIARCH 2>/dev/null)"
  if [ "$?" != 0 ]; then
      echo "Please install dpkg-dev to use pkg-config when cross-building" >&2
      exit 1
  fi
... 略 ...
  export PKG_CONFIG_LIBDIR
fi

exec pkg-config "$@"

なるほど、PKG_CONFIG_LIBDIR を予め設定してやれば、自分で探さなくなるので configure は進むはず。

# PKG_CONFIG_LIBDIR=/usr/x86_64-w64-mingw32/lib/pkgconfig ../../../configure --cross-prefix=x86_64-w64-mingw32- --disable-guest-agent-msi --disable-werror
Install prefix    c:/Program Files/QEMU
BIOS directory    c:/Program Files/QEMU
firmware path     c:/Program Files/QEMU/share/qemu-firmware
binary directory  c:/Program Files/QEMU
library directory c:/Program Files/QEMU/lib
module directory  c:/Program Files/QEMU/lib
libexec directory c:/Program Files/QEMU/libexec
include directory c:/Program Files/QEMU/include
config directory  c:/Program Files/QEMU
local state directory   queried at runtime
Windows SDK       no
Source path       /qemu
GIT binary        git
GIT submodules    ui/keycodemapdb tests/fp/berkeley-testfloat-3 tests/fp/berkeley-softfloat-3 dtc capstone
C compiler        x86_64-w64-mingw32-gcc
Host C compiler   cc
C++ compiler      x86_64-w64-mingw32-g++
Objective-C compiler x86_64-w64-mingw32-gcc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt -DHAS_LIBSSH2_SFTP_FSYNC -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -mms-bitfields -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/glib-2.0 -I/usr/x86_64-w64-mingw32/sys-root/mingw/lib/glib-2.0/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -m64 -mcx16 -I$(SRC_PATH)/hosts/w32/include -mthreads -D_POSIX=1 -D__USE_MINGW_ANSI_STDIO=1 -DWIN32_LEAN_AND_MEAN -DWINVER=0x501 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wextra -Wno-error=parentheses -Wno-error=format-extra-args -Wno-error=format -Wno-override-init -Wno-sign-compare -Wno-missing-field-initializers -Wno-unused-parameter -Wstrict-prototypes -Wredundant-decls -Wmissing-format-attribute -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wexpansion-to-defined -Wendif-labels -Wno-shift-negative-value -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/p11-kit-1 -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/libpng16 -I/usr/x86_64-w64-mingw32/sys-root/mingw/include -I$(SRC_PATH)/capstone/include
LDFLAGS           -Wl,--nxcompat -Wl,--no-seh -Wl,--dynamicbase -Wl,--warn-common -m64 -g 
QEMU_LDFLAGS      -L$(BUILD_DIR)/dtc/libfdt 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       aarch64-softmmu alpha-softmmu arm-softmmu cris-softmmu hppa-softmmu i386-softmmu lm32-softmmu m68k-softmmu microblaze-softmmu microblazeel-softmmu mips-softmmu mips64-softmmu mips64el-softmmu mipsel-softmmu moxie-softmmu nios2-softmmu or1k-softmmu ppc-softmmu ppc64-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu sparc64-softmmu tricore-softmmu unicore32-softmmu x86_64-softmmu xtensa-softmmu xtensaeb-softmmu
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
SDL support       yes (2.0.7)
GTK support       yes (3.22.28)
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    yes
libgcrypt         no
nettle            yes (3.4)
libtasn1          yes
curses support    yes
virgl support     no 
curl support      yes
mingw32 support   yes
Audio drivers     dsound
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
Multipath support no
VNC support       yes
VNC SASL support  no
VNC JPEG support  yes
VNC PNG support   yes
xen support       no
brlapi support    no
bluez  support    no
Documentation     yes
Tools             qemu-ga qemu-img$(EXESUF) qemu-io$(EXESUF) qemu-edid$(EXESUF) 
PIE               no
vde support       no
netmap support    no
Linux AIO support no
(X)ATTR support   no
Install blobs     yes
KVM support       no
HAX support       yes
HVF support       no
WHPX support      no
TCG support       yes
TCG debug enabled no
TCG interpreter   no
malloc trim support no
RDMA support      no
PVRDMA support    no
fdt support       git
membarrier        no
preadv support    no
fdatasync         no
madvise           no
posix_madvise     no
posix_memalign    no
libcap-ng support no
vhost-net support no
vhost-crypto support no
vhost-scsi support no
vhost-vsock support no
vhost-user support no
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            yes
usb net redir     yes
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info yes
QGA MSI support   no
seccomp support   no
coroutine backend win32
coroutine pool    no
debug stack usage no
mutex debugging   no
crypto afalg      no
GlusterFS support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   yes
TPM passthrough   no
TPM emulator      no
QOM debugging     yes
Live block migration yes
lzo support       yes
snappy support    no
bzip2 support     yes
NUMA host support no
libxml2           yes
tcmalloc support  no
jemalloc support  no
avx2 optimization yes
replication support yes
VxHS block device no
bochs support     yes
cloop support     yes
dmg support       yes
qcow v1 support   yes
vdi support       yes
vvfat support     yes
qed support       yes
parallels support yes
sheepdog support  yes
capstone          git
docker            no
libpmem support   no
libudev           no

NOTE: cross-compilers enabled:  'x86_64-w64-mingw32-gcc'

うん、configure は通った。WHPX support は no のままだが、まずは進めてみよう。

make

CPU は 4 core なので -j4 で、stdout & stderr を log に残しながら make を実施した(昔からのやり方)。

# make -j4 2>&1 > ~/qemu_make.log &

... なんか warning が色々表示されながら進んでいる。stderr も記録しているのに、なんで画面表示が出るのだろうか... でも make は進む。別の端末の chroot の外で、

# watch tail -n 20 amd64/buster/root/qemu_make.log

で覗きながら進捗を確認した。
hiro20180901.hatenablog.com
こちらの記事で書いた中国の方の成功例だと、dtc と keycodemap を別に持ってくる必要があったらしいが、今回はすんなり通っていた。
log:

# grep -i system-x86_64 qemu_make.log 
  LINK    x86_64-softmmu/qemu-system-x86_64w.exe
  GEN     x86_64-softmmu/qemu-system-x86_64.exe

実行ファイルが無事に作成できた。

installer の作成

# cd /qemu/bin/ndebug/x86_64-w64-mingw32 && make installer INSTALLER=myinstaller.exe
 make[1]: flex: Command not found
make[1]: bison: Command not found
make[1]: flex: Command not found
make[2]: flex: Command not found
make[2]: bison: Command not found
make[2]: flex: Command not found
/bin/sh: 1: xgettext: not found
/bin/sh: 1: msgmerge: not found
make[2]: *** [Makefile:52: /qemu/po/bg.po] Error 127
make[1]: *** [Makefile:886: install] Error 2
make: *** [Makefile:1055: myinstaller.exe] Error 2

flex や bison は多分 cross な必要はないよね。msgmerge は gettext に入っている。もう少し。

# apt install flex
# apt install bison
# cd /qemu/bin/ndebug/x86_64-w64-mingw32 && make installer INSTALLER=myinstaller.exe
/bin/sh: 1: msgmerge: not found
make[2]: *** [Makefile:52: /qemu/po/bg.po] Error 127
make[1]: *** [Makefile:886: install] Error 2
make: *** [Makefile:1055: myinstaller.exe] Error 2
# apt install gettext
# cd /qemu/bin/ndebug/x86_64-w64-mingw32 && make installer INSTALLER=myinstaller.exe
File: "/usr/i686-w64-mingw32/sys-root/mingw/share/icons" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
   /oname=outfile one_file_only)
Error in script "/qemu/qemu.nsi" on line 180 -- aborting creation process
make: *** [Makefile:1057: myinstaller.exe] Error 1

qemu.nsi を見ると、W64 の分岐で i686-w64-mingw32 側を使う方に入っている。
qemu.nsi:

... 略 ...
Section "Desktop icons" SectionGnome
    SetOutPath "$INSTDIR\share"
!ifdef W64
    File /r /usr/x86_64-w64-mingw32/sys-root/mingw/share/icons
!else
    File /r /usr/i686-w64-mingw32/sys-root/mingw/share/icons
!endif
SectionEnd
... 略 ...

x86_64-w64-mingw32 で作っているのに、何故 i686-w64-mingw32 を読みに行くのだろう... W64 が true となるように Makefile を修正した。

# diff -u Makefile.old Makefile
--- Makefile.old	2019-02-16 05:46:34.306995785 +0000
+++ Makefile	2019-02-16 05:29:41.631405926 +0000
@@ -1050,6 +1050,7 @@
 installer: $(INSTALLER)
 
 INSTDIR=/tmp/qemu-nsis
+nsisflags += -DW64
 
 $(INSTALLER): $(SRC_PATH)/qemu.nsi
 	$(MAKE) install prefix=${INSTDIR}
# cd /qemu/bin/ndebug/x86_64-w64-mingw32 && make installer INSTALLER=myinstaller.exe
... 略 ...
makensis -V2 -NOCD -DW64 \
                -DCONFIG_DOCUMENTATION="y" \
                -DCONFIG_GTK="y" \
                -DBINDIR="/tmp/qemu-nsis" \
                 \
                -DSRCDIR="/qemu" \
                -DOUTFILE="myinstaller.exe" \
                -DDISPLAYVERSION="3.1.0" \
                /qemu/qemu.nsi
rm -r /tmp/qemu-nsis
# ls -l myinstaller.exe
-rw-r--r-- 1 root root 80986968 Feb 16 05:33 myinstaller.exe

出来た。

結果

多少の引っかかりはあったものの、configure option を変更しない状態で、installer まで作成する事が出来た。次は、作成した myinstaller.exe が正常に動作するかどうかを確認してみる。