diff --git a/.dockerignore b/.dockerignore index 15191b977aa..4b91414fe46 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,3 +17,6 @@ venv/ # ignore artifacts artifacts/ + +# ignore Dockerfiles themselves +/docker/ diff --git a/cmake/compile_definitions/linux.cmake b/cmake/compile_definitions/linux.cmake index d4ebb597312..6710a498a89 100644 --- a/cmake/compile_definitions/linux.cmake +++ b/cmake/compile_definitions/linux.cmake @@ -223,6 +223,11 @@ if (${SUNSHINE_TRAY} EQUAL 0 AND SUNSHINE_REQUIRE_TRAY) message(FATAL_ERROR "Tray icon is required") endif() +pkg_check_modules(EVDEV libevdev REQUIRED) +include_directories(SYSTEM ${EVDEV_INCLUDE_DIRS}) +link_directories(${EVDEV_LIBRARY_DIRS}) +list(APPEND SUNSHINE_EXTERNAL_LIBRARIES ${EVDEV_LIBRARIES}) + list(APPEND PLATFORM_TARGET_FILES src/platform/linux/publish.cpp src/platform/linux/graphics.h @@ -241,13 +246,11 @@ list(APPEND PLATFORM_TARGET_FILES list(APPEND PLATFORM_LIBRARIES Boost::dynamic_linking dl - evdev numa pulse pulse-simple) include_directories( SYSTEM - /usr/include/libevdev-1.0 third-party/nv-codec-headers/include third-party/glad/include) diff --git a/docker/fedora-38.dockerfile b/docker/fedora-38.dockerfile index 5408782d074..66e18ea834a 100644 --- a/docker/fedora-38.dockerfile +++ b/docker/fedora-38.dockerfile @@ -1,17 +1,22 @@ # syntax=docker/dockerfile:1.4 # artifacts: true # platforms: linux/amd64,linux/arm64/v8 -# platforms_pr: linux/amd64 +# platforms_pr: linux/amd64,linux/arm64/v8 # no-cache-filters: sunshine-base,artifacts,sunshine ARG BASE=fedora ARG TAG=38 -FROM ${BASE}:${TAG} AS sunshine-base +FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-base FROM sunshine-base as sunshine-build +# reused args from base +ARG TAG +ENV TAG=${TAG} + ARG TARGETPLATFORM RUN echo "target_platform: ${TARGETPLATFORM}" +# args from ci workflow ARG BRANCH ARG BUILD_VERSION ARG COMMIT @@ -22,51 +27,111 @@ ENV BUILD_VERSION=${BUILD_VERSION} ENV COMMIT=${COMMIT} SHELL ["/bin/bash", "-o", "pipefail", "-c"] -# install dependencies +# setup env +WORKDIR /env +RUN <<_ENV +#!/bin/bash +set -e +case "${TARGETPLATFORM}" in + linux/amd64) + TARGETARCH=x86_64 + echo GCC_FLAVOR="" >> ./env + echo "DNF=( dnf -y --releasever \"${TAG}\" --forcearch \"${TARGETARCH}\" )" >> ./env + ;; + linux/arm64) + TARGETARCH=aarch64 + echo GCC_FLAVOR="-${TARGETARCH}-linux-gnu" >> ./env + echo "DNF=( dnf -y --installroot /mnt/cross --releasever \"${TAG}\" --forcearch \"${TARGETARCH}\" )" >> ./env + ;; + *) + echo "unsupported platform: ${TARGETPLATFORM}"; + exit 1 + ;; +esac +echo TARGETARCH=${TARGETARCH} >> ./env +echo TUPLE=${TARGETARCH}-linux-gnu >> ./env +_ENV + +# reset workdir +WORKDIR / + +# install build dependencies # hadolint ignore=DL3041 -RUN <<_DEPS +RUN <<_DEPS_A #!/bin/bash set -e + +# shellcheck source=/dev/null +source /env/env + dnf -y update -dnf -y group install "Development Tools" dnf -y install \ - boost-devel-1.78.0* \ cmake-3.27.* \ - gcc-13.2.* \ - gcc-c++-13.2.* \ - git \ - libappindicator-gtk3-devel \ - libcap-devel \ - libcurl-devel \ - libdrm-devel \ - libevdev-devel \ - libnotify-devel \ - libva-devel \ - libvdpau-devel \ - libX11-devel \ - libxcb-devel \ - libXcursor-devel \ - libXfixes-devel \ - libXi-devel \ - libXinerama-devel \ - libXrandr-devel \ - libXtst-devel \ - mesa-libGL-devel \ - miniupnpc-devel \ + gcc"${GCC_FLAVOR}"-13.2.* \ + gcc-c++"${GCC_FLAVOR}"-13.2.* \ + git-core \ nodejs \ - numactl-devel \ - openssl-devel \ - opus-devel \ - pulseaudio-libs-devel \ + pkgconf-pkg-config \ rpm-build \ + wayland-devel \ wget \ which -if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then - dnf -y install intel-mediasdk-devel -fi dnf clean all -rm -rf /var/cache/yum -_DEPS +_DEPS_A + +# install host dependencies +# hadolint ignore=DL3041 +RUN <<_DEPS_B +#!/bin/bash +set -e + +# shellcheck source=/dev/null +source /env/env + +# Initialize an array for packages +packages=( + boost-devel-1.78.0* + glibc-devel + libappindicator-gtk3-devel + libcap-devel + libcurl-devel + libdrm-devel + libevdev-devel + libnotify-devel + libstdc++-devel + libva-devel + libvdpau-devel + libX11-devel + libxcb-devel + libXcursor-devel + libXfixes-devel + libXi-devel + libXinerama-devel + libXrandr-devel + libXtst-devel + mesa-libGL-devel + miniupnpc-devel + numactl-devel + openssl-devel + opus-devel + pulseaudio-libs-devel + wayland-devel +) + +# Conditionally include arch specific packages +if [[ "${TARGETARCH}" == 'x86_64' ]]; then + packages+=(intel-mediasdk-devel) +fi + +"${DNF[@]}" install \ + filesystem + +# Install packages using the array +"${DNF[@]}" --setopt=tsflags=noscripts install "${packages[@]}" + +# Clean up +"${DNF[@]}" clean all +_DEPS_B # todo - enable cuda once it's supported for gcc 13 and fedora 38 ## install cuda @@ -78,9 +143,12 @@ _DEPS #RUN <<_INSTALL_CUDA ##!/bin/bash #set -e +# +## shellcheck source=/dev/null +#source /env/env #cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" #cuda_suffix="" -#if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then +#if [[ "${TARGETARCH}" == 'aarch64' ]]; then # cuda_suffix="_sbsa" #fi #url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" @@ -104,7 +172,32 @@ WORKDIR /build/sunshine/build RUN <<_MAKE #!/bin/bash set -e + +# shellcheck source=/dev/null +source /env/env + +# shellcheck disable=SC2086 +if [[ "${TARGETARCH}" == 'aarch64' ]]; then + CXX_FLAG_1="$(echo /mnt/cross/usr/include/c++/[0-9]*/)" + CXX_FLAG_2="$(echo /mnt/cross/usr/include/c++/[0-9]*/${TUPLE%%-*}-*/)" + LD_FLAG="$(echo /mnt/cross/usr/lib/gcc/${TUPLE%%-*}-*/[0-9]*/)" + + export \ + CXXFLAGS="-isystem ${CXX_FLAG_1} -isystem ${CXX_FLAG_2}" \ + LDFLAGS="-L${LD_FLAG}" \ + PKG_CONFIG_LIBDIR=/mnt/cross/usr/lib64/pkgconfig:/mnt/cross/usr/share/pkgconfig \ + PKG_CONFIG_SYSROOT_DIR=/mnt/cross \ + PKG_CONFIG_SYSTEM_INCLUDE_PATH=/mnt/cross/usr/include \ + PKG_CONFIG_SYSTEM_LIBRARY_PATH=/mnt/cross/usr/lib64 +fi + +TOOLCHAIN_OPTION="" +if [[ "${TARGETARCH}" != 'x86_64' ]]; then + TOOLCHAIN_OPTION="-DCMAKE_TOOLCHAIN_FILE=toolchain-${TUPLE}.cmake" +fi + cmake \ + "$TOOLCHAIN_OPTION" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DSUNSHINE_ASSETS_DIR=share/sunshine \ @@ -124,7 +217,7 @@ ARG TAG ARG TARGETARCH COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.rpm /sunshine-${BASE}-${TAG}-${TARGETARCH}.rpm -FROM sunshine-base as sunshine +FROM ${BASE}:${TAG} AS sunshine # copy deb from builder COPY --link --from=artifacts /sunshine*.rpm /sunshine.rpm diff --git a/docker/fedora-39.dockerfile b/docker/fedora-39.dockerfile index cc781a6730f..cae4c95fa7a 100644 --- a/docker/fedora-39.dockerfile +++ b/docker/fedora-39.dockerfile @@ -1,17 +1,24 @@ # syntax=docker/dockerfile:1.4 # artifacts: true # platforms: linux/amd64,linux/arm64/v8 -# platforms_pr: linux/amd64 -# no-cache-filters: sunshine-base,artifacts,sunshine +# platforms_pr: linux/amd64,linux/arm64/v8 +# no-cache-filters: sunshine-base,sunshine-install,artifacts,sunshine +ARG UNAME=lizard ARG BASE=fedora ARG TAG=39 -FROM ${BASE}:${TAG} AS sunshine-base +FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-build -FROM sunshine-base as sunshine-build +# reused args from base +ARG BASE +ARG TAG +ENV TAG=${TAG} -ARG TARGETPLATFORM -RUN echo "target_platform: ${TARGETPLATFORM}" +ARG BUILDARCH +ARG TARGETARCH +RUN echo "build_arch: ${BUILDARCH}" +RUN echo "target_arch: ${TARGETARCH}" +# args from ci workflow ARG BRANCH ARG BUILD_VERSION ARG COMMIT @@ -21,75 +28,146 @@ ENV BRANCH=${BRANCH} ENV BUILD_VERSION=${BUILD_VERSION} ENV COMMIT=${COMMIT} +ENV CUDA_NATIVE_DISTRO=fedora37 +ENV CUDA_CROSS_DISTRO=rhel8 +ENV CUDA_RT_VERSION=12.3.101 +ENV CUDA_NVCC_VERSION=12.3.107 + SHELL ["/bin/bash", "-o", "pipefail", "-c"] -# install dependencies +# setup env +WORKDIR /env +RUN <<_ENV +#!/bin/bash +set -e + +BUILD_DNF=( dnf -y --setopt=install_weak_deps=False --setopt=keepcache=True ) +DNF=( "${BUILD_DNF[@]}" --releasever "${TAG}" ) + +case "${TARGETARCH}" in + amd64) + DNF_ARCH=x86_64 + CUDA_ARCH=x86_64 + DNF+=( --forcearch "${DNF_ARCH}" ) + GCC_FLAVOR="" + ;; + arm64) + DNF_ARCH=aarch64 + CUDA_ARCH=sbsa + DNF+=( --forcearch "${DNF_ARCH}" --installroot /mnt/cross ) + GCC_FLAVOR="-${DNF_ARCH}-linux-gnu" + ;; + ppc64le) + DNF_ARCH=ppc64le + CUDA_ARCH=ppc64le + DNF+=( --forcearch "${DNF_ARCH}" --installroot /mnt/cross ) + GCC_FLAVOR="-${DNF_ARCH}-linux-gnu" + ;; + *) + echo "unsupported platform: ${TARGETARCH}"; + exit 1 + ;; +esac + +CUDA_REPOS="https://developer.download.nvidia.com/compute/cuda/repos" +CUDA_VERSION_SHORT="${CUDA_RT_VERSION%.*}" +TUPLE="${DNF_ARCH}-linux-gnu" + +declare -p \ + BUILD_DNF \ + DNF \ + DNF_ARCH \ + CUDA_ARCH \ + CUDA_REPOS \ + CUDA_VERSION_SHORT \ + GCC_FLAVOR \ + TUPLE \ + > ./env +_ENV + +# reset workdir +WORKDIR / + +# install build dependencies # hadolint ignore=DL3041 -RUN <<_DEPS +RUN --mount=type=cache,target=/var/cache/dnf,mode=0755,id=${BASE}-${TAG}-dnf <<_DEPS_A #!/bin/bash set -e -dnf -y update -dnf -y group install "Development Tools" -dnf -y install \ - boost-devel-1.81.0* \ + +# shellcheck source=/dev/null +source /env/env + +#curl -s -f -L --output-dir /etc/yum.repos.d -O "${CUDA_REPOS}/${CUDA_NATIVE_DISTRO}/$(uname -m)/cuda-${CUDA_NATIVE_DISTRO}.repo" + +"${BUILD_DNF[@]}" -y update +"${BUILD_DNF[@]}" -y install \ cmake-3.27.* \ - gcc-13.2.* \ - gcc-c++-13.2.* \ - git \ - libappindicator-gtk3-devel \ - libcap-devel \ - libcurl-devel \ - libdrm-devel \ - libevdev-devel \ - libnotify-devel \ - libva-devel \ - libvdpau-devel \ - libX11-devel \ - libxcb-devel \ - libXcursor-devel \ - libXfixes-devel \ - libXi-devel \ - libXinerama-devel \ - libXrandr-devel \ - libXtst-devel \ - mesa-libGL-devel \ - miniupnpc-devel \ - nodejs \ - numactl-devel \ - openssl-devel \ - opus-devel \ - pulseaudio-libs-devel \ + gcc"${GCC_FLAVOR}"-13.2.* \ + gcc-c++"${GCC_FLAVOR}"-13.2.* \ + git-core \ + nodejs-npm \ + pkgconf-pkg-config \ rpm-build \ - wget \ + wayland-devel \ which -if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then - dnf -y install intel-mediasdk-devel +# cuda-nvcc-"${CUDA_VERSION_SHORT//./-}" \ +_DEPS_A + +# install host dependencies +# hadolint ignore=DL3041 +RUN --mount=type=cache,target=/mnt/cross/var/cache/dnf,mode=0755,id=${BASE}-${TAG}-dnf <<_DEPS_B +#!/bin/bash +set -e + +# shellcheck source=/dev/null +source /env/env + +# Initialize an array for packages +packages=( + boost-devel-1.81.0* + glibc-devel + libappindicator-gtk3-devel + libcap-devel + libcurl-devel + libdrm-devel + libevdev-devel + libnotify-devel + libstdc++-devel + libva-devel + libvdpau-devel + libX11-devel + libxcb-devel + libXcursor-devel + libXfixes-devel + libXi-devel + libXinerama-devel + libXrandr-devel + libXtst-devel + mesa-libGL-devel + miniupnpc-devel + numactl-devel + openssl-devel + opus-devel + pulseaudio-libs-devel + wayland-devel +) + +# Conditionally include arch specific packages +if [[ "${TARGETARCH}" == 'amd64' ]]; then + packages+=(intel-mediasdk-devel) fi -dnf clean all -rm -rf /var/cache/yum -_DEPS - -# todo - enable cuda once it's supported for gcc 13 and fedora 39 -## install cuda -#WORKDIR /build/cuda -## versions: https://developer.nvidia.com/cuda-toolkit-archive -#ENV CUDA_VERSION="12.0.0" -#ENV CUDA_BUILD="525.60.13" -## hadolint ignore=SC3010 -#RUN <<_INSTALL_CUDA -##!/bin/bash -#set -e -#cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" -#cuda_suffix="" -#if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then -# cuda_suffix="_sbsa" -#fi -#url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" -#echo "cuda url: ${url}" -#wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run -#chmod a+x ./cuda.run -#./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm -#rm ./cuda.run -#_INSTALL_CUDA + +"${DNF[@]}" install \ + filesystem + +# Install packages using the array +"${DNF[@]}" --setopt=tsflags=noscripts install "${packages[@]}" + +# if [[ "${BUILDARCH}" != "${TARGETARCH}" ]]; then +# for URL in "${CUDA_REPOS}/${CUDA_CROSS_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 +# curl -s -f -L "${URL}" | rpm2archive | tar --directory=/ -zx "./usr/local/cuda-${CUDA_VERSION_SHORT}/targets/" +# done +# fi +_DEPS_B # copy repository WORKDIR /build/sunshine/ @@ -104,7 +182,52 @@ WORKDIR /build/sunshine/build RUN <<_MAKE #!/bin/bash set -e + +# shellcheck source=/dev/null +source /env/env + +cat > toolchain.cmake <<_TOOLCHAIN + set(CMAKE_ASM_COMPILER "${TUPLE}-gcc") + set(CMAKE_ASM-ATT_COMPILER "${TUPLE}-gcc") + set(CMAKE_C_COMPILER "${TUPLE}-gcc") + set(CMAKE_CXX_COMPILER "${TUPLE}-g++") + set(CMAKE_AR "${TUPLE}-gcc-ar" CACHE FILEPATH "Archive manager" FORCE) + set(CMAKE_RANLIB "${TUPLE}-gcc-ranlib" CACHE FILEPATH "Archive index generator" FORCE) + set(CMAKE_SYSTEM_PROCESSOR "$(case ${TARGETARCH} in + arm) echo armv7l ;; + *) echo ${DNF_ARCH} ;; + esac)") + set(CMAKE_SYSTEM_NAME "Linux") + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +_TOOLCHAIN + +if [[ "${TARGETARCH}" != 'amd64' ]]; then + cat >> toolchain.cmake <<_TOOLCHAIN + set(CMAKE_SYSROOT "/mnt/cross") +_TOOLCHAIN + + CXX_FLAG_1="$(echo /mnt/cross/usr/include/c++/[0-9]*/)" + CXX_FLAG_2="$(echo /mnt/cross/usr/include/c++/[0-9]*/${TUPLE%%-*}-*/)" + LD_FLAG="$(echo /mnt/cross/usr/lib/gcc/${TUPLE%%-*}-*/[0-9]*/)" + + export \ + CXXFLAGS="-isystem ${CXX_FLAG_1} -isystem ${CXX_FLAG_2}" \ + LDFLAGS="--sysroot=/mnt/cross -L${LD_FLAG}" \ + PKG_CONFIG_LIBDIR=/mnt/cross/usr/lib64/pkgconfig:/mnt/cross/usr/share/pkgconfig \ + PKG_CONFIG_SYSROOT_DIR=/mnt/cross \ + PKG_CONFIG_SYSTEM_INCLUDE_PATH=/mnt/cross/usr/include \ + PKG_CONFIG_SYSTEM_LIBRARY_PATH=/mnt/cross/usr/lib64 + + export \ + CUDAFLAGS="--compiler-options --sysroot=/mnt/cross,${CXXFLAGS// /,} --linker-options ${LDFLAGS// /,}" +fi + cmake \ + -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \ + -DCMAKE_CUDA_COMPILER:PATH="/usr/local/cuda-${CUDA_VERSION_SHORT}/bin/nvcc;${CUDAFLAGS// /;}" \ + -DCMAKE_CUDA_HOST_COMPILER:PATH="${TUPLE}-g++" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ -DSUNSHINE_ASSETS_DIR=share/sunshine \ @@ -122,49 +245,60 @@ FROM scratch AS artifacts ARG BASE ARG TAG ARG TARGETARCH + COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.rpm /sunshine-${BASE}-${TAG}-${TARGETARCH}.rpm -FROM sunshine-base as sunshine +FROM ${BASE}:${TAG} AS sunshine-base + +FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-install +ARG BASE +ARG TAG +ARG TARGETARCH + +COPY --link --from=sunshine-build /env/env /env/env +COPY --link --from=sunshine-base /usr/lib/sysimage/rpm /mnt/cross/usr/lib/sysimage/rpm +COPY --link --from=sunshine-base /etc/passwd /etc/group /etc/shadow /etc/gshadow /etc/sub?id /mnt/cross/etc/ -# copy deb from builder -COPY --link --from=artifacts /sunshine*.rpm /sunshine.rpm +# setup user +ARG PGID=1000 +ENV PGID=${PGID} +ARG PUID=1000 +ENV PUID=${PUID} +ARG UNAME +ENV UNAME=${UNAME} # install sunshine -RUN <<_INSTALL_SUNSHINE +RUN --mount=type=cache,target=/mnt/cross/var/cache/dnf,mode=0755,id=${BASE}-${TAG}-dnf \ + --mount=type=bind,from=artifacts,source=/sunshine-${BASE}-${TAG}-${TARGETARCH}.rpm,target=/tmp/sunshine.rpm \ + <<_INSTALL_SUNSHINE #!/bin/bash set -e -dnf -y update -dnf -y install /sunshine.rpm -dnf clean all -rm -rf /var/cache/yum + +# shellcheck source=/dev/null +source /env/env + +"${DNF[@]}" reinstall filesystem +"${DNF[@]}" --setopt=tsflags=noscripts update +"${DNF[@]}" --setopt=tsflags=noscripts install /tmp/sunshine.rpm + +groupadd -R /mnt/cross -f -g "${PGID}" "${UNAME}" +useradd -R /mnt/cross -lm -d "/home/${UNAME}" -s /bin/bash -g "${PGID}" -u "${PUID}" "${UNAME}" +mkdir -p "/mnt/cross/home/${UNAME}/.config/sunshine" +ln -s "home/${UNAME}/.config/sunshine" /mnt/cross/config +chown -R "${PUID}:${PGID}" "/mnt/cross/home/${UNAME}" _INSTALL_SUNSHINE +FROM ${BASE}:${TAG} AS sunshine +COPY --link --from=sunshine-install /mnt/cross / + # network setup EXPOSE 47984-47990/tcp EXPOSE 48010 EXPOSE 47998-48000/udp -# setup user -ARG PGID=1000 -ENV PGID=${PGID} -ARG PUID=1000 -ENV PUID=${PUID} +ARG UNAME +ENV HOME=/home/${UNAME} ENV TZ="UTC" -ARG UNAME=lizard -ENV UNAME=${UNAME} - -ENV HOME=/home/$UNAME - -# setup user -RUN <<_SETUP_USER -#!/bin/bash -set -e -groupadd -f -g "${PGID}" "${UNAME}" -useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -u "${PUID}" "${UNAME}" -mkdir -p ${HOME}/.config/sunshine -ln -s ${HOME}/.config/sunshine /config -chown -R ${UNAME} ${HOME} -_SETUP_USER USER ${UNAME} WORKDIR ${HOME} diff --git a/docker/ubuntu-22.04.dockerfile b/docker/ubuntu-22.04.dockerfile index 0e975df0558..ac9e5cc1d1f 100644 --- a/docker/ubuntu-22.04.dockerfile +++ b/docker/ubuntu-22.04.dockerfile @@ -1,19 +1,28 @@ # syntax=docker/dockerfile:1.4 # artifacts: true # platforms: linux/amd64,linux/arm64/v8 -# platforms_pr: linux/amd64 -# no-cache-filters: sunshine-base,artifacts,sunshine +# platforms_pr: linux/amd64,linux/arm64/v8 +# no-cache-filters: artifacts,sunshine ARG BASE=ubuntu ARG TAG=22.04 -FROM ${BASE}:${TAG} AS sunshine-base +ARG DIST=jammy +FROM --platform=$BUILDPLATFORM ${BASE}:${TAG} AS sunshine-build ENV DEBIAN_FRONTEND=noninteractive -FROM sunshine-base as sunshine-build +# reused args from base +ARG BASE +ARG TAG +ENV TAG=${TAG} +ARG DIST +ENV DIST=${DIST} -ARG TARGETPLATFORM -RUN echo "target_platform: ${TARGETPLATFORM}" +ARG BUILDARCH +ARG TARGETARCH +RUN echo "build_arch: ${BUILDARCH}" +RUN echo "target_arch: ${TARGETARCH}" +# args from ci workflow ARG BRANCH ARG BUILD_VERSION ARG COMMIT @@ -23,50 +32,140 @@ ENV BRANCH=${BRANCH} ENV BUILD_VERSION=${BUILD_VERSION} ENV COMMIT=${COMMIT} +ENV CUDA_DISTRO=rhel8 +ENV CUDA_RT_VERSION=12.3.101 +ENV CUDA_NVCC_VERSION=12.3.107 + SHELL ["/bin/bash", "-o", "pipefail", "-c"] # install dependencies -RUN <<_DEPS +WORKDIR /env +RUN --mount=type=cache,target=/var/cache/apt/archives,mode=0755,id=${BASE}-${TAG}-apt-archives \ + --mount=type=cache,target=/var/lib/apt/lists,mode=0755,id=${BASE}-${TAG}-apt-lists <<_DEPS #!/bin/bash set -e + +# Keep downloaded archives in the cache. +rm /etc/apt/apt.conf.d/docker-clean + +case "${TARGETARCH}" in + amd64) + DEB_ARCH=amd64 + DNF_ARCH=x86_64 + CUDA_ARCH=x86_64 + TUPLE=x86_64-linux-gnu + ;; + arm64) + DEB_ARCH=arm64 + DNF_ARCH=aarch64 + CUDA_ARCH=sbsa + TUPLE=aarch64-linux-gnu + ;; + ppc64le) + DEB_ARCH=ppc64el + DNF_ARCH=ppc64le + CUDA_ARCH=ppc64le + TUPLE=powerpc64le-linux-gnu + ;; + *) + echo "unsupported arch: ${TARGETARCH}"; + exit 1 + ;; +esac + +declare -p DEB_ARCH DNF_ARCH TUPLE > env + apt-get update -y apt-get install -y --no-install-recommends \ - build-essential \ - cmake=3.22.* \ + apt-transport-https \ ca-certificates \ - git \ - libayatana-appindicator3-dev \ - libavdevice-dev \ - libboost-filesystem-dev=1.74.* \ - libboost-locale-dev=1.74.* \ - libboost-log-dev=1.74.* \ - libboost-program-options-dev=1.74.* \ - libcap-dev \ - libcurl4-openssl-dev \ - libdrm-dev \ - libevdev-dev \ - libminiupnpc-dev \ - libnotify-dev \ - libnuma-dev \ - libopus-dev \ - libpulse-dev \ - libssl-dev \ - libva-dev \ - libvdpau-dev \ - libwayland-dev \ - libx11-dev \ - libxcb-shm0-dev \ - libxcb-xfixes0-dev \ - libxcb1-dev \ - libxfixes-dev \ - libxrandr-dev \ - libxtst-dev \ + gnupg \ wget -if [[ "${TARGETPLATFORM}" == 'linux/amd64' ]]; then - apt-get install -y --no-install-recommends \ - libmfx-dev + +source /etc/lsb-release + +CUDA_REPOS="https://developer.download.nvidia.com/compute/cuda/repos" +CUDA_UBUNTU="${CUDA_REPOS}/ubuntu${DISTRIB_RELEASE//.}/$(uname -m)" +CUDA_VERSION_SHORT="${CUDA_RT_VERSION%.*}" + +wget -qO- "${CUDA_UBUNTU}/3bf863cc.pub" | gpg --dearmor > /etc/apt/trusted.gpg.d/cuda.gpg +cat > /etc/apt/sources.list.d/cuda.list <<_SOURCES + deb [arch=$(dpkg --print-architecture)] ${CUDA_UBUNTU}/ / +_SOURCES + +if [[ "${BUILDARCH}" != "${TARGETARCH}" ]]; then + sed -i "s/^deb /deb [arch=$(dpkg --print-architecture)] /" /etc/apt/sources.list + dpkg --add-architecture "${DEB_ARCH}" + + cat > /etc/apt/sources.list.d/ports.list <<_SOURCES + deb [arch=${DEB_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ ${DISTRIB_CODENAME} main restricted universe multiverse + deb [arch=${DEB_ARCH}] http://ports.ubuntu.com/ubuntu-ports/ ${DISTRIB_CODENAME}-updates main restricted universe multiverse +_SOURCES +fi + +# Initialize an array for packages +packages=( + "cmake=3.22.*" + "cuda-nvcc-${CUDA_VERSION_SHORT//./-}" + "git" + "libwayland-bin" + "pkgconf" + "rpm2cpio" + "libayatana-appindicator3-dev:${DEB_ARCH}" + "libavdevice-dev:${DEB_ARCH}" + "libboost-filesystem-dev:${DEB_ARCH}=1.74.*" + "libboost-locale-dev:${DEB_ARCH}=1.74.*" + "libboost-log-dev:${DEB_ARCH}=1.74.*" + "libboost-program-options-dev:${DEB_ARCH}=1.74.*" + "libcap-dev:${DEB_ARCH}" + "libcurl4-openssl-dev:${DEB_ARCH}" + "libdrm-dev:${DEB_ARCH}" + "libevdev-dev:${DEB_ARCH}" + "libminiupnpc-dev:${DEB_ARCH}" + "libnotify-dev:${DEB_ARCH}" + "libnuma-dev:${DEB_ARCH}" + "libopus-dev:${DEB_ARCH}" + "libpulse-dev:${DEB_ARCH}" + "libssl-dev:${DEB_ARCH}" + "libva-dev:${DEB_ARCH}" + "libvdpau-dev:${DEB_ARCH}" + "libwayland-dev:${DEB_ARCH}" + "libx11-dev:${DEB_ARCH}" + "libxcb-shm0-dev:${DEB_ARCH}" + "libxcb-xfixes0-dev:${DEB_ARCH}" + "libxcb1-dev:${DEB_ARCH}" + "libxfixes-dev:${DEB_ARCH}" + "libxrandr-dev:${DEB_ARCH}" + "libxtst-dev:${DEB_ARCH}" +) + +# Conditionally include arch specific packages +if [[ "${TARGETARCH}" == 'amd64' ]]; then + packages+=( + "libmfx-dev:${DEB_ARCH}" + ) +fi +if [[ "${BUILDARCH}" == "${TARGETARCH}" ]]; then + packages+=( + "g++=4:11.2.*" + "gcc=4:11.2.*" + ) +else + packages+=( + "g++-${TUPLE}=4:11.2.*" + "gcc-${TUPLE}=4:11.2.*" + ) +fi + +apt-get update -y +apt-get install -y --no-install-recommends "${packages[@]}" + +if [[ "${BUILDARCH}" != "${TARGETARCH}" ]]; then + 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 + wget -q "${URL}" + rpm2archive "${URL##*/}" + tar --directory=/ -zxf "${URL##*/}.tgz" "./usr/local/cuda-${CUDA_VERSION_SHORT}/targets/" + done fi -apt-get clean -rm -rf /var/lib/apt/lists/* _DEPS #Install Node @@ -80,28 +179,6 @@ nvm install 20.9.0 nvm use 20.9.0 _INSTALL_NODE -# install cuda -WORKDIR /build/cuda -# versions: https://developer.nvidia.com/cuda-toolkit-archive -ENV CUDA_VERSION="11.8.0" -ENV CUDA_BUILD="520.61.05" -# hadolint ignore=SC3010 -RUN <<_INSTALL_CUDA -#!/bin/bash -set -e -cuda_prefix="https://developer.download.nvidia.com/compute/cuda/" -cuda_suffix="" -if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then - cuda_suffix="_sbsa" -fi -url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run" -echo "cuda url: ${url}" -wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run -chmod a+x ./cuda.run -./cuda.run --silent --toolkit --toolkitpath=/build/cuda --no-opengl-libs --no-man-page --no-drm -rm ./cuda.run -_INSTALL_CUDA - # copy repository WORKDIR /build/sunshine/ COPY --link .. . @@ -117,11 +194,39 @@ set -e #Set Node version source "$HOME/.nvm/nvm.sh" nvm use 20.9.0 -#Actually build + +# shellcheck source=/dev/null +source /env/env + +# Configure build +cat > toolchain.cmake <<_TOOLCHAIN +set(CMAKE_ASM_COMPILER "${TUPLE}-gcc") +set(CMAKE_ASM-ATT_COMPILER "${TUPLE}-gcc") +set(CMAKE_C_COMPILER "${TUPLE}-gcc") +set(CMAKE_CXX_COMPILER "${TUPLE}-g++") +set(CMAKE_AR "${TUPLE}-gcc-ar" CACHE FILEPATH "Archive manager" FORCE) +set(CMAKE_RANLIB "${TUPLE}-gcc-ranlib" CACHE FILEPATH "Archive index generator" FORCE) +set(CMAKE_SYSTEM_PROCESSOR "$(case ${TARGETARCH} in + arm) echo armv7l ;; + *) echo ${DNF_ARCH} ;; +esac)") +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +_TOOLCHAIN + +export \ + PKG_CONFIG_LIBDIR=/usr/lib/"${TUPLE}"/pkgconfig:/usr/share/pkgconfig + +# Actually build cmake \ - -DCMAKE_CUDA_COMPILER:PATH=/build/cuda/bin/nvcc \ + -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \ + -DCMAKE_CUDA_COMPILER:PATH=/usr/local/cuda/bin/nvcc \ + -DCMAKE_CUDA_HOST_COMPILER:PATH="${TUPLE}-g++" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ + -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE="${DEB_ARCH}" \ -DSUNSHINE_ASSETS_DIR=share/sunshine \ -DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine \ -DSUNSHINE_ENABLE_WAYLAND=ON \ @@ -139,19 +244,20 @@ ARG TAG ARG TARGETARCH COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb -FROM sunshine-base as sunshine - -# copy deb from builder -COPY --link --from=artifacts /sunshine*.deb /sunshine.deb +FROM ${BASE}:${TAG} as sunshine +ARG BASE +ARG TAG +ARG TARGETARCH # install sunshine -RUN <<_INSTALL_SUNSHINE +RUN --mount=type=cache,target=/var/cache/apt/archives,mode=0755,id=${BASE}-${TAG}-apt-archives \ + --mount=type=cache,target=/var/lib/apt/lists,mode=0755,id=${BASE}-${TAG}-apt-lists \ + --mount=type=bind,from=artifacts,source=/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb,target=/tmp/sunshine.deb \ + <<_INSTALL_SUNSHINE #!/bin/bash set -e apt-get update -y -apt-get install -y --no-install-recommends /sunshine.deb -apt-get clean -rm -rf /var/lib/apt/lists/* +apt-get install -y --no-install-recommends /tmp/sunshine.deb _INSTALL_SUNSHINE # network setup diff --git a/toolchain-aarch64-linux-gnu-debian.cmake b/toolchain-aarch64-linux-gnu-debian.cmake new file mode 100644 index 00000000000..e853b7d6271 --- /dev/null +++ b/toolchain-aarch64-linux-gnu-debian.cmake @@ -0,0 +1,26 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Linux) + +# set processor type +SET(CMAKE_SYSTEM_PROCESSOR aarch64) + +SET(COMPILER_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-linux-gnu) + +# which compilers to use for C and C++ +SET(CMAKE_ASM_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_ASM-ATT_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX}) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# packaging +set(CPACK_RPM_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}") diff --git a/toolchain-aarch64-linux-gnu.cmake b/toolchain-aarch64-linux-gnu.cmake new file mode 100644 index 00000000000..4a1407e8aea --- /dev/null +++ b/toolchain-aarch64-linux-gnu.cmake @@ -0,0 +1,29 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Linux) + +# set processor type +SET(CMAKE_SYSTEM_PROCESSOR aarch64) + +SET(COMPILER_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-linux-gnu) + +# which compilers to use for C and C++ +SET(CMAKE_ASM_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_ASM-ATT_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++) + +# here is the target environment located +set(CMAKE_SYSROOT "/mnt/cross") + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_AR "${COMPILER_PREFIX}-gcc-ar" CACHE FILEPATH "Archive manager" FORCE) +set(CMAKE_RANLIB "${COMPILER_PREFIX}-gcc-ranlib" CACHE FILEPATH "Archive index generator" FORCE) + +# packaging +set(CPACK_RPM_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}") diff --git a/toolchain-x86_64-linux-gnu.cmake b/toolchain-x86_64-linux-gnu.cmake new file mode 100644 index 00000000000..148a13615bd --- /dev/null +++ b/toolchain-x86_64-linux-gnu.cmake @@ -0,0 +1,29 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Linux) + +# set processor type +SET(CMAKE_SYSTEM_PROCESSOR x86_64) + +SET(COMPILER_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-linux-gnu) + +# which compilers to use for C and C++ +SET(CMAKE_ASM_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_ASM-ATT_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) +SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++) + +# here is the target environment located +set(CMAKE_SYSROOT "/mnt/cross") + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_AR "${COMPILER_PREFIX}-gcc-ar" CACHE FILEPATH "Archive manager" FORCE) +set(CMAKE_RANLIB "${COMPILER_PREFIX}-gcc-ranlib" CACHE FILEPATH "Archive index generator" FORCE) + +# packaging +set(CPACK_RPM_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")