The emulator's control channel was the only thing pulling grpc-swift
in, and with it swift-nio-ssl, which does not build on Windows at all
-- it has no branch for the platform and its PosixPort reaches for
mlock, lstat and readlink. Nothing here wants TLS: the endpoint is
plaintext on the loopback, and only seven calls are ever made.
So the wire is spoken directly. GRPCConnection opens one HTTP/2
stream per call over swift-nio-http2 and frames length-prefixed
protobuf into it; EmulatorControlClient names the seven. That drops
grpc-swift-2, grpc-swift-nio-transport, grpc-swift-protobuf and
swift-nio-ssl from the graph, along with 7840 lines of generated
service stubs. The generated messages stay.
The rest is what running it on Windows turned up:
- AVD discovery split on "\n" and trimmed only .whitespaces, so
every name kept a trailing \r and every AVD was dropped.
- An AVD config spells its paths with backslashes, which URL keeps
as ordinary characters rather than separators.
- emulator and adb want .exe, and the SDK sits under LOCALAPPDATA.
- Port reservation and process lookup move into HostPort and
HostProcessLookup, which QemuMachine's two copies also wanted.
- The launcher re-execs into QEMU there, so the discovery ini is
named after that process; the one naming this launch's debug port
is taken when the launcher's own is absent.
Frames still arrive through a mapping rather than the socket:
CreateFileMapping backs the same file:// handle the emulator is
handed elsewhere.
A guest without vsock is refused outright on Windows, where the
virtio-serial fallback would ask QEMU for a QMP UNIX socket and be
told "unix sockets are not available on windows".
LUMA_EMULATOR_DISPLAY_ONLY drives launch, control and streaming
without a guest agent. Against a Pixel_2 AVD it reports a 1080x1920
first frame and nine more in three seconds.
The emulators were downloaded from a qemu-<build> release built in
MSYS2 against MinGW's GLib and pixman, so the installer carried
those beside the vcpkg ones the app links: two copies of GLib and
friends.
Build them in the Windows job instead, against the vcpkg prefix,
cached like the other dependencies on the QEMU version and the
build script. QEMU builds under MinGW and nowhere else on Windows,
but UCRT64 and CLANGARM64 sit on the same C runtime as the MSVC
DLLs they now link, so a descriptor means the same on both sides.
The x86_64 environment moves from MINGW64 for that reason.
The emulators live a directory below the app, where nothing looks
for its GLib on its own, so they are started with the installation
root on PATH.
Windows drops out of the QEMU workflow, which macOS still uses.
Extract with shortcuts, since the tarball's dangling symlinks defeat
MSYS2's habit of copying what one points at, and install base-devel
for the make and diff that meson and the build itself want.
Build the arm64 flavour on an arm64 runner under CLANGARM64, name the
archive after the arch -- the MSYS2 runtime is x86_64 whatever it
builds for -- and stage it into that installer too.
Unpack the published archive beside the LumaCore bundle, where the
app already looks, and sign every emulator for the hardened runtime;
TCG needs the JIT entitlements.
Name the build once now that more than Windows uses it, and keep a
checksum per platform.
frida-swift to 141d200c, which carries FridaCore 17.18.0. frida-core
to 0602e5dc and radare2 to 84e28a44 for the Windows and Linux builds.
GRDB 7.11.1, swift-asn1 1.7.2, Sparkle 2.9.6.
frida-swift resolves the main context off a worker thread, a halted
guest can be let go, and a script that errors or overflows its stack
no longer takes the guest down. Fetch the matching barebone agents
from the 17.17.1-barebone lineage.
Fetch the qemu-<build> archive our workflow publishes instead of
unpacking the upstream installer, dropping the 7-Zip requirement and
the list of graphics libraries that only existed to leave that
installer's cruft behind. The checksum pin moves to the new archive;
fill it in from the release notes once qemu-11.1.0-luma.1 has built.
Nothing packages a QEMU to build against, so the official build is
taken as it comes, pinned by date and by hash. Upstream publishes no
checksum, so the hash is of the bytes this was verified with.
Its installer wants administrator rights, which this script does not
ask for, so 7-Zip unpacks it instead. A QEMU built without the D-Bus
display cannot draw a guest, and is refused here rather than at boot.
Bootstrap provisions Frida, radare2 and the Pharo VM at their pinned
revisions and skips what is present, so a re-run resumes. The Windows
CI job drives it a component at a time. Build from a plain shell via
vcvars, and order the prefixes so a stale Frida cannot win the load.