Skip to content

Commit ed6eaf3

Browse files
committed
build: Fix Docker cross-compiling for Ubuntu 22.04
Works for amd64, arm64, and ppc64le.
1 parent 3d01cb8 commit ed6eaf3

File tree

1 file changed

+142
-136
lines changed

1 file changed

+142
-136
lines changed

docker/ubuntu-22.04.dockerfile

Lines changed: 142 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,25 @@
22
# artifacts: true
33
# platforms: linux/amd64,linux/arm64/v8
44
# platforms_pr: linux/amd64,linux/arm64/v8
5-
# no-cache-filters: sunshine-base,artifacts,sunshine
5+
# no-cache-filters: artifacts,sunshine
66
ARG BASE=ubuntu
77
ARG TAG=22.04
88
ARG DIST=jammy
9-
FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-base
9+
FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-build
1010

1111
ENV DEBIAN_FRONTEND=noninteractive
1212

13-
FROM sunshine-base as sunshine-build
14-
1513
# reused args from base
14+
ARG BASE
1615
ARG TAG
1716
ENV TAG=${TAG}
1817
ARG DIST
1918
ENV DIST=${DIST}
2019

21-
ARG BUILDPLATFORM
22-
ARG TARGETPLATFORM
23-
RUN echo "build_platform: ${BUILDPLATFORM}"
24-
RUN echo "target_platform: ${TARGETPLATFORM}"
20+
ARG BUILDARCH
21+
ARG TARGETARCH
22+
RUN echo "build_arch: ${BUILDARCH}"
23+
RUN echo "target_arch: ${TARGETARCH}"
2524

2625
# args from ci workflow
2726
ARG BRANCH
@@ -33,118 +32,124 @@ ENV BRANCH=${BRANCH}
3332
ENV BUILD_VERSION=${BUILD_VERSION}
3433
ENV COMMIT=${COMMIT}
3534

35+
ENV CUDA_DISTRO=rhel8
36+
ENV CUDA_RT_VERSION=12.3.101
37+
ENV CUDA_NVCC_VERSION=12.3.107
38+
3639
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
37-
# setup env
40+
# install dependencies
3841
WORKDIR /env
39-
RUN <<_ENV
42+
RUN --mount=type=cache,target=/var/cache/apt/archives,mode=0755,id=${BASE}-${TAG}-apt-archives \
43+
--mount=type=cache,target=/var/lib/apt/lists,mode=0755,id=${BASE}-${TAG}-apt-lists <<_DEPS
4044
#!/bin/bash
4145
set -e
42-
case "${BUILDPLATFORM}" in
43-
linux/amd64)
44-
BUILDARCH=amd64
45-
;;
46-
linux/arm64)
47-
BUILDARCH=arm64
48-
;;
49-
*)
50-
echo "unsupported platform: ${TARGETPLATFORM}";
51-
exit 1
52-
;;
53-
esac
5446

55-
case "${TARGETPLATFORM}" in
56-
linux/amd64)
57-
PACKAGEARCH=amd64
58-
TARGETARCH=x86_64
47+
# Keep downloaded archives in the cache.
48+
rm /etc/apt/apt.conf.d/docker-clean
49+
50+
case "${TARGETARCH}" in
51+
amd64)
52+
DEB_ARCH=amd64
53+
DNF_ARCH=x86_64
54+
CUDA_ARCH=x86_64
55+
TUPLE=x86_64-linux-gnu
56+
;;
57+
arm64)
58+
DEB_ARCH=arm64
59+
DNF_ARCH=aarch64
60+
CUDA_ARCH=sbsa
61+
TUPLE=aarch64-linux-gnu
5962
;;
60-
linux/arm64)
61-
PACKAGEARCH=arm64
62-
TARGETARCH=aarch64
63+
ppc64le)
64+
DEB_ARCH=ppc64el
65+
DNF_ARCH=ppc64le
66+
CUDA_ARCH=ppc64le
67+
TUPLE=powerpc64le-linux-gnu
6368
;;
6469
*)
65-
echo "unsupported platform: ${TARGETPLATFORM}";
70+
echo "unsupported arch: ${TARGETARCH}";
6671
exit 1
6772
;;
6873
esac
6974

70-
mirror="http://ports.ubuntu.com/ubuntu-ports"
71-
extra_sources=$(cat <<- VAREOF
72-
deb [arch=$PACKAGEARCH] $mirror $DIST main restricted
73-
deb [arch=$PACKAGEARCH] $mirror $DIST-updates main restricted
74-
deb [arch=$PACKAGEARCH] $mirror $DIST universe
75-
deb [arch=$PACKAGEARCH] $mirror $DIST-updates universe
76-
deb [arch=$PACKAGEARCH] $mirror $DIST multiverse
77-
deb [arch=$PACKAGEARCH] $mirror $DIST-updates multiverse
78-
deb [arch=$PACKAGEARCH] $mirror $DIST-backports main restricted universe multiverse
79-
deb [arch=$PACKAGEARCH] $mirror $DIST-security main restricted
80-
deb [arch=$PACKAGEARCH] $mirror $DIST-security universe
81-
deb [arch=$PACKAGEARCH] $mirror $DIST-security multiverse
82-
VAREOF
83-
)
84-
85-
if [[ "${BUILDPLATFORM}" != "${TARGETPLATFORM}" ]]; then
86-
# fix original sources
87-
sed -i -e "s#deb http#deb [arch=$BUILDARCH] http#g" /etc/apt/sources.list
88-
dpkg --add-architecture $PACKAGEARCH
75+
declare -p DEB_ARCH DNF_ARCH TUPLE > env
8976

90-
echo "$extra_sources" | tee -a /etc/apt/sources.list
77+
apt-get update -y
78+
apt-get install -y --no-install-recommends \
79+
apt-transport-https \
80+
ca-certificates \
81+
gnupg \
82+
wget
83+
84+
source /etc/lsb-release
85+
86+
CUDA_REPOS="https://developer.download.nvidia.com/compute/cuda/repos"
87+
CUDA_UBUNTU="${CUDA_REPOS}/ubuntu${DISTRIB_RELEASE//.}/$(uname -m)"
88+
CUDA_VERSION_SHORT="${CUDA_RT_VERSION%.*}"
89+
90+
wget -qO- "${CUDA_UBUNTU}/3bf863cc.pub" | gpg --dearmor > /etc/apt/trusted.gpg.d/cuda.gpg
91+
cat > /etc/apt/sources.list.d/cuda.list <<_SOURCES
92+
deb [arch=$(dpkg --print-architecture)] ${CUDA_UBUNTU}/ /
93+
_SOURCES
94+
95+
if [[ "${BUILDARCH}" != "${TARGETARCH}" ]]; then
96+
sed -i "s/^deb /deb [arch=$(dpkg --print-architecture)] /" /etc/apt/sources.list
97+
dpkg --add-architecture "${DEB_ARCH}"
98+
99+
cat > /etc/apt/sources.list.d/ports.list <<_SOURCES
100+
deb [arch=${DEB_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ ${DISTRIB_CODENAME} main restricted universe multiverse
101+
deb [arch=${DEB_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ ${DISTRIB_CODENAME}-updates main restricted universe multiverse
102+
_SOURCES
91103
fi
92104

93-
echo PACKAGEARCH=${PACKAGEARCH}; \
94-
echo TARGETARCH=${TARGETARCH}; \
95-
echo TUPLE=${TARGETARCH}-linux-gnu >> ./env
96-
_ENV
97-
98-
# install dependencies
99-
RUN <<_DEPS
100-
#!/bin/bash
101-
set -e
102-
103-
# shellcheck source=/dev/null
104-
source /env/env
105-
106105
# Initialize an array for packages
107106
packages=(
108-
"build-essential"
109107
"cmake=3.22.*"
110-
"ca-certificates"
108+
"cuda-nvcc-${CUDA_VERSION_SHORT//./-}"
111109
"git"
112-
"libayatana-appindicator3-dev"
113-
"libavdevice-dev"
114-
"libboost-filesystem-dev=1.74.*"
115-
"libboost-locale-dev=1.74.*"
116-
"libboost-log-dev=1.74.*"
117-
"libboost-program-options-dev=1.74.*"
118-
"libcap-dev"
119-
"libcurl4-openssl-dev"
120-
"libdrm-dev"
121-
"libevdev-dev"
122-
"libminiupnpc-dev"
123-
"libnotify-dev"
124-
"libnuma-dev"
125-
"libopus-dev"
126-
"libpulse-dev"
127-
"libssl-dev"
128-
"libva-dev"
129-
"libvdpau-dev"
130-
"libwayland-dev"
131-
"libx11-dev"
132-
"libxcb-shm0-dev"
133-
"libxcb-xfixes0-dev"
134-
"libxcb1-dev"
135-
"libxfixes-dev"
136-
"libxrandr-dev"
137-
"libxtst-dev"
138-
"wget"
110+
"libwayland-bin"
111+
"pkgconf"
112+
"rpm2cpio"
113+
"libayatana-appindicator3-dev:${DEB_ARCH}"
114+
"libavdevice-dev:${DEB_ARCH}"
115+
"libboost-filesystem-dev:${DEB_ARCH}=1.74.*"
116+
"libboost-locale-dev:${DEB_ARCH}=1.74.*"
117+
"libboost-log-dev:${DEB_ARCH}=1.74.*"
118+
"libboost-program-options-dev:${DEB_ARCH}=1.74.*"
119+
"libcap-dev:${DEB_ARCH}"
120+
"libcurl4-openssl-dev:${DEB_ARCH}"
121+
"libdrm-dev:${DEB_ARCH}"
122+
"libevdev-dev:${DEB_ARCH}"
123+
"libminiupnpc-dev:${DEB_ARCH}"
124+
"libnotify-dev:${DEB_ARCH}"
125+
"libnuma-dev:${DEB_ARCH}"
126+
"libopus-dev:${DEB_ARCH}"
127+
"libpulse-dev:${DEB_ARCH}"
128+
"libssl-dev:${DEB_ARCH}"
129+
"libva-dev:${DEB_ARCH}"
130+
"libvdpau-dev:${DEB_ARCH}"
131+
"libwayland-dev:${DEB_ARCH}"
132+
"libx11-dev:${DEB_ARCH}"
133+
"libxcb-shm0-dev:${DEB_ARCH}"
134+
"libxcb-xfixes0-dev:${DEB_ARCH}"
135+
"libxcb1-dev:${DEB_ARCH}"
136+
"libxfixes-dev:${DEB_ARCH}"
137+
"libxrandr-dev:${DEB_ARCH}"
138+
"libxtst-dev:${DEB_ARCH}"
139139
)
140140

141141
# Conditionally include arch specific packages
142-
if [[ "${TARGETARCH}" == 'x86_64' ]]; then
142+
if [[ "${TARGETARCH}" == 'amd64' ]]; then
143143
packages+=(
144-
"libmfx-dev"
144+
"libmfx-dev:${DEB_ARCH}"
145145
)
146146
fi
147-
if [[ "${BUILDPLATFORM}" != "${TARGETPLATFORM}" ]]; then
147+
if [[ "${BUILDARCH}" == "${TARGETARCH}" ]]; then
148+
packages+=(
149+
"g++=4:11.2.*"
150+
"gcc=4:11.2.*"
151+
)
152+
else
148153
packages+=(
149154
"g++-${TUPLE}=4:11.2.*"
150155
"gcc-${TUPLE}=4:11.2.*"
@@ -153,8 +158,14 @@ fi
153158

154159
apt-get update -y
155160
apt-get install -y --no-install-recommends "${packages[@]}"
156-
apt-get clean
157-
rm -rf /var/lib/apt/lists/*
161+
162+
if [[ "${BUILDARCH}" != "${TARGETARCH}" ]]; then
163+
for URL in "${CUDA_REPOS}/${CUDA_DISTRO}/${CUDA_ARCH}"/{cuda-cudart-devel-${CUDA_VERSION_SHORT//./-}-${CUDA_RT_VERSION},cuda-nvcc-${CUDA_VERSION_SHORT//./-}-${CUDA_NVCC_VERSION}}-1.${DNF_ARCH}.rpm; do
164+
wget -q "${URL}"
165+
rpm2archive "${URL##*/}"
166+
tar --directory=/ -zxf "${URL##*/}.tgz" "./usr/local/cuda-${CUDA_VERSION_SHORT}/targets/"
167+
done
168+
fi
158169
_DEPS
159170

160171
#Install Node
@@ -168,28 +179,6 @@ nvm install 20.9.0
168179
nvm use 20.9.0
169180
_INSTALL_NODE
170181

171-
# install cuda
172-
WORKDIR /build/cuda
173-
# versions: https://developer.nvidia.com/cuda-toolkit-archive
174-
ENV CUDA_VERSION="11.8.0"
175-
ENV CUDA_BUILD="520.61.05"
176-
# hadolint ignore=SC3010
177-
RUN <<_INSTALL_CUDA
178-
#!/bin/bash
179-
set -e
180-
cuda_prefix="https://developer.download.nvidia.com/compute/cuda/"
181-
cuda_suffix=""
182-
if [[ "${TARGETARCH}" == 'aarch64' ]]; then
183-
cuda_suffix="_sbsa"
184-
fi
185-
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
186-
echo "cuda url: ${url}"
187-
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
188-
chmod a+x ./cuda.run
189-
./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm
190-
rm ./cuda.run
191-
_INSTALL_CUDA
192-
193182
# copy repository
194183
WORKDIR /build/sunshine/
195184
COPY --link .. .
@@ -209,19 +198,35 @@ nvm use 20.9.0
209198
# shellcheck source=/dev/null
210199
source /env/env
211200

212-
TOOLCHAIN_OPTION=""
213-
if [[ "${BUILDPLATFORM}" != "${TARGETPLATFORM}" ]]; then
214-
export "CCPREFIX=/usr/bin/${TUPLE}-"
215-
216-
TOOLCHAIN_OPTION="-DCMAKE_TOOLCHAIN_FILE=toolchain-${TUPLE}-debian.cmake"
217-
fi
218-
219-
#Actually build
201+
# Configure build
202+
cat > toolchain.cmake <<_TOOLCHAIN
203+
set(CMAKE_ASM_COMPILER "${TUPLE}-gcc")
204+
set(CMAKE_ASM-ATT_COMPILER "${TUPLE}-gcc")
205+
set(CMAKE_C_COMPILER "${TUPLE}-gcc")
206+
set(CMAKE_CXX_COMPILER "${TUPLE}-g++")
207+
set(CMAKE_AR "${TUPLE}-gcc-ar" CACHE FILEPATH "Archive manager" FORCE)
208+
set(CMAKE_RANLIB "${TUPLE}-gcc-ranlib" CACHE FILEPATH "Archive index generator" FORCE)
209+
set(CMAKE_SYSTEM_PROCESSOR "$(case ${TARGETARCH} in
210+
arm) echo armv7l ;;
211+
*) echo ${DNF_ARCH} ;;
212+
esac)")
213+
set(CMAKE_SYSTEM_NAME "Linux")
214+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
215+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
216+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
217+
_TOOLCHAIN
218+
219+
export \
220+
PKG_CONFIG_LIBDIR=/usr/lib/"${TUPLE}"/pkgconfig:/usr/share/pkgconfig
221+
222+
# Actually build
220223
cmake \
221-
"$TOOLCHAIN_OPTION" \
222-
-DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \
224+
-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
225+
-DCMAKE_CUDA_COMPILER:PATH=/usr/local/cuda/bin/nvcc \
226+
-DCMAKE_CUDA_HOST_COMPILER:PATH="${TUPLE}-g++" \
223227
-DCMAKE_BUILD_TYPE=Release \
224228
-DCMAKE_INSTALL_PREFIX=/usr \
229+
-DCPACK_DEBIAN_PACKAGE_ARCHITECTURE="${DEB_ARCH}" \
225230
-DSUNSHINE_ASSETS_DIR=share/sunshine \
226231
-DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \
227232
-DSUNSHINE_ENABLE_WAYLAND=ON \
@@ -240,18 +245,19 @@ ARG TARGETARCH
240245
COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb
241246

242247
FROM ${BASE}:${TAG} as sunshine
243-
244-
# copy deb from builder
245-
COPY --link --from=artifacts /sunshine*.deb /sunshine.deb
248+
ARG BASE
249+
ARG TAG
250+
ARG TARGETARCH
246251

247252
# install sunshine
248-
RUN <<_INSTALL_SUNSHINE
253+
RUN --mount=type=cache,target=/var/cache/apt/archives,mode=0755,id=${BASE}-${TAG}-apt-archives \
254+
--mount=type=cache,target=/var/lib/apt/lists,mode=0755,id=${BASE}-${TAG}-apt-lists \
255+
--mount=type=bind,from=artifacts,source=/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb,target=/tmp/sunshine.deb \
256+
<<_INSTALL_SUNSHINE
249257
#!/bin/bash
250258
set -e
251259
apt-get update -y
252-
apt-get install -y --no-install-recommends /sunshine.deb
253-
apt-get clean
254-
rm -rf /var/lib/apt/lists/*
260+
apt-get install -y --no-install-recommends /tmp/sunshine.deb
255261
_INSTALL_SUNSHINE
256262

257263
# network setup

0 commit comments

Comments
 (0)