blob: 65179ef2299752d65c377d2c979d2d4a0f36cab9 [file] [log] [blame]
#!/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="654e9c3794273b481284d8bafecfc74c7ffd643d"
PI_COMMIT="8051d54c9c3415ca800db232a226189fd17ad60a"
P4C_COMMIT="adce375fd961a9e467c7e77ad1bef647ef28e5e8"
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
#FIXME the following two lines seem like they are not required, at least for 16.04
sudo apt install -y python-software-properties software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt update
#FIXME 14.04 needs special gcc, 16.04 can use apt-get default
sudo apt install -y --no-install-recommends \
autoconf \
automake \
bison \
build-essential \
cmake \
cpp \
curl \
dpkg-dev \
flex \
g++-4.9 \
gcc-4.9 \
git \
libboost-dev \
libboost-filesystem-dev \
libboost-iostreams-dev \
libboost-program-options-dev \
libboost-system-dev \
libboost-test-dev \
libboost-thread-dev \
libc6-dev \
libevent-dev \
libffi-dev \
libfl-dev \
libgc-dev \
libgc1c2 \
libgflags-dev \
libgmp-dev \
libgmp10 \
libgmpxx4ldbl \
libjudy-dev \
libpcap-dev \
libreadline6 \
libreadline6-dev \
libssl-dev \
libtool \
make \
mktemp \
pkg-config \
python \
python-dev \
python-ipaddr \
python-pip \
python-scapy \
tcpdump \
wget \
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 {
cd ${BUILD_DIR}
if [ ! -d protobuf ]; then
git clone https://github.com/google/protobuf.git
fi
cd protobuf
git fetch
git checkout ${PROTOBUF_COMMIT}
export CFLAGS="-Os"
export CXXFLAGS="-Os"
export LDFLAGS="-Wl,-s"
./autogen.sh
./configure --prefix=/usr
make -j${NUM_CORES}
sudo make install
sudo ldconfig
unset CFLAGS CXXFLAGS LDFLAGS
}
function do_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
export LDFLAGS="-Wl,-s"
make -j${NUM_CORES}
sudo make install
sudo ldconfig
unset LDFLAGS
}
function do_p4runtime {
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-proto --without-cli --without-internal-rpc
make -j${NUM_CORES}
sudo make install
sudo ldconfig
}
function do_bmv2 {
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}
./autogen.sh
# FIXME: to build with debugger, we need to install nanomsg first (see bmv2's install_deps.sh)
./configure --without-thrift --without-nanomsg --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 {
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
}
# FIXME: Can we deprecate this?
function do_p4c_bm {
# 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
#FIXME need version check for 14.04 vs 16.04
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 ${PI_COMMIT} p4runtime do_p4runtime
check_and_do ${BMV2_COMMIT} bmv2 do_bmv2
check_and_do ${P4C_COMMIT} p4c do_p4c
check_and_do ${P4C_BM_COMMIT} p4c-bmv2 do_p4c_bm
echo "Done!"