1ARG BASE_IMAGE=docker.io/debian
2ARG BASE_IMAGE_TAG=bookworm-slim
3FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} AS base-image
4
5ENV APT_UPDATE="apt-get update" \
6    APT_INSTALL="env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends" \
7    APT_CLEANUP="rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*"
8
9FROM base-image AS base
10
11LABEL org.opencontainers.image.title="Pixman build environment for platform coverage" \
12      org.opencontainers.image.authors="Marek Pikuła <m.pikula@partner.samsung.com>"
13
14ARG GCOVR_VERSION="~=7.2"
15ARG MESON_VERSION="~=1.7"
16RUN echo "deb http://deb.debian.org/debian bookworm-backports main" >  /etc/apt/sources.list.d/debian-12-backports.list \
17    && ${APT_UPDATE} \
18    && ${APT_INSTALL} \
19        # Build dependencies.
20        build-essential \
21        ninja-build \
22        pkg-config \
23        # pipx dependencies.
24        python3-argcomplete \
25        python3-packaging \
26        python3-pip \
27        python3-platformdirs \
28        python3-userpath \
29        python3-venv \
30        # gcovr dependencies.
31        python3-lxml \
32    # User bookworm-backports for QEMU, as it has version 7 by default, which
33    # has some issues.
34    && ${APT_INSTALL} \
35        $(grep bookworm /etc/os-release >/dev/null && echo -t bookworm-backports) \
36        qemu-user \
37    && ${APT_CLEANUP} \
38    # Install pipx using pip to have a more recent version of pipx, which
39    # supports the `--global` flag.
40    && pip install pipx --break-system-packages \
41    # Install a recent version of meson and gcovr using pipx to have the same
42    # version across all variants regardless of base.
43    && pipx install --global --system-site-packages \
44        gcovr${GCOVR_VERSION} \
45        meson${MESON_VERSION} \
46    && gcovr --version \
47    && echo Meson version: \
48    && meson --version
49
50FROM base AS llvm-base
51# LLVM 16 is the highest available in Bookworm. Preferably, we should use the
52# same version for all platforms, but it's not possible at the moment.
53ARG LLVM_VERSION=16
54RUN ${APT_UPDATE} \
55    && ${APT_INSTALL} \
56        clang-${LLVM_VERSION} \
57        libclang-rt-${LLVM_VERSION}-dev \
58        lld-${LLVM_VERSION} \
59        llvm-${LLVM_VERSION} \
60    && ${APT_CLEANUP} \
61    && ln -f /usr/bin/clang-${LLVM_VERSION} /usr/bin/clang \
62    && ln -f /usr/bin/lld-${LLVM_VERSION} /usr/bin/lld \
63    && ln -f /usr/bin/llvm-ar-${LLVM_VERSION} /usr/bin/llvm-ar \
64    && ln -f /usr/bin/llvm-strip-${LLVM_VERSION} /usr/bin/llvm-strip
65
66FROM llvm-base AS native-base
67ARG LLVM_VERSION=16
68RUN ${APT_UPDATE} \
69    && ${APT_INSTALL} \
70        # Runtime library dependencies.
71        libglib2.0-dev \
72        libgtk-3-dev \
73        libpng-dev \
74    # Install libomp-dev if available (OpenMP support for LLVM). It's done only
75    # for the native images, as OpenMP support in cross-build environment is
76    # tricky for LLVM.
77    && (${APT_INSTALL} libomp-${LLVM_VERSION}-dev \
78        || echo "OpenMP not available on this platform.") \
79    && ${APT_CLEANUP}
80
81# The following targets differ in BASE_IMAGE.
82FROM native-base AS linux-386
83FROM native-base AS linux-amd64
84FROM native-base AS linux-arm-v5
85FROM native-base AS linux-arm-v7
86FROM native-base AS linux-arm64-v8
87FROM native-base AS linux-mips64le
88FROM native-base AS linux-mipsel
89FROM native-base AS linux-ppc64le
90FROM native-base AS linux-riscv64
91
92# The following targets should have a common BASE_IMAGE.
93FROM llvm-base AS linux-mips
94RUN ${APT_UPDATE} \
95    && ${APT_INSTALL} gcc-multilib-mips-linux-gnu \
96    && ${APT_CLEANUP}
97
98FROM llvm-base AS linux-ppc
99RUN ${APT_UPDATE} \
100    && ${APT_INSTALL} gcc-multilib-powerpc-linux-gnu \
101    && ${APT_CLEANUP}
102
103FROM llvm-base AS linux-ppc64
104RUN ${APT_UPDATE} \
105    && ${APT_INSTALL} gcc-multilib-powerpc64-linux-gnu \
106    && ${APT_CLEANUP}
107
108# Windows base image with a pre-built LLVM MinGW toolchain.
109FROM base-image AS windows-llvm-base-build
110ARG LLVM_MINGW_RELEASE=20250402
111ARG LLVM_MINGW_VARIANT=llvm-mingw-${LLVM_MINGW_RELEASE}-ucrt-ubuntu-20.04
112RUN ${APT_UPDATE} \
113    && ${APT_INSTALL} \
114        ca-certificates \
115        wget \
116        xz-utils \
117    && ${APT_CLEANUP} \
118    && wget https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_RELEASE}/${LLVM_MINGW_VARIANT}-`uname -m`.tar.xz \
119        -O - | tar -xJ -C /opt \
120    && mv /opt/llvm* /opt/llvm
121
122FROM base AS windows-llvm-base
123RUN ${APT_UPDATE} \
124    && ${APT_INSTALL} procps \
125    && ${APT_CLEANUP}
126COPY --from=windows-llvm-base-build /opt/llvm /opt/llvm
127ENV PATH=/opt/llvm/bin:${PATH} \
128    # Inspired by https://code.videolan.org/videolan/docker-images
129    WINE_BOOT='wine wineboot --init \
130        && while pgrep wineserver > /dev/null; do \
131            echo "waiting ..."; \
132            sleep 1; \
133        done \
134        && rm -rf /tmp/wine-*'
135
136FROM windows-llvm-base AS windows-686
137ENV WINEPATH=/opt/llvm/i686-w64-mingw32/bin \
138    WINEARCH=win32
139RUN dpkg --add-architecture i386 \
140    && ${APT_UPDATE} \
141    && ${APT_INSTALL} \
142        libwine:i386 \
143        wine \
144        wine32 \
145    && ${APT_CLEANUP} \
146    && ${WINE_BOOT}
147
148# Dependencies needed both for Wine build and the final image.
149FROM windows-llvm-base AS windows-wine-build-base
150RUN ${APT_UPDATE} \
151    && ${APT_INSTALL} \
152        libfreetype-dev \
153        libgnutls28-dev \
154        libkrb5-dev \
155        libx11-dev \
156        libxcomposite-dev \
157        libxcursor-dev \
158        libxext-dev \
159        libxfixes-dev \
160        libxi-dev \
161        libxrandr-dev \
162        libxrender-dev \
163    && ${APT_CLEANUP}
164
165# Wine build intermediate target, not going into the final image.
166FROM windows-wine-build-base AS windows-wine-build
167RUN ${APT_UPDATE} \
168    && ${APT_INSTALL} \
169        bison \
170        ca-certificates \
171        clang \
172        flex \
173        git \
174        lld \
175        llvm \
176    && ${APT_CLEANUP}
177ARG WINE_VERSION=10.5
178RUN git clone https://gitlab.winehq.org/wine/wine.git \
179        -b wine-${WINE_VERSION} \
180        --depth 1
181RUN cd wine \
182    && ./configure --enable-win64 --disable-tests --without-unwind --prefix=/opt/wine \
183    && make -j`nproc` \
184    && make install
185
186FROM windows-llvm-base AS windows-amd64
187COPY --from=windows-wine-build /opt/wine /opt/wine
188ENV PATH=/opt/wine/bin:${PATH} \
189    WINEPATH=/opt/llvm/x86_64-w64-mingw32/bin
190RUN ${WINE_BOOT}
191
192FROM windows-wine-build-base AS windows-arm64-v8
193COPY --from=windows-wine-build /opt/wine /opt/wine
194ENV PATH=/opt/wine/bin:${PATH} \
195    WINEPATH=/opt/llvm/aarch64-w64-mingw32/bin
196RUN ${WINE_BOOT}
197