Open5

Alpine LinuxでMingw32-w64のクロスコンパイル環境を作ってWindows版qemuをビルドしたい

okuokuokuoku

MSYS2環境でtarget tripleとかを見て、それをコピーすれば一撃なんではないか。

okuokuokuoku

安直に mingw-w64-gcc

/ # apk add mingw-w64-gcc
(1/12) Installing zstd-libs (1.5.6-r2)
(2/12) Installing mingw-w64-binutils (2.43-r0)
(3/12) Installing mingw-w64-crt (12.0.0-r0)
(4/12) Installing mingw-w64-headers (12.0.0-r0)
(5/12) Installing mingw-w64-winpthreads (12.0.0-r0)
(6/12) Installing libgcc (14.2.0-r4)
(7/12) Installing gmp (6.3.0-r2)
(8/12) Installing isl26 (0.26-r1)
(9/12) Installing mpfr4 (4.2.1-r0)
(10/12) Installing mpc1 (1.3.1-r1)
(11/12) Installing libstdc++ (14.2.0-r4)
(12/12) Installing mingw-w64-gcc (14.2.0-r1)
Executing busybox-1.37.0-r9.trigger
OK: 487 MiB in 27 packages

パッケージにはgccとしか書いてないけど、G++も入るようだ。

/ # x86_64-w64-mingw32-g++ -v
Using built-in specs.
COLLECT_GCC=x86_64-w64-mingw32-g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-w64-mingw32/14.2.0/lto-wrapper
Target: x86_64-w64-mingw32
Configured with: /home/buildozer/aports/community/mingw-w64-gcc/src/gcc-14.2.0/configure --prefix=/usr --target=x86_64-w64-mingw32 --libexecdir=/usr/libexec --disable-dw2-exceptions --disable-multilib --disable-nls --disable-sjlj-exceptions --disable-werror --enable-checking=release --enable-cloog-backend=isl --enable-fully-dynamic-string --enable-languages=c,lto,c++ --enable-libgomp --enable-libstdcxx-time=yes --enable-lto --enable-shared --enable-static --enable-threads=posix --with-bugurl=https://gitlab.alpinelinux.org/alpine/aports/-/issues --with-system-zlib
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (GCC)
okuokuokuoku

UCRTにコンパイルする

--help=target によると、

  -mcrtdll=                   Preprocess, compile or link with specified C
                              RunTime DLL library.

がある。確かに、 -dumpspecs を見ると:

%{mcrtdll=ucrt*:-D_UCRT}

よって、 -mcrtdll=ucrt を付けて、

x86_64-w64-mingw32-gcc -static -mcrtdll=ucrt hello.c

で良さそう。

okuokuokuoku

Meson

これは難敵だな。。

srcs/deps/glib/meson.build:1:0: ERROR: Executables created by c compiler x86_64-w64-mingw32-gcc are not runnable.

CC のような環境変数で渡すだけではダメで、cross-fileを書かないといけない。

https://mesonbuild.com/Cross-compilation.html

Pkg-config binary missing from cross or native file, or env var undefined.
Default target is not allowed for cross use
Found pkg-config: NO
Dependency lookup for glib-2.0 with method 'pkgconfig' failed: Pkg-config for machine host machine not found. Giving up.
CMake binary for host machine is not cached
CMake binary missing from cross or native file, or env var undefined.
Default target is not allowed for cross use
Found CMake: NO
Dependency lookup for glib-2.0 with method 'cmake' failed: CMake binary for machine host machine not found. Giving up.

いやまぁpkgconfigがダメなのはわかるけどCMakeは別にcrossで使ってもよくない。。?

cross-file の [binaries] セクションに pkgconfig が必要。

[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
windres = 'x86_64-w64-mingw32-windres'
strip = 'x86_64-w64-mingw32-strip'
pkgconfig = 'pkg-config'
okuokuokuoku

qemu

pkg-config を使わせるには環境変数 PKG_CONFIG で指定する必要がある。

../../srcs/qemu/target/hexagon/meson.build:29:16: ERROR: No build machine compiler for 'target/hexagon/gen_semantics.c'

host-ccが要るのか。。 gccmusl-dev をインストールした。

HAVE_al8 が立たない

In file included from ../../srcs/qemu/accel/tcg/cputlb.c:20:
In function 'load_atomic8',
    inlined from 'load_atom_extract_al8x2' at ../../srcs/qemu/accel/tcg/ldst_atomicity.c.inc:256:9,
    inlined from 'load_atom_8' at ../../srcs/qemu/accel/tcg/ldst_atomicity.c.inc:511:16,
    inlined from 'do_ld_8' at ../../srcs/qemu/accel/tcg/cputlb.c:2307:15:
/srcs/qemu/include/qemu/osdep.h:261:35: error: call to 'qemu_build_not_reached_always' declared with attribute error: code path is reachable
  261 | #define qemu_build_not_reached()  qemu_build_not_reached_always()
      |                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/srcs/qemu/include/qemu/osdep.h:272:50: note: in expansion of macro 'qemu_build_not_reached'
  272 | #define qemu_build_assert(test)  while (!(test)) qemu_build_not_reached()
      |                                                  ^~~~~~~~~~~~~~~~~~~~~~
../../srcs/qemu/accel/tcg/ldst_atomicity.c.inc:136:5: note: in expansion of macro 'qemu_build_assert'
  136 |     qemu_build_assert(HAVE_al8);
      |     ^~~~~~~~~~~~~~~~~
ninja: subcommand failed

Compile testに -liconv で軒並み失敗している。。

/objs/qemu # cat config-meson.cross
# Automatically generated by configure - do not modify
[properties]
[built-in options]
c_args = ['-mcrtdll=ucrt','-DLIBSLIRP_STATIC','-mcrtdll=ucrt']
cpp_args = ['-mcrtdll=ucrt','-DLIBSLIRP_STATIC','-mcrtdll=ucrt']
objc_args = ['-DLIBSLIRP_STATIC','-mcrtdll=ucrt']
c_link_args = ['-mcrtdll=ucrt','-DLIBSLIRP_STATIC','-mcrtdll=ucrt','-liconv','-mcrtdll=ucrt']
cpp_link_args = ['-mcrtdll=ucrt','-DLIBSLIRP_STATIC','-mcrtdll=ucrt','-liconv','-mcrtdll=ucrt']

もともとはMSYS2のために入れている(MSYS2では iconv が標準提供)けど、それが何か不味いことになってそうだな。

https://zenn.dev/link/comments/6ea77fc621e9fd

MSYS2側のglibのビルドがわるい。そっちを直すことにして一旦 -liconv を外す。ここまででビルドできた。

https://github.com/okuoku/qemubuild/commit/a7036bd8cb0e7edf1b4146c2a9436027eea45e0d