blob: 774e007ca3f0c09d523bebce791875d51a4829a2 [file] [log] [blame]
Carmelo Casconeb7e618d2018-01-12 18:31:33 -08001#!/usr/bin/env bash
2# -----------------------------------------------------------------------------
3# Builds and installs all tools needed for developing and testing P4 support in
4# ONOS.
5#
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -08006# Tested on 16.04 and 18.04.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -08007#
8# Recommended minimum system requirements:
9# 4 GB of RAM
10# 2 cores
11# 8 GB free hard drive space (~4 GB to build everything)
Carmelo Cascone95e5afd2018-07-17 14:45:23 +020012#
13# To execute up to a given step, pass the step name as the first argument. For
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -080014# example, to install PI, but not bmv2, p4c, etc:
Carmelo Cascone95e5afd2018-07-17 14:45:23 +020015# ./install-p4-tools.sh PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080016# -----------------------------------------------------------------------------
17
18# Exit on errors.
19set -e
20
21BUILD_DIR=~/p4tools
Esin Karaman971fb7f2017-12-28 13:44:52 +000022# in case BMV2_COMMIT value is updated, the same variable in
23# protocols/bmv2/thrift-api/BUCK file should also be updated
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -080024BMV2_COMMIT="9c8ab62d5680044b94aa2e37b6989f386cc7ae7c"
Carmelo Casconee45902b2018-12-18 13:30:45 -080025PI_COMMIT="a95222eca9b039f6398c048d7e1a1bf7f49b7235"
26P4C_COMMIT="264da2c524c849df0d9ba478cdd1d61b29d64722"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080027PROTOBUF_COMMIT="tags/v3.2.0"
28GRPC_COMMIT="tags/v1.3.2"
29LIBYANG_COMMIT="v0.14-r1"
30SYSREPO_COMMIT="v0.7.2"
31
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -080032set -x
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080033NUM_CORES=`grep -c ^processor /proc/cpuinfo`
Carmelo Casconef02872d2018-06-20 08:49:02 +020034# If false, build tools without debug features to improve throughput of BMv2 and
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -070035# reduce CPU/memory footprint. Default is true.
Carmelo Casconef02872d2018-06-20 08:49:02 +020036DEBUG_FLAGS=${DEBUG_FLAGS:-true}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +020037# Execute up to the given step (first argument), or all if not defined.
38LAST_STEP=${1:-all}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -080039# PI and BMv2 must be configured differently if we want to use Stratum
40USE_STRATUM=${USE_STRATUM:-false}
41# Improve time for one-time builds
42FAST_BUILD=${FAST_BUILD:-false}
43# Remove build artifacts
44CLEAN_UP=${CLEAN_UP:-false}
45BMV2_INSTALL=/usr/local
46set +x
Carmelo Cascone95e5afd2018-07-17 14:45:23 +020047
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080048function do_requirements {
49 sudo apt update
50 sudo apt-get install -y --no-install-recommends \
51 autoconf \
52 automake \
53 bison \
54 build-essential \
55 cmake \
56 cpp \
57 curl \
58 flex \
59 git \
Carmelo Casconeb5324e72018-11-25 02:26:32 -080060 graphviz \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080061 libavl-dev \
62 libboost-dev \
Carmelo Casconeb5324e72018-11-25 02:26:32 -080063 libboost-graph-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080064 libboost-program-options-dev \
65 libboost-system-dev \
66 libboost-filesystem-dev \
67 libboost-thread-dev \
68 libboost-filesystem-dev \
69 libboost-program-options-dev \
70 libboost-system-dev \
71 libboost-test-dev \
72 libboost-thread-dev \
73 libc6-dev \
74 libev-dev \
75 libevent-dev \
76 libffi-dev \
77 libfl-dev \
78 libgc-dev \
79 libgc1c2 \
80 libgflags-dev \
81 libgmp-dev \
82 libgmp10 \
83 libgmpxx4ldbl \
84 libjudy-dev \
85 libpcap-dev \
86 libpcre3-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080087 libssl-dev \
88 libtool \
89 make \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080090 pkg-config \
91 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070092 python2.7 \
93 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080094 tcpdump \
95 wget \
96 unzip
97
Charles Chan87dc82e2018-08-05 16:27:10 -070098 sudo -H pip install setuptools cffi ipaddr ipaddress pypcap
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080099}
100
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800101function do_requirements_1604 {
102 sudo apt-get update
103 sudo apt-get install -y --no-install-recommends \
104 ca-certificates \
105 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800106 libboost-iostreams1.58-dev \
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900107 libprotobuf-c-dev \
108 libreadline6 \
109 libreadline6-dev \
110 mktemp
111}
112
113function do_requirements_1804 {
114 sudo apt-get update
115 sudo apt-get install -y --no-install-recommends \
116 ca-certificates \
117 g++ \
118 libboost1.65-dev \
119 libboost-regex1.65-dev \
120 libboost-iostreams1.65-dev \
121 libreadline-dev \
122 libssl1.0-dev \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800123 libprotobuf-c-dev
124}
125
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800126function do_protobuf {
127 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800128 if [[ ! -d protobuf ]]; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800129 git clone https://github.com/google/protobuf.git
130 fi
131 cd protobuf
132 git fetch
133 git checkout ${PROTOBUF_COMMIT}
134
135 export CFLAGS="-Os"
136 export CXXFLAGS="-Os"
137 export LDFLAGS="-Wl,-s"
138 ./autogen.sh
139 ./configure --prefix=/usr
140 make -j${NUM_CORES}
141 sudo make install
142 sudo ldconfig
143 unset CFLAGS CXXFLAGS LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200144
145 cd python
146 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800147}
148
149function do_grpc {
150 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800151 if [[ ! -d grpc ]]; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800152 git clone https://github.com/grpc/grpc.git
153 fi
154 cd grpc
155 git fetch
156 git checkout ${GRPC_COMMIT}
157 git submodule update --init
158
159 export LDFLAGS="-Wl,-s"
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900160 RELEASE=`lsb_release -rs`
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800161 if version_ge ${RELEASE} 18.04; then
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900162 # Ubuntu 18.04 ships OpenSSL 1.1 by default, which has breaking changes in the API.
163 # Here, we will build grpc with OpenSSL 1.0.
164 # (Reference: https://github.com/grpc/grpc/issues/10589)
165 # Also, set CFLAGS to avoid compilcation error caused by gcc7.
166 # (Reference: https://github.com/grpc/grpc/issues/13854)
167 PKG_CONFIG_PATH=/usr/lib/openssl-1.0/pkgconfig make -j${NUM_CORES} CFLAGS='-Wno-error'
168 else
169 make -j${NUM_CORES}
170 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800171 sudo make install
172 sudo ldconfig
173 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200174
175 sudo pip install -r requirements.txt
176 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800177}
178
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800179function checkout_bmv2 {
180 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800181 if [[ ! -d bmv2 ]]; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800182 git clone https://github.com/p4lang/behavioral-model.git bmv2
183 fi
184 cd bmv2
185 git fetch
186 git checkout ${BMV2_COMMIT}
187}
188
189function do_pi_bmv2_deps {
190 checkout_bmv2
191 # From bmv2's install_deps.sh.
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200192 # Nanomsg is required also by PI.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800193 tmpdir=`mktemp -d -p .`
194 cd ${tmpdir}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800195 if [[ "${USE_STRATUM}" = false ]] ; then
196 bash ../travis/install-thrift.sh
197 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800198 sudo ldconfig
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800199 cd ..
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800200 sudo rm -rf ${tmpdir}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800201}
202
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200203function do_PI {
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800204 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800205 if [[ ! -d PI ]]; then
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200206 git clone https://github.com/p4lang/PI.git
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800207 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200208 cd PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800209 git fetch
210 git checkout ${PI_COMMIT}
211 git submodule update --init --recursive
212
213 ./autogen.sh
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800214 if [[ "${USE_STRATUM}" = false ]] ; then
215 ./configure --with-proto --without-internal-rpc --without-cli
216 else
217 # Configure for Stratum
218 ./configure --without-bmv2 --without-proto --without-fe-cpp --without-cli --without-internal-rpc --prefix=${BMV2_INSTALL}
219 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800220 make -j${NUM_CORES}
221 sudo make install
222 sudo ldconfig
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800223}
224
225function do_bmv2 {
226 checkout_bmv2
227
228 ./autogen.sh
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800229
230 confOpts="--with-pi --disable-elogger --without-nanomsg --without-targets"
231 if [[ "${FAST_BUILD}" = true ]] ; then
232 confOpts="${confOpts} --disable-dependency-tracking"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200233 fi
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800234 if [[ "${DEBUG_FLAGS}" = false ]] ; then
235 confOpts="${confOpts} --disable-logging-macros"
236 fi
237 if [[ "${USE_STRATUM}" = true ]] ; then
238 confOpts="CPPFLAGS=\"-isystem${BMV2_INSTALL}/include\" --prefix=${BMV2_INSTALL} --without-thrift ${confOpts}"
239 fi
240 confCmd="./configure ${confOpts}"
241 eval ${confCmd}
242
243 make -j${NUM_CORES}
244 sudo make install
245 cd targets/simple_switch
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800246 make -j${NUM_CORES}
247 sudo make install
248 sudo ldconfig
249
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800250 if [[ "${USE_STRATUM}" = false ]] ; then
251 # Simple_switch_grpc target (not using Stratum)
252 cd targets/simple_switch_grpc
253 ./autogen.sh
254 ./configure --with-thrift
255 make -j${NUM_CORES}
256 sudo make install
257 sudo ldconfig
258 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800259}
260
261function do_p4c {
262 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800263 if [[ ! -d p4c ]]; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800264 git clone https://github.com/p4lang/p4c.git
265 fi
266 cd p4c
267 git fetch
268 git checkout ${P4C_COMMIT}
269 git submodule update --init --recursive
270
271 mkdir -p build
272 cd build
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700273 cmake .. -DENABLE_EBPF=OFF
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800274 make -j${NUM_CORES}
275 sudo make install
276 sudo ldconfig
277}
278
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200279function do_scapy-vxlan {
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800280 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800281 if [[ ! -d scapy-vxlan ]]; then
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200282 git clone https://github.com/p4lang/scapy-vxlan.git
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800283 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200284 cd scapy-vxlan
285
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800286 git pull origin master
287
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200288 sudo python setup.py install
289}
290
291function do_ptf {
292 cd ${BUILD_DIR}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800293 if [[ ! -d ptf ]]; then
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200294 git clone https://github.com/p4lang/ptf.git
295 fi
296 cd ptf
297 git pull origin master
298
299 sudo python setup.py install
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800300}
301
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800302function check_commit {
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800303 if [[ ! -e $2 ]]; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800304 return 0 # true
305 fi
306 if [[ $(< $2) != "$1" ]]; then
307 return 0 # true
308 fi
309 return 1 # false
310}
311
312# The following is borrowed from Mininet's util/install.sh
313function version_ge {
314 # sort -V sorts by *version number*
315 latest=`printf "$1\n$2" | sort -V | tail -1`
316 # If $1 is latest version, then $1 >= $2
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800317 [[ "$1" == "$latest" ]]
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800318}
319
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800320function missing_lib {
Carmelo Casconee45902b2018-12-18 13:30:45 -0800321 ldconfig -p | grep $1 &> /dev/null
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800322 if [[ $? == 0 ]]; then
Carmelo Casconee45902b2018-12-18 13:30:45 -0800323 echo "$1 found!"
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800324 return 1 # false
Carmelo Casconee45902b2018-12-18 13:30:45 -0800325 fi
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800326 return 0 # true
327}
328
329function all_done {
330 if [[ "${CLEAN_UP}" = true ]] ; then
331 echo "Cleaning up build dir... ${BUILD_DIR})"
332 sudo rm -rf ${BUILD_DIR}
333 fi
334 echo "Done!"
335 exit 0
Carmelo Casconee45902b2018-12-18 13:30:45 -0800336}
337
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800338MUST_DO_ALL=false
339DID_REQUIREMENTS=false
340function check_and_do {
341 # Check if the latest built commit is the same we are trying to build now,
342 # or if all projects must be built. If true builds this project.
343 commit_id="$1"
344 proj_dir="$2"
345 func_name="$3"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200346 step_name="$4"
347 commit_file=${BUILD_DIR}/${proj_dir}/.last_built_commit_${step_name}
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800348 if [[ ${MUST_DO_ALL} = true ]] \
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200349 || check_commit ${commit_id} ${commit_file}; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800350 echo "#"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200351 echo "# Building ${step_name} (${commit_id})"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800352 echo "#"
353 # Print commands used to install to aid debugging
354 set -x
355 if ! ${DID_REQUIREMENTS} = true; then
356 do_requirements
357 # TODO consider other Linux distros; presently this script assumes
358 # that it is running on Ubuntu.
359 RELEASE=`lsb_release -rs`
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800360 if version_ge ${RELEASE} 18.04; then
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900361 do_requirements_1804
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800362 elif version_ge ${RELEASE} 16.04; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800363 do_requirements_1604
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800364 else
365 echo "Ubuntu version $RELEASE is not supported"
366 exit 1
367 fi
368 DID_REQUIREMENTS=true
369 fi
370 eval ${func_name}
Carmelo Casconee45902b2018-12-18 13:30:45 -0800371 if [[ -d ${BUILD_DIR}/${proj_dir} ]]; then
372 # If project was built, we expect its dir. Otherwise, we assume
373 # build was skipped.
374 echo ${commit_id} > ${commit_file}
375 # Build all next projects as they might depend on this one.
376 MUST_DO_ALL=true
377 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800378 # Disable printing to reduce output
379 set +x
380 else
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200381 echo "${step_name} is up to date (commit ${commit_id})"
382 fi
383 # Exit if last step.
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800384 if [[ ${step_name} = ${LAST_STEP} ]]; then
385 all_done
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800386 fi
387}
388
389mkdir -p ${BUILD_DIR}
390cd ${BUILD_DIR}
391# In dependency order.
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800392if missing_lib libprotobuf; then
393 check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
394fi
395if missing_lib libgrpc; then
396 check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
397fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800398check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200399check_and_do ${PI_COMMIT} PI do_PI PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800400check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
401check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200402check_and_do master scapy-vxlan do_scapy-vxlan scapy-vxlan
403check_and_do master ptf do_ptf ptf
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800404
Carmelo Cascone7c82bcf2019-02-08 22:57:18 -0800405all_done