#!/usr/bin/env bash # ----------------------------------------------------------------------------- # Builds and installs all tools needed for developing and testing P4 support in # ONOS. # # Tested on Ubuntu 14.04. # # Recommended minimum system requirements: # 4 GB of RAM # 2 cores # 8 GB free hard drive space (~4 GB to build everything) # ----------------------------------------------------------------------------- # Exit on errors. set -e BUILD_DIR=~/p4tools BMV2_COMMIT="487ee8f907153d93d4806f3e9e209ed9cb668c2b" PI_COMMIT="d7418b386e2301f82c1330a1d2dca131ef7b4fe3" P4C_COMMIT="80db63762314494b313f39c40067b3d3416007d3" P4C_BM_COMMIT="8f4abeaa6f8374aaf95ea2aacfc2b750069391b5" PROTOBUF_COMMIT="tags/v3.0.2" GRPC_COMMIT="tags/v1.3.0" NUM_CORES=`grep -c ^processor /proc/cpuinfo` function do_requirements { sudo apt update sudo apt install -y python-software-properties software-properties-common sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install -y \ autoconf \ automake \ bison \ curl \ dpkg-dev \ flex \ g++-4.9 \ gcc-4.9 \ git \ libboost-dev \ libboost-iostreams-dev \ libfl-dev \ libgc-dev \ libgmp-dev \ libreadline6 \ libreadline6-dev \ libtool \ libc6-dev \ make \ pkg-config \ python \ python-ipaddr \ python-scapy \ tcpdump \ unzip # Needed for p4c. sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50 } function do_protobuf { # Protobuf cd ${BUILD_DIR} if [ ! -d protobuf ]; then git clone https://github.com/google/protobuf.git fi cd protobuf git fetch git checkout ${PROTOBUF_COMMIT} ./autogen.sh ./configure --prefix=/usr make -j${NUM_CORES} sudo make install sudo ldconfig } function do_grpc { # gRPC cd ${BUILD_DIR} if [ ! -d grpc ]; then git clone https://github.com/grpc/grpc.git fi cd grpc git fetch git checkout ${GRPC_COMMIT} git submodule update --init make -j${NUM_CORES} sudo make install sudo ldconfig } function do_bmv2 { # BMv2 part 1 (without PI) cd ${BUILD_DIR} if [ ! -d bmv2 ]; then git clone https://github.com/p4lang/behavioral-model.git bmv2 fi cd bmv2 git fetch git checkout ${BMV2_COMMIT} ./install_deps.sh ./autogen.sh ./configure --enable-debugger make -j${NUM_CORES} sudo make install sudo ldconfig } function do_p4runtime { # P4Runtime (PI) cd ${BUILD_DIR} if [ ! -d p4runtime ]; then git clone https://github.com/p4lang/PI.git p4runtime fi cd p4runtime git fetch git checkout ${PI_COMMIT} git submodule update --init --recursive ./autogen.sh ./configure --with-bmv2 --with-proto make -j${NUM_CORES} sudo make install sudo ldconfig } function do_bmv2_with_pi { # BMv2 part 2 (with PI) cd ${BUILD_DIR}/bmv2 ./configure --enable-debugger --with-pi make -j${NUM_CORES} sudo make install sudo ldconfig # Simple_switch_grpc target cd targets/simple_switch_grpc ./autogen.sh ./configure make -j${NUM_CORES} sudo make install sudo ldconfig } function do_p4c { # p4c cd ${BUILD_DIR} if [ ! -d p4c ]; then git clone https://github.com/p4lang/p4c.git fi cd p4c git fetch git checkout ${P4C_COMMIT} git submodule update --init --recursive ./bootstrap.sh cd build make -j${NUM_CORES} sudo make install sudo ldconfig } function do_p4c_bm { # p4c-bmv2 (old BMv2 compiler) cd ${BUILD_DIR} if [ ! -d p4c-bmv2 ]; then git clone https://github.com/p4lang/p4c-bm.git p4c-bmv2 fi cd p4c-bmv2 git fetch git checkout ${P4C_BM_COMMIT} sudo pip install -r requirements.txt sudo python setup.py install } function check_commit { if [ ! -e $2 ]; then return 0 # true fi if [[ $(< $2) != "$1" ]]; then return 0 # true fi return 1 # false } MUST_DO_ALL=false DID_REQUIREMENTS=false function check_and_do { # Check if the latest built commit is the same we are trying to build now, or if all projects # must be built. If true builds this project. commit_id="$1" proj_dir="$2" func_name="$3" if ${MUST_DO_ALL} = true || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then echo "#" echo "# Building ${proj_dir} (${commit_id})" echo "#" if ! ${DID_REQUIREMENTS} = true; then do_requirements DID_REQUIREMENTS=true fi eval ${func_name} echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit # Build all next projects as they might depend on this one. MUST_DO_ALL=true else echo "${proj_dir} is up to date (commit ${commit_id})" fi } mkdir -p ${BUILD_DIR} cd ${BUILD_DIR} # In dependency order. check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf check_and_do ${GRPC_COMMIT} grpc do_grpc check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 check_and_do ${PI_COMMIT} p4runtime do_p4runtime check_and_do ${BMV2_COMMIT} bmv2 do_bmv2_with_pi check_and_do ${P4C_COMMIT} p4c do_p4c check_and_do ${P4C_BM_COMMIT} p4c-bmv2 do_p4c_bm echo "Done!"