blob: 4516c8ebdb2201033d3646f3ec68c37b9b09e8fc [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#
6# Tested on Ubuntu 14.04 and 16.04.
7#
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
14# example, to install PI, but not BMv2, p4c, etc:
15# ./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 Casconea52c8802018-12-18 13:30:45 -080024BMV2_COMMIT="7fd3b39519ca892c2e160b8be358d3f487b1b00e"
25PI_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
32NUM_CORES=`grep -c ^processor /proc/cpuinfo`
33
Carmelo Casconef02872d2018-06-20 08:49:02 +020034# If false, build tools without debug features to improve throughput of BMv2 and
Carmelo Casconeb0f45fe2018-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}
37
Carmelo Cascone95e5afd2018-07-17 14:45:23 +020038# Execute up to the given step (first argument), or all if not defined.
39LAST_STEP=${1:-all}
40
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080041function do_requirements {
42 sudo apt update
43 sudo apt-get install -y --no-install-recommends \
44 autoconf \
45 automake \
46 bison \
47 build-essential \
48 cmake \
49 cpp \
50 curl \
51 flex \
52 git \
Carmelo Casconeb0c66652018-11-25 02:26:32 -080053 graphviz \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080054 libavl-dev \
55 libboost-dev \
Carmelo Casconeb0c66652018-11-25 02:26:32 -080056 libboost-graph-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080057 libboost-program-options-dev \
58 libboost-system-dev \
59 libboost-filesystem-dev \
60 libboost-thread-dev \
61 libboost-filesystem-dev \
62 libboost-program-options-dev \
63 libboost-system-dev \
64 libboost-test-dev \
65 libboost-thread-dev \
66 libc6-dev \
67 libev-dev \
68 libevent-dev \
69 libffi-dev \
70 libfl-dev \
71 libgc-dev \
72 libgc1c2 \
73 libgflags-dev \
74 libgmp-dev \
75 libgmp10 \
76 libgmpxx4ldbl \
77 libjudy-dev \
78 libpcap-dev \
79 libpcre3-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080080 libreadline6 \
81 libreadline6-dev \
82 libssl-dev \
83 libtool \
84 make \
85 mktemp \
86 pkg-config \
87 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070088 python2.7 \
89 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080090 tcpdump \
91 wget \
92 unzip
93
Charles Chan87dc82e2018-08-05 16:27:10 -070094 sudo -H pip install setuptools cffi ipaddr ipaddress pypcap
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080095}
96
97function do_requirements_1404 {
98 sudo apt install -y python-software-properties software-properties-common
99 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
100 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
101 sudo apt update
102 sudo apt install -y \
103 dpkg-dev \
104 g++-4.9 \
105 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800106 cmake \
107 libbz2-dev
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800108
109 # Needed for p4c.
110 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
111 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800112
113 if [ -z "$(ldconfig -p | grep libboost_iostreams.so.1.58.0)" ]; then
114 do_boost
115 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800116}
117
118function do_requirements_1604 {
119 sudo apt-get update
120 sudo apt-get install -y --no-install-recommends \
121 ca-certificates \
122 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800123 libboost-iostreams1.58-dev \
124 libprotobuf-c-dev
125}
126
127function do_boost {
128 cd ${BUILD_DIR}
129 wget https://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.bz2/download -O boost_1_58_0.tar.bz2
130 tar --bzip2 -xf boost_1_58_0.tar.bz2
131 cd boost_1_58_0
132
133 ./bootstrap.sh --with-libraries=iostreams
134 sudo ./b2 install
135 sudo ldconfig
136
137 cd ..
138 sudo rm -rf boost_1_58_0
139}
140
141function do_protobuf-c {
142 cd ${BUILD_DIR}
143 git clone https://github.com/protobuf-c/protobuf-c.git
144 cd protobuf-c
145
146 ./autogen.sh
147 ./configure --prefix=/usr
148 make -j${NUM_CORES}
149 sudo make install
150 sudo ldconfig
151
152 cd ..
153 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800154}
155
156function do_protobuf {
Carmelo Casconea52c8802018-12-18 13:30:45 -0800157 if check_lib libprotobuf; then
158 return
159 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800160 cd ${BUILD_DIR}
161 if [ ! -d protobuf ]; then
162 git clone https://github.com/google/protobuf.git
163 fi
164 cd protobuf
165 git fetch
166 git checkout ${PROTOBUF_COMMIT}
167
168 export CFLAGS="-Os"
169 export CXXFLAGS="-Os"
170 export LDFLAGS="-Wl,-s"
171 ./autogen.sh
172 ./configure --prefix=/usr
173 make -j${NUM_CORES}
174 sudo make install
175 sudo ldconfig
176 unset CFLAGS CXXFLAGS LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200177
178 cd python
179 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800180}
181
182function do_grpc {
Carmelo Casconea52c8802018-12-18 13:30:45 -0800183 if check_lib libgrpc; then
184 return
185 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800186 cd ${BUILD_DIR}
187 if [ ! -d grpc ]; then
188 git clone https://github.com/grpc/grpc.git
189 fi
190 cd grpc
191 git fetch
192 git checkout ${GRPC_COMMIT}
193 git submodule update --init
194
195 export LDFLAGS="-Wl,-s"
196 make -j${NUM_CORES}
197 sudo make install
198 sudo ldconfig
199 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200200
201 sudo pip install -r requirements.txt
202 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800203}
204
205function do_libyang {
206 cd ${BUILD_DIR}
207 if [ ! -d libyang ]; then
208 git clone https://github.com/CESNET/libyang.git
209 fi
210 cd libyang
211 git fetch
212 git checkout ${LIBYANG_COMMIT}
213
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800214 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800215 cd build
216 cmake ..
217 make -j${NUM_CORES}
218 sudo make install
219 sudo ldconfig
220}
221
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800222function do_sysrepo_deps {
223 RELEASE=`lsb_release -rs`
224 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
225 do_protobuf-c
226 fi
227}
228
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800229function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800230 do_sysrepo_deps
231
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800232 cd ${BUILD_DIR}
233 if [ ! -d sysrepo ]; then
234 git clone https://github.com/sysrepo/sysrepo.git
235 fi
236 cd sysrepo
237 git fetch
238 git checkout ${SYSREPO_COMMIT}
239
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800240 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800241 cd build
242 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
243 -DCALL_TARGET_BINS_DIRECTLY=Off ..
244 make -j${NUM_CORES}
245 sudo make install
246 sudo ldconfig
247}
248
249function checkout_bmv2 {
250 cd ${BUILD_DIR}
251 if [ ! -d bmv2 ]; then
252 git clone https://github.com/p4lang/behavioral-model.git bmv2
253 fi
254 cd bmv2
255 git fetch
256 git checkout ${BMV2_COMMIT}
257}
258
259function do_pi_bmv2_deps {
260 checkout_bmv2
261 # From bmv2's install_deps.sh.
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200262 # Nanomsg is required also by PI.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800263 tmpdir=`mktemp -d -p .`
264 cd ${tmpdir}
265 bash ../travis/install-thrift.sh
266 bash ../travis/install-nanomsg.sh
267 sudo ldconfig
268 bash ../travis/install-nnpy.sh
269 cd ..
270 sudo rm -rf $tmpdir
271}
272
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200273function do_PI {
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800274 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200275 if [ ! -d PI ]; then
276 git clone https://github.com/p4lang/PI.git
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800277 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200278 cd PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800279 git fetch
280 git checkout ${PI_COMMIT}
281 git submodule update --init --recursive
282
283 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800284 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700285 # ./configure --with-proto --with-sysrepo
286 ./configure --with-proto --without-internal-rpc --without-cli
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800287 make -j${NUM_CORES}
288 sudo make install
289 sudo ldconfig
290
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800291 # FIXME: re-enable when gNMI support becomes more stable
292 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800293}
294
295function do_bmv2 {
296 checkout_bmv2
297
298 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200299 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700300 ./configure --with-pi --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200301 else
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700302 ./configure --with-pi --disable-elogger --without-nanomsg --disable-logging-macros
Carmelo Casconef02872d2018-06-20 08:49:02 +0200303 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800304 make -j${NUM_CORES}
305 sudo make install
306 sudo ldconfig
307
308 # Simple_switch_grpc target
309 cd targets/simple_switch_grpc
310 ./autogen.sh
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700311 ./configure --with-thrift
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800312 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700313 # ./configure --with-sysrepo --with-thrift
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800314 make -j${NUM_CORES}
315 sudo make install
316 sudo ldconfig
317}
318
319function do_p4c {
320 cd ${BUILD_DIR}
321 if [ ! -d p4c ]; then
322 git clone https://github.com/p4lang/p4c.git
323 fi
324 cd p4c
325 git fetch
326 git checkout ${P4C_COMMIT}
327 git submodule update --init --recursive
328
329 mkdir -p build
330 cd build
Carmelo Casconeb0f45fe2018-10-11 08:31:59 -0700331 cmake .. -DENABLE_EBPF=OFF
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800332 make -j${NUM_CORES}
333 sudo make install
334 sudo ldconfig
335}
336
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200337function do_scapy-vxlan {
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800338 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200339 if [ ! -d scapy-vxlan ]; then
340 git clone https://github.com/p4lang/scapy-vxlan.git
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800341 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200342 cd scapy-vxlan
343
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800344 git pull origin master
345
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200346 sudo python setup.py install
347}
348
349function do_ptf {
350 cd ${BUILD_DIR}
351 if [ ! -d ptf ]; then
352 git clone https://github.com/p4lang/ptf.git
353 fi
354 cd ptf
355 git pull origin master
356
357 sudo python setup.py install
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800358}
359
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800360function check_commit {
361 if [ ! -e $2 ]; then
362 return 0 # true
363 fi
364 if [[ $(< $2) != "$1" ]]; then
365 return 0 # true
366 fi
367 return 1 # false
368}
369
370# The following is borrowed from Mininet's util/install.sh
371function version_ge {
372 # sort -V sorts by *version number*
373 latest=`printf "$1\n$2" | sort -V | tail -1`
374 # If $1 is latest version, then $1 >= $2
375 [ "$1" == "$latest" ]
376}
377
Carmelo Casconea52c8802018-12-18 13:30:45 -0800378function check_lib {
379 ldconfig -p | grep $1 &> /dev/null
380 if [ $? == 0 ]; then
381 echo "$1 found!"
382 return 0 # true
383 fi
384 return 1 # false
385}
386
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800387MUST_DO_ALL=false
388DID_REQUIREMENTS=false
389function check_and_do {
390 # Check if the latest built commit is the same we are trying to build now,
391 # or if all projects must be built. If true builds this project.
392 commit_id="$1"
393 proj_dir="$2"
394 func_name="$3"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200395 step_name="$4"
396 commit_file=${BUILD_DIR}/${proj_dir}/.last_built_commit_${step_name}
Carmelo Cascone05354672018-04-10 13:24:03 -0700397 if [ ${MUST_DO_ALL} = true ] \
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200398 || check_commit ${commit_id} ${commit_file}; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800399 echo "#"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200400 echo "# Building ${step_name} (${commit_id})"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800401 echo "#"
402 # Print commands used to install to aid debugging
403 set -x
404 if ! ${DID_REQUIREMENTS} = true; then
405 do_requirements
406 # TODO consider other Linux distros; presently this script assumes
407 # that it is running on Ubuntu.
408 RELEASE=`lsb_release -rs`
409 if version_ge $RELEASE 16.04; then
410 do_requirements_1604
411 elif version_ge $RELEASE 14.04; then
412 do_requirements_1404
413 else
414 echo "Ubuntu version $RELEASE is not supported"
415 exit 1
416 fi
417 DID_REQUIREMENTS=true
418 fi
419 eval ${func_name}
Carmelo Casconea52c8802018-12-18 13:30:45 -0800420 if [[ -d ${BUILD_DIR}/${proj_dir} ]]; then
421 # If project was built, we expect its dir. Otherwise, we assume
422 # build was skipped.
423 echo ${commit_id} > ${commit_file}
424 # Build all next projects as they might depend on this one.
425 MUST_DO_ALL=true
426 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800427 # Disable printing to reduce output
428 set +x
429 else
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200430 echo "${step_name} is up to date (commit ${commit_id})"
431 fi
432 # Exit if last step.
433 if [ ${step_name} = ${LAST_STEP} ]; then
434 exit
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800435 fi
436}
437
438mkdir -p ${BUILD_DIR}
439cd ${BUILD_DIR}
440# In dependency order.
441check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
442check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800443# FIXME: re-enable when gNMI support becomes more stable
444# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
445# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800446check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200447check_and_do ${PI_COMMIT} PI do_PI PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800448check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
449check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200450check_and_do master scapy-vxlan do_scapy-vxlan scapy-vxlan
451check_and_do master ptf do_ptf ptf
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800452
453echo "Done!"