diff --git a/bindist/Dockerfile b/bindist/Dockerfile new file mode 100644 index 00000000..628bd86b --- /dev/null +++ b/bindist/Dockerfile @@ -0,0 +1,136 @@ +FROM ubuntu:24.04 AS builder + +ARG DEBIAN_FRONTEND=noninteractive +ARG BEHAVIORAL_MODEL_VERSION=main +ARG PI_VERSION=main +ARG P4C_VERSION=main + +# Step 1: Install all build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf automake bison build-essential clang cmake curl flex g++ git \ + libboost-dev libboost-filesystem-dev libboost-graph-dev \ + libboost-iostreams-dev libboost-program-options-dev libboost-system-dev \ + libboost-test-dev libboost-thread-dev libbz2-dev libevent-dev libffi-dev \ + libfl-dev libgc-dev libgflags-dev libgmp-dev libgrpc++-dev libgrpc-dev \ + libelf-dev liblzma-dev libpcap-dev libprotobuf-dev libreadline-dev \ + libssl-dev libtool libtool-bin llvm make net-tools patchelf pkg-config \ + protobuf-compiler protobuf-compiler-grpc python3-dev python3-pip \ + python3-venv tcpdump unzip valgrind wget \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /build + +# Step 2: Build Thrift 0.16.0 +RUN git clone --depth 1 --branch v0.16.0 https://github.com/apache/thrift.git thrift-0.16.0 \ + && cd thrift-0.16.0 \ + && ./bootstrap.sh \ + && ./configure --with-cpp --with-python --without-java --without-ruby \ + --without-nodejs --without-go --without-erlang --without-lua \ + --without-php --without-swift --without-rs --without-dotnetcore \ + --without-haskell --without-perl --without-c_glib --without-d \ + --without-qt5 \ + && make -j$(nproc) \ + && make install \ + && cd /build && rm -rf thrift-0.16.0 + +# Step 3: Build nanomsg 1.0.0 +RUN git clone --depth 1 --branch 1.0.0 https://github.com/nanomsg/nanomsg.git nanomsg-1.0.0 \ + && cd nanomsg-1.0.0 \ + && mkdir build && cd build \ + && cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \ + && make -j$(nproc) \ + && make install \ + && cd /build && rm -rf nanomsg-1.0.0 + +RUN ldconfig + +# Step 5: Build PI +RUN git clone https://github.com/p4lang/PI.git \ + && cd PI \ + && if [ "$PI_VERSION" != "main" ]; then git checkout $PI_VERSION; fi \ + && git submodule update --init --recursive \ + && ./autogen.sh \ + && ./configure --with-proto --without-internal-rpc --without-cli --without-bmv2 \ + && make -j$(nproc) \ + && make install \ + && cd /build && rm -rf PI + +RUN ldconfig + +# Step 6: Build behavioral-model +# Patches are from vm-ubuntu-24.04/patches/ in the tutorials repo. +# Build context must be set to the tutorials/ root: +# docker build -f bindist/Dockerfile -t p4-bindist . +COPY vm-ubuntu-24.04/patches/behavioral-model-support-fedora.patch /build/patches/ +COPY vm-ubuntu-24.04/patches/behavioral-model-support-venv.patch /build/patches/ +RUN git clone https://github.com/p4lang/behavioral-model.git \ + && cd behavioral-model \ + && if [ "$BEHAVIORAL_MODEL_VERSION" != "main" ]; then git checkout $BEHAVIORAL_MODEL_VERSION; fi \ + && git submodule update --init --recursive \ + && patch -p1 < /build/patches/behavioral-model-support-fedora.patch \ + && patch -p1 < /build/patches/behavioral-model-support-venv.patch \ + && ./autogen.sh \ + && ./configure --with-pi --with-thrift --enable-debugger \ + && make -j$(nproc) \ + && make install-strip \ + && cd /build && rm -rf behavioral-model + +RUN ldconfig + +# Step 7: Build p4c with static linking +RUN git clone --recurse-submodules https://github.com/p4lang/p4c.git \ + && cd p4c \ + && if [ "$P4C_VERSION" != "main" ]; then git checkout $P4C_VERSION && git submodule update --init --recursive; fi \ + && mkdir build && cd build \ + && cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DSTATIC_BUILD_WITH_DYNAMIC_GLIBC=ON \ + -DENABLE_TEST_TOOLS=OFF \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + && make -j$(nproc) \ + && make install \ + && cd /build && rm -rf p4c + +# Step 8: Collect artifacts into bindist +RUN mkdir -p /build/bindist/p4-bindist-ubuntu2404-x86_64/bin \ + && mkdir -p /build/bindist/p4-bindist-ubuntu2404-x86_64/lib \ + && mkdir -p /build/bindist/p4-bindist-ubuntu2404-x86_64/share + +# Copy p4c binaries +RUN for bin in p4c p4c-bm2-ss p4c-bm2-psa p4c-bm2-pna p4c-dpdk p4c-ebpf \ + p4c-ubpf p4c-pna-p4tc p4c-graphs p4test; do \ + cp /usr/local/bin/$bin /build/bindist/p4-bindist-ubuntu2404-x86_64/bin/ 2>/dev/null || true; \ + done + +# Copy behavioral-model binaries +RUN cp /usr/local/bin/simple_switch /build/bindist/p4-bindist-ubuntu2404-x86_64/bin/ \ + && cp /usr/local/bin/simple_switch_grpc /build/bindist/p4-bindist-ubuntu2404-x86_64/bin/ \ + && cp /usr/local/bin/simple_switch_CLI /build/bindist/p4-bindist-ubuntu2404-x86_64/bin/ + +# Copy bundled shared libraries (not available via apt on Ubuntu 24.04) +RUN cp -a /usr/local/lib/libthrift*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ \ + && cp -a /usr/local/lib/libnanomsg*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ \ + && cp -a /usr/local/lib/libpi*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ \ + && cp -a /usr/local/lib/libbm*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ \ + && cp -a /usr/local/lib/libsimpleswitch*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ \ + && cp -a /usr/local/lib/libruntimestubs*.so* /build/bindist/p4-bindist-ubuntu2404-x86_64/lib/ + +# Copy p4c share files +RUN cp -r /usr/local/share/p4c /build/bindist/p4-bindist-ubuntu2404-x86_64/share/ + +# Fix RPATHs on behavioral-model binaries +RUN for bin in simple_switch simple_switch_grpc; do \ + patchelf --set-rpath '$ORIGIN/../lib' /build/bindist/p4-bindist-ubuntu2404-x86_64/bin/$bin; \ + done + +# Copy install script +COPY bindist/install.sh /build/bindist/p4-bindist-ubuntu2404-x86_64/install.sh +RUN chmod +x /build/bindist/p4-bindist-ubuntu2404-x86_64/install.sh + +# Create the tarball +RUN cd /build/bindist \ + && tar czf p4-bindist-ubuntu2404-x86_64.tar.gz p4-bindist-ubuntu2404-x86_64/ + +# Final stage: just the tarball +FROM scratch +COPY --from=builder /build/bindist/p4-bindist-ubuntu2404-x86_64.tar.gz / diff --git a/bindist/install.sh b/bindist/install.sh new file mode 100644 index 00000000..f58b6bae --- /dev/null +++ b/bindist/install.sh @@ -0,0 +1,170 @@ +#!/bin/bash +# install.sh - Install script for p4-bindist (P4 binary distribution) +# Target: Ubuntu 24.04 x86_64 +# +# Usage: +# sudo ./install.sh # Install to /usr/local (default) +# sudo ./install.sh --prefix /opt/p4 # Install to custom prefix +# sudo ./install.sh --uninstall # Remove installed files + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PREFIX="/usr/local" +UNINSTALL=0 + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --prefix) + PREFIX="$2" + shift 2 + ;; + --uninstall) + UNINSTALL=1 + shift + ;; + --help) + echo "Usage: $0 [--prefix /path] [--uninstall]" + echo "" + echo "Options:" + echo " --prefix PATH Install to PATH (default: /usr/local)" + echo " --uninstall Remove previously installed files" + echo " --help Show this help" + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Run '$0 --help' for usage." + exit 1 + ;; + esac +done + +# Check we're running on Ubuntu 24.04 +check_os() { + if [ -f /etc/os-release ]; then + . /etc/os-release + if [ "$ID" != "ubuntu" ] || [ "$VERSION_ID" != "24.04" ]; then + echo "WARNING: This bindist was built for Ubuntu 24.04." + echo "Detected: $ID $VERSION_ID" + echo "It may not work correctly on this system." + read -p "Continue anyway? [y/N] " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + fi + fi +} + +# Runtime apt dependencies that the p4c compiler and BMv2 binaries need. +# These are standard Ubuntu 24.04 packages. +RUNTIME_DEPS=( + cpp + python3 + patchelf + libboost-filesystem1.83.0 + libboost-program-options1.83.0 + libboost-thread1.83.0 + libgmp10 + libpcap0.8t64 + libprotobuf32t64 + libgrpc++1.51t64 + libgrpc29t64 + libabsl20220623t64 + libre2-10 + libcares2 +) + +install_runtime_deps() { + echo "Installing runtime dependencies via apt..." + apt-get update -qq + apt-get install -y --no-install-recommends "${RUNTIME_DEPS[@]}" + echo "Runtime dependencies installed." +} + +do_install() { + echo "Installing p4-bindist to ${PREFIX}..." + + # Create directories + mkdir -p "${PREFIX}/bin" + mkdir -p "${PREFIX}/lib/p4-bindist" + mkdir -p "${PREFIX}/share/p4c" + + # Copy binaries + cp -f "${SCRIPT_DIR}/bin/"* "${PREFIX}/bin/" + + # Copy bundled shared libraries to a dedicated directory (preserve symlinks) + cp -a "${SCRIPT_DIR}/lib/"* "${PREFIX}/lib/p4-bindist/" + + # Copy share files + cp -rf "${SCRIPT_DIR}/share/p4c/"* "${PREFIX}/share/p4c/" + + # Fix RPATHs to point to the actual install location + for bin in simple_switch simple_switch_grpc; do + if [ -f "${PREFIX}/bin/${bin}" ]; then + patchelf --set-rpath "${PREFIX}/lib/p4-bindist" "${PREFIX}/bin/${bin}" 2>/dev/null || true + fi + done + + # Update linker cache + echo "${PREFIX}/lib/p4-bindist" > /etc/ld.so.conf.d/p4-bindist.conf + ldconfig + + # Save install manifest for uninstall + MANIFEST="${PREFIX}/share/p4c/.p4-bindist-manifest" + echo "${PREFIX}" > "${MANIFEST}" + + echo "" + echo "Installation complete!" + echo "" + echo "Installed binaries:" + echo " p4c - P4 compiler driver" + echo " p4c-bm2-ss - P4 compiler for BMv2 simple_switch" + echo " simple_switch - BMv2 software switch" + echo " simple_switch_grpc - BMv2 software switch with gRPC" + echo " simple_switch_CLI - CLI for simple_switch" + echo "" + echo "Verify with:" + echo " p4c --version" + echo " simple_switch_grpc --version" +} + +do_uninstall() { + echo "Uninstalling p4-bindist from ${PREFIX}..." + + # Remove binaries + for bin in p4c p4c-bm2-ss p4c-bm2-psa p4c-bm2-pna p4c-dpdk p4c-ebpf \ + p4c-ubpf p4c-pna-p4tc p4c-graphs p4test \ + simple_switch simple_switch_grpc simple_switch_CLI; do + rm -f "${PREFIX}/bin/${bin}" + done + + # Remove bundled libraries + rm -rf "${PREFIX}/lib/p4-bindist" + + # Remove share files + rm -rf "${PREFIX}/share/p4c" + + # Remove linker config + rm -f /etc/ld.so.conf.d/p4-bindist.conf + ldconfig + + echo "Uninstall complete." +} + +# Check for root +if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root (use sudo)." + exit 1 +fi + +check_os + +if [ "$UNINSTALL" -eq 1 ]; then + do_uninstall +else + install_runtime_deps + do_install +fi