# Ubuntu 24.04 (Noble) base with CUDA 13 devel toolchain FROM nvidia/cuda:13.3.0-devel-ubuntu24.04 LABEL authors="leonarski_f" ENV DEBIAN_FRONTEND=noninteractive ARG OPENSSL_VERSION=3.5.4 ARG QT_VERSION=6.11.1 ARG DBUS_VERSION=1.14.10 ARG NODE_MAJOR=22 ARG EIGEN_VERSION=3.4.0 # HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent / # ExternalProject). Eigen is an external find_package(Eigen3 3.4) dependency, installed from source # below (3.4.x is required; Eigen's same-major-version rule rejects 5.x). nasm is required by the # project's libjpeg-turbo ExternalProject for SIMD-accelerated JPEG. # Update base and install toolchain + static-Qt build dependencies # (XCB/X11/OpenGL/EGL/DBus/fontconfig/freetype/zlib headers needed to build static Qt). # # arm64 is enabled as a second dpkg architecture here so this one image can also CROSS-COMPILE the # rugnux CLI for aarch64 (DGX Spark GB10 / Grace Hopper GH200 -- both arm64 SBSA). Noble's deb822 # ubuntu.sources carries no Architectures: field, so a bare `dpkg --add-architecture arm64` sends apt # to archive.ubuntu.com for arm64 indexes and 404s on every one; arm64 is published on # ports.ubuntu.com instead. Pin the stock entries to amd64 and add a ports entry for arm64. RUN set -eux; \ dpkg --add-architecture arm64; \ sed -i 's/^Components: main/Architectures: amd64\nComponents: main/' /etc/apt/sources.list.d/ubuntu.sources; \ printf '\nTypes: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: noble noble-updates noble-security\nComponents: main restricted universe multiverse\nArchitectures: arm64\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \ >> /etc/apt/sources.list.d/ubuntu.sources RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ ca-certificates \ curl \ wget \ git \ which \ tar \ xz-utils \ build-essential \ python3 \ python3-venv \ python3-requests \ python3.12 \ python3.12-venv \ perl \ pkg-config \ gdb \ file \ nasm \ dpkg-dev \ fakeroot \ libnuma-dev \ libkrb5-dev \ libxcb1-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev \ libxcursor-dev \ libxfixes-dev \ libxinerama-dev \ libxkbcommon-dev \ libxkbcommon-x11-dev \ libx11-xcb-dev \ libxcb-shape0-dev \ libxcb-sync-dev \ libxcb-xfixes0-dev \ libxcb-image0-dev \ libxcb-icccm4-dev \ libxcb-keysyms1-dev \ libxcb-render-util0-dev \ libxcb-util-dev \ libxcb-randr0-dev \ libxcb-xkb-dev \ libxcb-shm0-dev \ libxcb-cursor0 \ libxcb-cursor-dev \ libxcb-glx0-dev \ libgl1-mesa-dev \ libglx-dev \ libegl1-mesa-dev \ libexpat1-dev \ zlib1g-dev \ libfontconfig1-dev \ libdrm-dev \ libglvnd-dev \ libassimp-dev \ libfreetype6-dev; \ apt-get clean; \ rm -rf /var/lib/apt/lists/* # Git over HTTP/1.1: the HTTP/2 multiplexing used by default makes clones from some servers # (and through the PSI proxy) fail mid-transfer with "RPC failed; curl 92 HTTP/2 stream ... not # closed cleanly". Every source dependency below and the project's own FetchContent step clone over # HTTPS, so set this system-wide for the image. RUN git config --system http.version HTTP/1.1 # Use the default GCC/G++ (gcc-13 on Noble, supported by CUDA 13.3) ENV CC=/usr/bin/gcc ENV CXX=/usr/bin/g++ # Build a static OpenSSL # Everything built from source below is identical in all four build images, so it lives in # docker/common/ and is run from there -- one copy to change, not four. The build context is # docker/ (see build_images.sh), which is what puts common/ in reach of this COPY. ARG CMAKE_VERSION=3.31.8 ARG CMAKE_SHA256=630615d8e98ac33eba7fbe472626dff5c899c85af3c024585ae109166a6909d0 ARG NINJA_VERSION=1.13.2 ARG NINJA_SHA256=5749cbc4e668273514150a80e387a957f933c6ed3f5f11e03fb30955e2bbead6 COPY common/ /opt/jfjoch-common/ RUN /opt/jfjoch-common/install-cmake.sh RUN /opt/jfjoch-common/install-ninja.sh # Ahead of the distro path: these are the CMake and Ninja every later step and every CI build uses. ENV PATH=/opt/cmake-${CMAKE_VERSION}/bin:/opt/ninja-${NINJA_VERSION}/bin:${PATH} RUN /opt/jfjoch-common/build-openssl.sh # Expose static OpenSSL to CMake/pkg-config ENV OPENSSL_ROOT_DIR=/opt/openssl-${OPENSSL_VERSION} ENV PKG_CONFIG_PATH=${OPENSSL_ROOT_DIR}/lib/pkgconfig:${OPENSSL_ROOT_DIR}/lib64/pkgconfig # Install Node.js (NodeSource) RUN set -eux; \ curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash -; \ apt-get update; \ apt-get install -y --no-install-recommends nodejs; \ apt-get clean; \ rm -rf /var/lib/apt/lists/*; \ node --version; npm --version; (corepack enable || true) # Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime. # A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and # libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so # that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control # D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the # daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build # finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus # installs, which imports libdbus-1.a). Built -fPIC (--with-pic) so the archive links into Qt's PIE # tools (qdbusxml2cpp). expat is only a configure-time dep of the dbus daemon; the client libdbus-1 # links neither expat nor systemd. RUN /opt/jfjoch-common/build-dbus.sh # Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH} # Build and install static Qt with Core, Gui, Widgets, Charts, DBus ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static RUN /opt/jfjoch-common/build-qt.sh # Eigen 3.4 (header-only) -- external find_package(Eigen3 3.4) dependency, installed to /opt/eigen-3.4. RUN /opt/jfjoch-common/install-eigen.sh # Make Qt, the static libdbus, and Eigen discoverable by CMake. The static libdbus prefix is # required here (not only at Qt build time): every Qt6::DBus consumer re-runs find_package(DBus1) # through Qt's exported config, so DBus1Config.cmake must be on CMAKE_PREFIX_PATH for the viewer build. ENV CMAKE_PREFIX_PATH=/opt/qt-${QT_VERSION}-static:/opt/dbus-${DBUS_VERSION}-static:/opt/eigen-3.4 # --------------------------------------------------------------------------------------------- # aarch64 cross-compilation support (rugnux only -- the viewer is not cross-built). # # crossbuild-essential-arm64 the aarch64 gcc/g++. # qemu-user-static HDF5 runs two try_run() probes (config/ConfigureChecks.cmake) that # need CMAKE_CROSSCOMPILING_EMULATOR. libzmq guards its own run-checks # with NOT CMAKE_CROSSCOMPILING; Ceres, libtiff, zstd, Catch2, spdlog, # cpp-httplib, FFTW and ffbidx have no run-checks at all. # binutils-aarch64-linux-gnu reading aarch64 ELF on the build host. # :arm64 libraries ZLIB is one of the project's two external dependencies (Eigen, the # other, is header-only and installed above); OpenSSL is needed by the # libcurl the build fetches. # --------------------------------------------------------------------------------------------- RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ crossbuild-essential-arm64 binutils-aarch64-linux-gnu qemu-user-static \ zlib1g-dev:arm64 libssl-dev:arm64; \ apt-get clean; \ rm -rf /var/lib/apt/lists/* # CUDA cross target tree -> /usr/local/cuda/targets/sbsa-linux, beside the image's x86_64 tree. # These packages are NOT in the x86_64 CUDA repo (it publishes none) and NOT in the sbsa repo (that # is the NATIVE arm64 one a Spark or GH200 installs locally). They have their own repo and keyring: # repos/ubuntu2404/cross-linux-sbsa/ # repos/ubuntu2404/cross-linux-aarch64/ also exists -- that is the Tegra/Jetson tree, not this one. RUN set -eux; \ cd /tmp; \ wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/cross-linux-sbsa/cuda-keyring_1.1-1_all.deb; \ dpkg -i cuda-keyring_1.1-1_all.deb; rm cuda-keyring_1.1-1_all.deb; \ apt-get update; \ V=$(nvcc --version | sed -nE 's/.*release ([0-9]+)\.([0-9]+).*/\1-\2/p'); \ apt-get install -y --no-install-recommends \ cuda-cudart-cross-sbsa-$V cuda-crt-cross-sbsa-$V \ cuda-culibos-cross-sbsa-$V libcufft-cross-sbsa-$V; \ test -f /usr/local/cuda/targets/sbsa-linux/lib/libcufft_static.a; \ apt-get clean; \ rm -rf /var/lib/apt/lists/* # aarch64-sbsa.cmake is deliberately NOT copied in: the build passes it from the checkout, so the # toolchain is versioned with the source it configures and needs no image rebuild to change. # Set workdir for your project WORKDIR /workspace # Default entrypoint: interactive shell CMD ["/bin/bash", "-l"] RUN rm -rf /opt/jfjoch-common