# Development environment for webserv. # # Target platform is Linux, because that is what the Codam VMs run and what the # official testers are built for. The base is Ubuntu 22.04, the same release # those VMs run, so this image is that environment rather than something close # to it. A newer base would be the permissive side of the difference: its glibc # accepts everything the older one does and more, so code that cannot run at # school would still build clean here. On 24.04 a plain std::strtoul compiles # into a call to __isoc23_strtoul, a GLIBC_2.38 symbol that 22.04 does not have, # at every -std= and not only at C++23. # # 22.04 ships neither compiler this project needs, so two repositories are # added: ubuntu-toolchain-r/test for g++ 14, apt.llvm.org for clang 18. Both # publish builds made for 22.04, which is what keeps the produced binary # runnable there. # # libc++ is installed alongside libstdc++ for one specific reason: clang 18 # reports __cpp_concepts as 201907, and libstdc++ gates on 202002L, # so clang + libstdc++ compiles "#include " into nothing at all. The # control build with clang — a second opinion on warnings, and the sanitizers — # would die on the first function returning Result. "make check-clang" passes # -stdlib=libc++ for exactly this. FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ gnupg \ wget \ lsb-release \ software-properties-common \ && add-apt-repository -y ppa:ubuntu-toolchain-r/test \ && wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key \ | gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg \ && echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg]" \ "http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" \ > /etc/apt/sources.list.d/llvm.list \ && apt-get update RUN apt-get install -y --no-install-recommends \ build-essential \ g++-14 \ clang-18 \ clang-tidy-18 \ clang-format-18 \ libc++-18-dev \ libc++abi-18-dev \ libclang-rt-18-dev \ gdb \ valgrind \ strace \ make \ git \ curl \ siege \ python3 \ python3-pip \ net-tools \ iproute2 \ procps \ less \ vim \ && rm -rf /var/lib/apt/lists/* # Make the versioned tools the defaults, so "c++", "g++", "clang++", # "clang-tidy" and "clang-format" all point at something that understands C++23. # Without the last two the Makefile would have to hardcode Ubuntu's versioned # names, which are wrong everywhere else — Codam included. RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100 \ && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 \ && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-18 100 \ && update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-14 100 \ && update-alternatives --install /usr/bin/clang-tidy clang-tidy \ /usr/bin/clang-tidy-18 100 \ && update-alternatives --install /usr/bin/clang-format clang-format \ /usr/bin/clang-format-18 100 # Run as a normal user whose uid/gid match the host account, so files created # inside the container (object files, uploads, test output) do not end up owned # by root on the macOS side of the bind mount. ARG UID=1000 ARG GID=1000 RUN if getent passwd ${UID} >/dev/null; then userdel -r "$(getent passwd ${UID} | cut -d: -f1)"; fi \ && groupadd -g ${GID} dev 2>/dev/null || true \ && useradd -m -u ${UID} -g ${GID} -s /bin/bash dev USER dev WORKDIR /webserv CMD ["/bin/bash"]