The Windows installer and the Flatpak carried no ONNX Runtime, so they ran every model on tract's one core; the Arch package left it to an optional dependency. Each now installs two builds under runtimes/ — Intel's OpenVINO build and the generic WebGPU one, both with the CPU provider — fetched by tools/fetch-bundled-runtimes.sh from PyPI wheels pinned by SHA-256, pruned to the native libraries (81 + 31 MB on Linux, 67 + 42 MB on Windows), licence texts beside them. darkroom-desktop searches runtimes/openvino and runtimes/webgpu under each place a package installs to; the engine opens all it finds and keeps the one that fits the GPU, so a CUDA or ROCm runtime installed beside them still wins on its vendor's card. On Windows the chosen runtime's directory goes on PATH, because Intel's build leaves OpenVINO's DLLs for the loader to find there. The Windows image gains unzip; the installer smoke test checks both runtimes landed.
111 lines
5.6 KiB
Docker
111 lines
5.6 KiB
Docker
# DarkRoom — reproducible Windows cross-build environment
|
|
#
|
|
# Everything docs/dev/windows.md §2 names: Rust with the GNU Windows target, the
|
|
# MinGW-w64 cross compiler it links with, NSIS to build the installer, and Wine
|
|
# to smoke-test the result. Both CI and local builds use this image, so "works
|
|
# on my machine" and "works in CI" are the same machine — the same argument
|
|
# docker/android makes, and the same shape.
|
|
#
|
|
# Build: docker build -t darkroom-windows:latest docker/windows
|
|
# Use: ./docker/windows/build.sh cargo build --release --target x86_64-pc-windows-gnu -p darkroom-desktop
|
|
|
|
# trixie rather than the Android image's bookworm, for Wine: rustc's std
|
|
# imports bcryptprimitives.dll for its random source, and bookworm's Wine 8.0
|
|
# does not have it, so the smoke test dies at load with c0000135 before a
|
|
# single instruction of the application runs. Wine 10 does. trixie also ships
|
|
# Node 20 itself, so the NodeSource step the Android image needs is not here.
|
|
FROM docker.io/library/debian:trixie-slim
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Versions — pinned deliberately, like the Android image.
|
|
# ---------------------------------------------------------------------------
|
|
ARG RUST_VERSION=1.92.0
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive \
|
|
CARGO_HOME=/opt/cargo \
|
|
RUSTUP_HOME=/opt/rustup \
|
|
PATH=/opt/cargo/bin:$PATH
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# System packages
|
|
# ---------------------------------------------------------------------------
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl git git-lfs \
|
|
# The bundled ONNX Runtime builds arrive as wheels, which are zips
|
|
# (tools/fetch-bundled-runtimes.sh).
|
|
unzip \
|
|
# A *host* C compiler as well as the cross one: build scripts and
|
|
# proc-macros are compiled for Linux and linked with `cc`, whatever
|
|
# the target. Without it the very first build script fails with
|
|
# "linker `cc` not found" before any Windows code is reached.
|
|
gcc libc6-dev \
|
|
# The cross compiler, binutils and the MinGW runtime headers/libs. This
|
|
# is the one C toolchain the target needs: bundled SQLite, ring's asm
|
|
# and anything else the cc crate builds for the target go through it.
|
|
gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64 \
|
|
# The installer compiler. A native Linux binary; NSIS has always built
|
|
# its installers on POSIX hosts.
|
|
nsis \
|
|
# Runs the .exe and the installer for the smoke tests (windows.md §6).
|
|
# Not needed to build anything. Both packages: `wine64` is the
|
|
# loader under /usr/lib/wine, `wine` is the wrapper on PATH.
|
|
wine wine64 \
|
|
# `file` reports PE32+; `xz-utils` because the mingw packages are
|
|
# compressed with it.
|
|
file xz-utils \
|
|
# Gitea runs JavaScript actions (checkout, cache) from inside the job
|
|
# container, and current actions want Node 20 or newer.
|
|
nodejs \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& node --version
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Rust + the Windows target
|
|
#
|
|
# The component list must be a superset of rust-toolchain.toml's, for the
|
|
# reason the Android Dockerfile gives: rustup reconciles that file on the
|
|
# first cargo invocation and downloads anything missing inside the job.
|
|
# ---------------------------------------------------------------------------
|
|
RUN curl -fsSL https://sh.rustup.rs | sh -s -- \
|
|
-y --no-modify-path --profile minimal --default-toolchain ${RUST_VERSION} \
|
|
&& rustup target add x86_64-pc-windows-gnu \
|
|
&& rustup component add rustfmt clippy rust-analyzer \
|
|
&& chmod -R a+rwX ${CARGO_HOME} ${RUSTUP_HOME}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Linker configuration
|
|
#
|
|
# Debian ships the cross compiler in two thread models and the bare name is an
|
|
# alternatives symlink. `-posix` is stated: it is the one whose libstdc++ and
|
|
# libwinpthread the Rust target's own MinGW pieces were built against, and
|
|
# picking the other produces link errors that read as if std were missing.
|
|
#
|
|
# The runtime is linked statically (docs/dev/windows.md §2) so the installer
|
|
# carries one file. `-static-libgcc` is all it takes: rustc's windows-gnu
|
|
# target links its own copy of winpthread in self-contained mode, so nothing
|
|
# imports libwinpthread-1.dll — the smoke test's objdump step is what checks
|
|
# that. The `--whole-archive -lwinpthread` incantation the spec first named is
|
|
# wrong here: it forces in unused winpthread objects whose kernel32 and
|
|
# msvcrt references come after those libraries on the link line, and the
|
|
# link fails on a hundred undefined `__imp_` symbols.
|
|
# ---------------------------------------------------------------------------
|
|
ENV CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc-posix \
|
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS="-C link-args=-static-libgcc -C link-args=-static-libstdc++" \
|
|
CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-posix \
|
|
CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++-posix \
|
|
AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-ar-posix \
|
|
WINDRES=x86_64-w64-mingw32-windres
|
|
|
|
# Wine writes its prefix under $HOME and refuses a directory it does not own.
|
|
# The caller passes --user, so nothing baked into the image can be owned by
|
|
# that user; build.sh bind-mounts a host directory here instead, which also
|
|
# keeps the prefix (and its slow first `wineboot`) across runs.
|
|
ENV HOME=/tmp/home \
|
|
WINEDEBUG=-all
|
|
|
|
VOLUME ["/opt/cargo/registry"]
|
|
|
|
WORKDIR /work
|
|
|
|
CMD ["/bin/bash"]
|