diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4d9b1a2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +** +!Dockerfile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f26a87f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,296 @@ +name: Build + +on: + workflow_dispatch: + +concurrency: + group: build + cancel-in-progress: false + +permissions: + contents: read + +env: + # Windows DriverVer requires four numeric components, so the required fourth + # component is fixed at zero. This exact value is used everywhere. + VERSION: 1.${{ vars.MAJOR }}.${{ vars.MINOR }}.0 + + # Only these two repositories float. Each run resolves master once and then + # passes the exact SHA to BuildKit as a named Git context. + D3D11_REPO: https://github.com/qemus/virtio-d3d11.git + KMD_REPO: https://github.com/qemus/virtio-drivers-windows.git + + # Everything below is pinned. + MESA_ARCHIVE_URL: https://gitlab.freedesktop.org/anonymix007/mesa/-/archive/venus-win32/mesa-venus-win32.tar.gz + MESA_TREE_SHA256: 9f216e64201e54408342a1757c1cd2e369b352a88ce96a05e8a4d7e91cad9690 + + MAKECAT_REF: ee7aa4dd1d10ad5f254020ca0637df5abcc95618 + CLANG_CL_LINUX_REF: 84e723d170e7611c55fff30c44d24c5a04bd4cb7 + + EWDK_VERSION: "26100.6584" + EWDK_URL: https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/EWDK_ge_release_svc_prod1_26100_250904-1728.iso + EWDK_SHA256: 9f48251dd24ad31aac206d8256e95bda5f90a9783982c45a8aafeb9054562379 + WINSDKVER: "10.0.26100.0" + VCTOOLSVER: "14.44.35207" + + RUST_TOOLCHAIN: nightly-2026-08-31 + CBINDGEN_VERSION: "0.29.4" + +jobs: + build: + name: Build + runs-on: ubuntu-24.04 + timeout-minutes: 240 + + steps: + - name: Checkout + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + + - name: Validate version + shell: bash + run: | + set -euo pipefail + + # Fail clearly if MAJOR/MINOR repository variables were not set. + test -n "${{ vars.MAJOR }}" + test -n "${{ vars.MINOR }}" + + [[ "${{ vars.MAJOR }}" =~ ^[0-9]+$ ]] + [[ "${{ vars.MINOR }}" =~ ^[0-9]+$ ]] + + # Microsoft requires every DriverVer component to be < 65535. + (( 10#${{ vars.MAJOR }} < 65535 )) + (( 10#${{ vars.MINOR }} < 65535 )) + + [[ "${VERSION}" =~ ^1\.[0-9]+\.[0-9]+\.0$ ]] + echo "Building driver/release version ${VERSION}" + + - name: Free runner disk space + shell: bash + run: | + set -euxo pipefail + + df -h / + + sudo rm -rf /usr/local/lib/android + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache + sudo docker system prune --all --force || true + sudo apt-get clean + + df -h / + + - name: Resolve floating qemus master commits + id: refs + shell: bash + run: | + set -euo pipefail + + d3d11_sha="$( + git ls-remote "${D3D11_REPO}" refs/heads/master | awk '{print $1}' + )" + kmd_sha="$( + git ls-remote "${KMD_REPO}" refs/heads/master | awk '{print $1}' + )" + + [[ "${d3d11_sha}" =~ ^[0-9a-f]{40}$ ]] + [[ "${kmd_sha}" =~ ^[0-9a-f]{40}$ ]] + + # Resolve the DXVK gitlink from the exact D3D11 commit without + # checking out the working tree. + tmp="$(mktemp -d)" + trap 'rm -rf "${tmp}"' EXIT + + git -C "${tmp}" init --quiet + git -C "${tmp}" remote add origin "${D3D11_REPO}" + git -C "${tmp}" fetch --quiet --depth=1 origin "${d3d11_sha}" + + fetched_sha="$(git -C "${tmp}" rev-parse FETCH_HEAD)" + test "${fetched_sha}" = "${d3d11_sha}" + + dxvk_sha="$( + git -C "${tmp}" ls-tree "${d3d11_sha}" thirdparty/dxvk \ + | awk '{print $3}' + )" + [[ "${dxvk_sha}" =~ ^[0-9a-f]{40}$ ]] + + echo "D3D11 master: ${d3d11_sha}" + echo "DXVK gitlink: ${dxvk_sha}" + echo "KMD master: ${kmd_sha}" + + { + echo "d3d11_sha=${d3d11_sha}" + echo "dxvk_sha=${dxvk_sha}" + echo "kmd_sha=${kmd_sha}" + } >> "${GITHUB_OUTPUT}" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f + + - name: Build package + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 + with: + context: . + file: ./Dockerfile + target: artifact + push: false + pull: false + provenance: false + + # The two current masters are resolved once above. Full 40-character + # commit fragments make each named context immutable for this run. + build-contexts: | + d3d11=${{ env.D3D11_REPO }}#${{ steps.refs.outputs.d3d11_sha }} + kmd=${{ env.KMD_REPO }}#${{ steps.refs.outputs.kmd_sha }} + + build-args: | + VERSION_ARG=${{ env.VERSION }} + + D3D11_SHA=${{ steps.refs.outputs.d3d11_sha }} + DXVK_SHA=${{ steps.refs.outputs.dxvk_sha }} + KMD_SHA=${{ steps.refs.outputs.kmd_sha }} + + MESA_ARCHIVE_URL=${{ env.MESA_ARCHIVE_URL }} + MESA_TREE_SHA256=${{ env.MESA_TREE_SHA256 }} + + MAKECAT_REF=${{ env.MAKECAT_REF }} + CLANG_CL_LINUX_REF=${{ env.CLANG_CL_LINUX_REF }} + + EWDK_VERSION=${{ env.EWDK_VERSION }} + EWDK_URL=${{ env.EWDK_URL }} + EWDK_SHA256=${{ env.EWDK_SHA256 }} + WINSDKVER=${{ env.WINSDKVER }} + VCTOOLSVER=${{ env.VCTOOLSVER }} + + RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} + CBINDGEN_VERSION=${{ env.CBINDGEN_VERSION }} + + outputs: type=local,dest=./out + + # qemus master changes invalidate only stages consuming their named + # contexts. Pinned Mesa/EWDK/toolchain stages remain reusable. + cache-from: type=gha,scope=qemus-virtio-gpu-x64 + cache-to: type=gha,mode=max,scope=qemus-virtio-gpu-x64,ignore-error=true + + - name: Verify exported package and version + shell: bash + run: | + set -euxo pipefail + + required=( + virtio_wddm_rs.inf + virtio_wddm_rs.cat + virtio_wddm_rs.sys + virtio_gpu_wddm_rs.pdb + dx11um_virtio.dll + dx11um_virtio.debug + vulkan_virtio.dll + vulkan_virtio.debug + virtio_icd.x86_64.json + virtio_test_signing.cer + BUILDINFO.txt + ) + + for file_name in "${required[@]}"; do + test -s "out/${file_name}" + done + + # The release version must literally equal the installed Windows + # DriverVer version, not merely resemble it. + driver_version="$( + sed -n 's/^DriverVer=[^,]*,[[:space:]]*//p' out/virtio_wddm_rs.inf + )" + test "${driver_version}" = "${VERSION}" + + grep -Fq "Driver / release version: ${VERSION}" out/BUILDINFO.txt + grep -Fq "${{ steps.refs.outputs.d3d11_sha }}" out/BUILDINFO.txt + grep -Fq "${{ steps.refs.outputs.dxvk_sha }}" out/BUILDINFO.txt + grep -Fq "${{ steps.refs.outputs.kmd_sha }}" out/BUILDINFO.txt + grep -Fq "${MESA_TREE_SHA256}" out/BUILDINFO.txt + + echo + echo "Driver version: ${driver_version}" + cat out/BUILDINFO.txt + echo + find out -maxdepth 1 -type f -printf '%f\n' | sort + + - name: Create release ZIP + shell: bash + run: | + set -euxo pipefail + + archive="virtio-gpu-${VERSION}.zip" + + python3 - "${archive}" <<'PY' + import sys + import zipfile + from pathlib import Path + + archive = Path(sys.argv[1]) + source = Path("out") + + with zipfile.ZipFile( + archive, + "w", + compression=zipfile.ZIP_DEFLATED, + compresslevel=9, + ) as zf: + for path in sorted(source.iterdir()): + if path.is_file(): + zf.write(path, path.name) + PY + + test -s "${archive}" + sha256sum "${archive}" + + - name: Upload Actions artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: virtio-gpu-${{ env.VERSION }} + path: | + out/ + virtio-gpu-${{ env.VERSION }}.zip + if-no-files-found: error + compression-level: 0 + retention-days: 30 + + - name: Create a release + uses: action-pack/github-release@d887b892618f95e19985108bfbc0c26833efa505 + with: + tag: "v${{ env.VERSION }}" + title: "v${{ env.VERSION }}" + token: ${{ secrets.REPO_ACCESS_TOKEN }} + + - name: Add package to release + env: + GH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} + shell: bash + run: | + set -euxo pipefail + gh release upload \ + "v${VERSION}" \ + "virtio-gpu-${VERSION}.zip" + + - name: Increment version variable + uses: action-pack/increment@1458c307cedd62641619be2480c6263cf39864ac + with: + name: 'MINOR' + token: ${{ secrets.REPO_ACCESS_TOKEN }} + + - name: Send mail + uses: action-pack/send-mail@33d560748d5c56be2a180c578ba4cf92b22a4723 + with: + to: ${{ secrets.MAILTO }} + from: Github Actions <${{ secrets.MAILTO }}> + connection_url: ${{ secrets.MAIL_CONNECTION }} + subject: Build of ${{ github.event.repository.name }} v${{ env.VERSION }} completed + body: | + The build job of ${{ github.event.repository.name }} v${{ env.VERSION }} was completed successfully! + + Driver version: ${{ env.VERSION }} + D3D11: ${{ steps.refs.outputs.d3d11_sha }} + KMD: ${{ steps.refs.outputs.kmd_sha }} + + See https://github.com/${{ github.repository }}/actions for more information. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a4be57e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,479 @@ +# syntax=docker/dockerfile:1.7 + +ARG UBUNTU_IMAGE=ubuntu:24.04@sha256:1e0a86e57d247923571b75e0aaf48a1449cf8c543d51fb3e07a4a7d7bfa79316 + +FROM ${UBUNTU_IMAGE} AS toolchain + +ARG DEBIAN_FRONTEND=noninteractive +ARG RUST_TOOLCHAIN=nightly-2026-08-31 +ARG CBINDGEN_VERSION=0.29.4 + +ENV RUSTUP_HOME=/opt/rustup +ENV CARGO_HOME=/opt/cargo +ENV PATH=/opt/cargo/bin:/opt/mingw-posix/bin:${PATH} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + aria2 \ + bison \ + build-essential \ + ca-certificates \ + clang \ + cmake \ + curl \ + file \ + flex \ + gettext \ + git \ + glslang-tools \ + jq \ + libclang-dev \ + libexpat1-dev \ + libwine-dev \ + lld \ + mingw-w64 \ + ninja-build \ + openssl \ + osslsigncode \ + p7zip-full \ + pkg-config \ + python3 \ + python3-dev \ + python3-venv \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +# Make the POSIX-threading MinGW compiler the unqualified x86_64-w64-mingw32 +# toolchain used by Mesa and virtio-d3d11. +RUN set -eux; \ + mkdir -p /opt/mingw-posix/bin; \ + ln -s "$(command -v x86_64-w64-mingw32-gcc-posix)" /opt/mingw-posix/bin/x86_64-w64-mingw32-gcc; \ + ln -s "$(command -v x86_64-w64-mingw32-g++-posix)" /opt/mingw-posix/bin/x86_64-w64-mingw32-g++; \ + for tool in ar gcc-ar ld objcopy ranlib strip windres; do \ + ln -s "$(command -v x86_64-w64-mingw32-${tool})" "/opt/mingw-posix/bin/x86_64-w64-mingw32-${tool}"; \ + done + +# Pin the Rust compiler date and cbindgen version. rustup itself is only the +# bootstrap mechanism; the installed compiler/toolchain is the dated nightly. +RUN curl --proto '=https' --tlsv1.2 --fail --location \ + https://sh.rustup.rs -o /tmp/rustup.sh \ + && sh /tmp/rustup.sh -y --no-modify-path --profile minimal --default-toolchain none \ + && rm /tmp/rustup.sh \ + && rustup toolchain install "${RUST_TOOLCHAIN}" --profile minimal --component rust-src \ + && rustup default "${RUST_TOOLCHAIN}" \ + && rustup target add x86_64-pc-windows-msvc --toolchain "${RUST_TOOLCHAIN}" \ + && cargo install cbindgen --version "${CBINDGEN_VERSION}" --locked \ + && rustc --version \ + && cargo --version \ + && cbindgen --version + +FROM toolchain AS ewdk + +ARG EWDK_VERSION=26100.6584 +ARG EWDK_URL +ARG EWDK_SHA256 +ARG VCTOOLSVER=14.44.35207 +ARG WINSDKVER=10.0.26100.0 +ARG CLANG_CL_LINUX_REF=84e723d170e7611c55fff30c44d24c5a04bd4cb7 + +# The 18.6 GB ISO only exists during this RUN. It is deleted before the layer +# is committed, so the cache stores the extracted toolchain subset, not the ISO. +RUN set -eux; \ + test -n "${EWDK_URL}"; \ + test -n "${EWDK_SHA256}"; \ + iso=/tmp/ewdk.iso; \ + aria2c \ + --continue=true \ + --max-connection-per-server=8 \ + --min-split-size=10M \ + --split=8 \ + --file-allocation=none \ + --dir=/tmp \ + --out=ewdk.iso \ + "${EWDK_URL}"; \ + echo "${EWDK_SHA256} ${iso}" | sha256sum --check -; \ + mkdir -p /opt/ewdk; \ + 7z x -y -r "${iso}" -o/opt/ewdk \ + "Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/${VCTOOLSVER}/include/*" \ + "Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/${VCTOOLSVER}/lib/x64/*" \ + "Program Files/Windows Kits/10/Include/${WINSDKVER}/*" \ + "Program Files/Windows Kits/10/Include/wdf/kmdf/1.27/*" \ + "Program Files/Windows Kits/10/Lib/${WINSDKVER}/km/x64/*" \ + "Program Files/Windows Kits/10/Lib/wdf/kmdf/x64/1.27/*"; \ + rm -f "${iso}"; \ + test -d "/opt/ewdk/Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/${VCTOOLSVER}/include"; \ + test -f "/opt/ewdk/Program Files/Windows Kits/10/Include/${WINSDKVER}/km/ntddk.h"; \ + test -f "/opt/ewdk/Program Files/Windows Kits/10/Include/wdf/kmdf/1.27/wdf.h"; \ + test -d "/opt/ewdk/Program Files/Windows Kits/10/Lib/${WINSDKVER}/km/x64"; \ + test -d "/opt/ewdk/Program Files/Windows Kits/10/Lib/wdf/kmdf/x64/1.27" + +# Pin clang-cl-linux by immutable commit and retain only the VFS generator. +RUN curl --fail --location --retry 5 \ + "https://raw.githubusercontent.com/tmp64/clang-cl-linux/${CLANG_CL_LINUX_REF}/generate_vfs.py" \ + -o /opt/ewdk/generate_vfs.py \ + && python3 /opt/ewdk/generate_vfs.py \ + --msvc "/opt/ewdk/Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC" \ + --sdk "/opt/ewdk/Program Files/Windows Kits/10" \ + --out /opt/ewdk/vfs-overlay.json \ + && test -s /opt/ewdk/vfs-overlay.json + + +FROM toolchain AS makecat-build + +ARG MAKECAT_REF=ee7aa4dd1d10ad5f254020ca0637df5abcc95618 + +RUN set -eux; \ + git init /src/makecat; \ + git -C /src/makecat remote add origin https://github.com/anonymix007/makecat.git; \ + git -C /src/makecat fetch --depth=1 origin "${MAKECAT_REF}"; \ + git -C /src/makecat checkout --detach FETCH_HEAD; \ + test "$(git -C /src/makecat rev-parse HEAD)" = "${MAKECAT_REF}" + +WORKDIR /src/makecat +RUN --mount=type=cache,target=/opt/cargo/registry \ + --mount=type=cache,target=/opt/cargo/git \ + cargo build --release --locked \ + && install -Dm755 target/release/makecat /out/makecat + + +FROM toolchain AS mesa-build + +ARG MESA_ARCHIVE_URL=https://gitlab.freedesktop.org/anonymix007/mesa/-/archive/venus-win32/mesa-venus-win32.tar.gz +ARG MESA_TREE_SHA256=9f216e64201e54408342a1757c1cd2e369b352a88ce96a05e8a4d7e91cad9690 +ARG WINSDKVER=10.0.26100.0 + +COPY --from=ewdk /opt/ewdk /opt/ewdk + +# Mesa is content-pinned. The URL may name the branch, but the normalized +# extracted tree must match MESA_TREE_SHA256 exactly or the production build +# stops. Changing the pin intentionally invalidates this layer. +RUN set -eux; \ + mkdir -p /src/mesa; \ + curl --fail --location --retry 5 "${MESA_ARCHIVE_URL}" -o /tmp/mesa.tar.gz; \ + tar -xzf /tmp/mesa.tar.gz -C /src/mesa --strip-components=1; \ + rm /tmp/mesa.tar.gz; \ + actual="$(cd /src/mesa && tar \ + --sort=name \ + --mtime='UTC 1970-01-01' \ + --owner=0 \ + --group=0 \ + --numeric-owner \ + -cf - . | sha256sum | awk '{print $1}')"; \ + echo "Mesa normalized tree: ${actual}"; \ + test "${actual}" = "${MESA_TREE_SHA256}" + +# Populate precisely the WDK headers listed by the pinned Mesa source tree. +RUN set -eux; \ + sdk="/opt/ewdk/Program Files/Windows Kits/10/Include/${WINSDKVER}"; \ + mkdir -p /src/mesa/include/winddk; \ + while IFS= read -r header; do \ + test -n "${header}" || continue; \ + source_header="$(find "${sdk}" -type f -iname "${header}" -print -quit)"; \ + if [ -z "${source_header}" ]; then \ + echo "Missing EWDK header for Mesa: ${header}" >&2; \ + exit 1; \ + fi; \ + cp "${source_header}" "/src/mesa/include/winddk/${header}"; \ + done < /src/mesa/include/winddk/.gitignore + +RUN cat > /tmp/mingw-x86_64.ini <<'EOF' +[binaries] +c = 'x86_64-w64-mingw32-gcc' +cpp = 'x86_64-w64-mingw32-g++' +ar = 'x86_64-w64-mingw32-ar' +strip = 'x86_64-w64-mingw32-strip' +windres = 'x86_64-w64-mingw32-windres' + +[host_machine] +system = 'windows' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' + +[properties] +needs_exe_wrapper = true +EOF + +RUN python3 -m venv /opt/mesa-venv \ + && /opt/mesa-venv/bin/pip install --no-cache-dir \ + "meson==1.7.2" \ + "jinja2==3.1.6" \ + "mako==1.3.10" \ + "packaging==25.0" \ + "ply==3.11" \ + "pyyaml==6.0.2" + +ENV PATH=/opt/mesa-venv/bin:/opt/cargo/bin:/opt/mingw-posix/bin:${PATH} + +RUN meson setup \ + /src/mesa/build-win64 \ + /src/mesa \ + --cross-file /tmp/mingw-x86_64.ini \ + --buildtype=release \ + --prefix=/ \ + -Dplatforms=windows \ + -Dvulkan-drivers=virtio \ + -Dgallium-drivers= \ + -Dopengl=false \ + -Degl=disabled \ + -Dglx=disabled \ + -Dgbm=disabled \ + -Dllvm=disabled \ + -Dxmlconfig=disabled \ + -Dbuild-tests=false \ + -Dvulkan-manifest-per-architecture=true \ + && meson compile -C /src/mesa/build-win64 -j "$(nproc)" \ + && DESTDIR=/tmp/mesa-stage meson install -C /src/mesa/build-win64 \ + && mesa_dll="$(find /tmp/mesa-stage -type f -name vulkan_virtio.dll -print -quit)" \ + && mesa_json="$(find /tmp/mesa-stage -type f -name virtio_icd.x86_64.json -print -quit)" \ + && test -n "${mesa_dll}" \ + && test -n "${mesa_json}" \ + && mkdir -p /out \ + && cp "${mesa_dll}" /out/vulkan_virtio.dll \ + && cp "${mesa_json}" /out/virtio_icd.x86_64.json \ + && cp /src/mesa/src/virtio/virtio-gpu/wddm_hw.h /out/mesa_wddm_hw.h \ + && grep -q 'vulkan_virtio.dll' /out/virtio_icd.x86_64.json \ + && file /out/vulkan_virtio.dll | grep -q 'PE32+' + +FROM toolchain AS d3d11-build + +ARG D3D11_SHA +ARG DXVK_SHA +ARG WINSDKVER=10.0.26100.0 + +COPY --from=ewdk /opt/ewdk /opt/ewdk +COPY --from=d3d11 / /src/d3d11/ + +# The named Git context is recursively cloned by BuildKit, including the DXVK +# submodule. D3D11_SHA/DXVK_SHA are recorded and checked by the workflow. +RUN set -eux; \ + test -n "${D3D11_SHA}"; \ + test -n "${DXVK_SHA}"; \ + test -f /src/d3d11/thirdparty/dxvk/version.h.in; \ + test -f /src/d3d11/include/virtio_wddm_uapi.h + +# Fill in the ignored WDK headers from the pinned EWDK. +RUN set -eux; \ + sdk="/opt/ewdk/Program Files/Windows Kits/10/Include/${WINSDKVER}"; \ + mkdir -p /src/d3d11/include/winddk; \ + while IFS= read -r header; do \ + test -n "${header}" || continue; \ + source_header="$(find "${sdk}" -type f -iname "${header}" -print -quit)"; \ + if [ -z "${source_header}" ]; then \ + echo "Missing EWDK header for D3D11: ${header}" >&2; \ + exit 1; \ + fi; \ + cp "${source_header}" "/src/d3d11/include/winddk/${header}"; \ + done < /src/d3d11/include/winddk/.gitignore + +WORKDIR /src/d3d11 +RUN set -eux; \ + vulkan_import="$(find /usr -type f -name 'libvulkan-1.a' -print -quit)"; \ + test -n "${vulkan_import}"; \ + export LIBRARY_PATH="$(dirname "${vulkan_import}")"; \ + make -j"$(nproc)" DXVK_GIT_VERSION="${DXVK_SHA}"; \ + test -f build/dist/dx11um_virtio.dll; \ + test -f build/dist/dx11um_virtio.debug; \ + mkdir -p /out; \ + cp build/dist/dx11um_virtio.dll /out/; \ + cp build/dist/dx11um_virtio.debug /out/; \ + cp include/virtio_wddm_uapi.h /out/d3d11_virtio_wddm_uapi.h; \ + file /out/dx11um_virtio.dll | grep -q 'PE32+'; \ + if x86_64-w64-mingw32-objdump -p /out/dx11um_virtio.dll \ + | grep -Eiq 'DLL Name: (libgcc_s|libstdc\+\+|libwinpthread)'; then \ + echo "Unexpected MinGW runtime dependency in dx11um_virtio.dll" >&2; \ + exit 1; \ + fi + + +FROM toolchain AS package + +ARG VERSION_ARG +ARG KMD_SHA +ARG D3D11_SHA +ARG DXVK_SHA +ARG MESA_TREE_SHA256 +ARG MAKECAT_REF +ARG CLANG_CL_LINUX_REF +ARG EWDK_VERSION +ARG VCTOOLSVER +ARG WINSDKVER +ARG RUST_TOOLCHAIN +ARG CBINDGEN_VERSION + +ENV VCTOOLSVER=${VCTOOLSVER} +ENV WINSDKVER=${WINSDKVER} + +COPY --from=ewdk /opt/ewdk /opt/ewdk +COPY --from=makecat-build /out/makecat /usr/local/bin/makecat +COPY --from=kmd / /src/kmd/ +COPY --from=mesa-build /out/ /opt/mesa-artifacts/ +COPY --from=d3d11-build /out/ /opt/d3d11-artifacts/ + +WORKDIR /src/kmd + +# Configure the EWDK exactly the way the Rust WDK helper expects it. +RUN cat > /src/kmd/ewdk.env < /src/kmd/cert.env <<'EOF' +#!/bin/bash +export CERT="/opt/test-cert/cert.pem" +export KEY="/opt/test-cert/key.pem" +EOF + +# Build/package the floating KMD master using the pinned environment and the +# two UMD artifacts. BuildKit reuses all upstream stages when only KMD changes. +RUN --mount=type=cache,target=/opt/cargo/registry \ + --mount=type=cache,target=/opt/cargo/git \ + ./dist.sh + +RUN set -eux; \ + dist=/src/kmd/target/dist; \ + cp /opt/test-cert/virtio_test_signing.cer "${dist}/"; \ + cat > "${dist}/BUILDINFO.txt" <&2; \ + exit 1; \ + fi; \ + done; \ + find "${dist}" -maxdepth 1 -type f -printf '%f\n' | sort + + +FROM scratch AS artifact +COPY --from=package /src/kmd/target/dist/ /