Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions bindist/Dockerfile
Original file line number Diff line number Diff line change
@@ -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 /
170 changes: 170 additions & 0 deletions bindist/install.sh
Original file line number Diff line number Diff line change
@@ -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