blob: 07feecc8493346748ccc4a69b934ee6df844699f [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#
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +09006# Tested on Ubuntu 14.04, 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
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 Casconee45902b2018-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 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}
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 Casconeb5324e72018-11-25 02:26:32 -080053 graphviz \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080054 libavl-dev \
55 libboost-dev \
Carmelo Casconeb5324e72018-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 libssl-dev \
81 libtool \
82 make \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080083 pkg-config \
84 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070085 python2.7 \
86 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080087 tcpdump \
88 wget \
89 unzip
90
Charles Chan87dc82e2018-08-05 16:27:10 -070091 sudo -H pip install setuptools cffi ipaddr ipaddress pypcap
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080092}
93
94function do_requirements_1404 {
95 sudo apt install -y python-software-properties software-properties-common
96 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
97 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
98 sudo apt update
99 sudo apt install -y \
100 dpkg-dev \
101 g++-4.9 \
102 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800103 cmake \
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900104 libbz2-dev \
105 libreadline6 \
106 libreadline6-dev \
107 mktemp
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 \
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900124 libprotobuf-c-dev \
125 libreadline6 \
126 libreadline6-dev \
127 mktemp
128}
129
130function do_requirements_1804 {
131 sudo apt-get update
132 sudo apt-get install -y --no-install-recommends \
133 ca-certificates \
134 g++ \
135 libboost1.65-dev \
136 libboost-regex1.65-dev \
137 libboost-iostreams1.65-dev \
138 libreadline-dev \
139 libssl1.0-dev \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800140 libprotobuf-c-dev
141}
142
143function do_boost {
144 cd ${BUILD_DIR}
145 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
146 tar --bzip2 -xf boost_1_58_0.tar.bz2
147 cd boost_1_58_0
148
149 ./bootstrap.sh --with-libraries=iostreams
150 sudo ./b2 install
151 sudo ldconfig
152
153 cd ..
154 sudo rm -rf boost_1_58_0
155}
156
157function do_protobuf-c {
158 cd ${BUILD_DIR}
159 git clone https://github.com/protobuf-c/protobuf-c.git
160 cd protobuf-c
161
162 ./autogen.sh
163 ./configure --prefix=/usr
164 make -j${NUM_CORES}
165 sudo make install
166 sudo ldconfig
167
168 cd ..
169 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800170}
171
172function do_protobuf {
Carmelo Casconee45902b2018-12-18 13:30:45 -0800173 if check_lib libprotobuf; then
174 return
175 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800176 cd ${BUILD_DIR}
177 if [ ! -d protobuf ]; then
178 git clone https://github.com/google/protobuf.git
179 fi
180 cd protobuf
181 git fetch
182 git checkout ${PROTOBUF_COMMIT}
183
184 export CFLAGS="-Os"
185 export CXXFLAGS="-Os"
186 export LDFLAGS="-Wl,-s"
187 ./autogen.sh
188 ./configure --prefix=/usr
189 make -j${NUM_CORES}
190 sudo make install
191 sudo ldconfig
192 unset CFLAGS CXXFLAGS LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200193
194 cd python
195 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800196}
197
198function do_grpc {
Carmelo Casconee45902b2018-12-18 13:30:45 -0800199 if check_lib libgrpc; then
200 return
201 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800202 cd ${BUILD_DIR}
203 if [ ! -d grpc ]; then
204 git clone https://github.com/grpc/grpc.git
205 fi
206 cd grpc
207 git fetch
208 git checkout ${GRPC_COMMIT}
209 git submodule update --init
210
211 export LDFLAGS="-Wl,-s"
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900212 RELEASE=`lsb_release -rs`
213 if version_ge $RELEASE 18.04; then
214 # Ubuntu 18.04 ships OpenSSL 1.1 by default, which has breaking changes in the API.
215 # Here, we will build grpc with OpenSSL 1.0.
216 # (Reference: https://github.com/grpc/grpc/issues/10589)
217 # Also, set CFLAGS to avoid compilcation error caused by gcc7.
218 # (Reference: https://github.com/grpc/grpc/issues/13854)
219 PKG_CONFIG_PATH=/usr/lib/openssl-1.0/pkgconfig make -j${NUM_CORES} CFLAGS='-Wno-error'
220 else
221 make -j${NUM_CORES}
222 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800223 sudo make install
224 sudo ldconfig
225 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200226
227 sudo pip install -r requirements.txt
228 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800229}
230
231function do_libyang {
232 cd ${BUILD_DIR}
233 if [ ! -d libyang ]; then
234 git clone https://github.com/CESNET/libyang.git
235 fi
236 cd libyang
237 git fetch
238 git checkout ${LIBYANG_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 ..
243 make -j${NUM_CORES}
244 sudo make install
245 sudo ldconfig
246}
247
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800248function do_sysrepo_deps {
249 RELEASE=`lsb_release -rs`
250 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
251 do_protobuf-c
252 fi
253}
254
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800255function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800256 do_sysrepo_deps
257
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800258 cd ${BUILD_DIR}
259 if [ ! -d sysrepo ]; then
260 git clone https://github.com/sysrepo/sysrepo.git
261 fi
262 cd sysrepo
263 git fetch
264 git checkout ${SYSREPO_COMMIT}
265
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800266 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800267 cd build
268 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
269 -DCALL_TARGET_BINS_DIRECTLY=Off ..
270 make -j${NUM_CORES}
271 sudo make install
272 sudo ldconfig
273}
274
275function checkout_bmv2 {
276 cd ${BUILD_DIR}
277 if [ ! -d bmv2 ]; then
278 git clone https://github.com/p4lang/behavioral-model.git bmv2
279 fi
280 cd bmv2
281 git fetch
282 git checkout ${BMV2_COMMIT}
283}
284
285function do_pi_bmv2_deps {
286 checkout_bmv2
287 # From bmv2's install_deps.sh.
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200288 # Nanomsg is required also by PI.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800289 tmpdir=`mktemp -d -p .`
290 cd ${tmpdir}
291 bash ../travis/install-thrift.sh
292 bash ../travis/install-nanomsg.sh
293 sudo ldconfig
294 bash ../travis/install-nnpy.sh
295 cd ..
296 sudo rm -rf $tmpdir
297}
298
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200299function do_PI {
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800300 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200301 if [ ! -d PI ]; then
302 git clone https://github.com/p4lang/PI.git
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800303 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200304 cd PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800305 git fetch
306 git checkout ${PI_COMMIT}
307 git submodule update --init --recursive
308
309 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800310 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700311 # ./configure --with-proto --with-sysrepo
312 ./configure --with-proto --without-internal-rpc --without-cli
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800313 make -j${NUM_CORES}
314 sudo make install
315 sudo ldconfig
316
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800317 # FIXME: re-enable when gNMI support becomes more stable
318 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800319}
320
321function do_bmv2 {
322 checkout_bmv2
323
324 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200325 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700326 ./configure --with-pi --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200327 else
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700328 ./configure --with-pi --disable-elogger --without-nanomsg --disable-logging-macros
Carmelo Casconef02872d2018-06-20 08:49:02 +0200329 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800330 make -j${NUM_CORES}
331 sudo make install
332 sudo ldconfig
333
334 # Simple_switch_grpc target
335 cd targets/simple_switch_grpc
336 ./autogen.sh
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700337 ./configure --with-thrift
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800338 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700339 # ./configure --with-sysrepo --with-thrift
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800340 make -j${NUM_CORES}
341 sudo make install
342 sudo ldconfig
343}
344
345function do_p4c {
346 cd ${BUILD_DIR}
347 if [ ! -d p4c ]; then
348 git clone https://github.com/p4lang/p4c.git
349 fi
350 cd p4c
351 git fetch
352 git checkout ${P4C_COMMIT}
353 git submodule update --init --recursive
354
355 mkdir -p build
356 cd build
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700357 cmake .. -DENABLE_EBPF=OFF
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800358 make -j${NUM_CORES}
359 sudo make install
360 sudo ldconfig
361}
362
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200363function do_scapy-vxlan {
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800364 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200365 if [ ! -d scapy-vxlan ]; then
366 git clone https://github.com/p4lang/scapy-vxlan.git
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800367 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200368 cd scapy-vxlan
369
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800370 git pull origin master
371
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200372 sudo python setup.py install
373}
374
375function do_ptf {
376 cd ${BUILD_DIR}
377 if [ ! -d ptf ]; then
378 git clone https://github.com/p4lang/ptf.git
379 fi
380 cd ptf
381 git pull origin master
382
383 sudo python setup.py install
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800384}
385
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800386function check_commit {
387 if [ ! -e $2 ]; then
388 return 0 # true
389 fi
390 if [[ $(< $2) != "$1" ]]; then
391 return 0 # true
392 fi
393 return 1 # false
394}
395
396# The following is borrowed from Mininet's util/install.sh
397function version_ge {
398 # sort -V sorts by *version number*
399 latest=`printf "$1\n$2" | sort -V | tail -1`
400 # If $1 is latest version, then $1 >= $2
401 [ "$1" == "$latest" ]
402}
403
Carmelo Casconee45902b2018-12-18 13:30:45 -0800404function check_lib {
405 ldconfig -p | grep $1 &> /dev/null
406 if [ $? == 0 ]; then
407 echo "$1 found!"
408 return 0 # true
409 fi
410 return 1 # false
411}
412
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800413MUST_DO_ALL=false
414DID_REQUIREMENTS=false
415function check_and_do {
416 # Check if the latest built commit is the same we are trying to build now,
417 # or if all projects must be built. If true builds this project.
418 commit_id="$1"
419 proj_dir="$2"
420 func_name="$3"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200421 step_name="$4"
422 commit_file=${BUILD_DIR}/${proj_dir}/.last_built_commit_${step_name}
Carmelo Cascone05354672018-04-10 13:24:03 -0700423 if [ ${MUST_DO_ALL} = true ] \
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200424 || check_commit ${commit_id} ${commit_file}; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800425 echo "#"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200426 echo "# Building ${step_name} (${commit_id})"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800427 echo "#"
428 # Print commands used to install to aid debugging
429 set -x
430 if ! ${DID_REQUIREMENTS} = true; then
431 do_requirements
432 # TODO consider other Linux distros; presently this script assumes
433 # that it is running on Ubuntu.
434 RELEASE=`lsb_release -rs`
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900435 if version_ge $RELEASE 18.04; then
436 do_requirements_1804
437 elif version_ge $RELEASE 16.04; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800438 do_requirements_1604
439 elif version_ge $RELEASE 14.04; then
440 do_requirements_1404
441 else
442 echo "Ubuntu version $RELEASE is not supported"
443 exit 1
444 fi
445 DID_REQUIREMENTS=true
446 fi
447 eval ${func_name}
Carmelo Casconee45902b2018-12-18 13:30:45 -0800448 if [[ -d ${BUILD_DIR}/${proj_dir} ]]; then
449 # If project was built, we expect its dir. Otherwise, we assume
450 # build was skipped.
451 echo ${commit_id} > ${commit_file}
452 # Build all next projects as they might depend on this one.
453 MUST_DO_ALL=true
454 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800455 # Disable printing to reduce output
456 set +x
457 else
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200458 echo "${step_name} is up to date (commit ${commit_id})"
459 fi
460 # Exit if last step.
461 if [ ${step_name} = ${LAST_STEP} ]; then
462 exit
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800463 fi
464}
465
466mkdir -p ${BUILD_DIR}
467cd ${BUILD_DIR}
468# In dependency order.
469check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
470check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800471# FIXME: re-enable when gNMI support becomes more stable
472# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
473# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800474check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200475check_and_do ${PI_COMMIT} PI do_PI PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800476check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
477check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200478check_and_do master scapy-vxlan do_scapy-vxlan scapy-vxlan
479check_and_do master ptf do_ptf ptf
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800480
481echo "Done!"