blob: 8efc4a34c39495dad078cc68dabfe45d2c6b88c8 [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 Cascone03ae0ac2018-10-11 08:31:59 -070024BMV2_COMMIT="ae87b4d4523488ac935133b4aef437796ad1bbd1"
25PI_COMMIT="539e4624f16aac39f8890a6dfb11c65040e735ad"
26P4C_COMMIT="380830f6c26135d1d65e1312e3ba2da628c18145"
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 {
173 cd ${BUILD_DIR}
174 if [ ! -d protobuf ]; then
175 git clone https://github.com/google/protobuf.git
176 fi
177 cd protobuf
178 git fetch
179 git checkout ${PROTOBUF_COMMIT}
180
181 export CFLAGS="-Os"
182 export CXXFLAGS="-Os"
183 export LDFLAGS="-Wl,-s"
184 ./autogen.sh
185 ./configure --prefix=/usr
186 make -j${NUM_CORES}
187 sudo make install
188 sudo ldconfig
189 unset CFLAGS CXXFLAGS LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200190
191 cd python
192 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800193}
194
195function do_grpc {
196 cd ${BUILD_DIR}
197 if [ ! -d grpc ]; then
198 git clone https://github.com/grpc/grpc.git
199 fi
200 cd grpc
201 git fetch
202 git checkout ${GRPC_COMMIT}
203 git submodule update --init
204
205 export LDFLAGS="-Wl,-s"
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900206 RELEASE=`lsb_release -rs`
207 if version_ge $RELEASE 18.04; then
208 # Ubuntu 18.04 ships OpenSSL 1.1 by default, which has breaking changes in the API.
209 # Here, we will build grpc with OpenSSL 1.0.
210 # (Reference: https://github.com/grpc/grpc/issues/10589)
211 # Also, set CFLAGS to avoid compilcation error caused by gcc7.
212 # (Reference: https://github.com/grpc/grpc/issues/13854)
213 PKG_CONFIG_PATH=/usr/lib/openssl-1.0/pkgconfig make -j${NUM_CORES} CFLAGS='-Wno-error'
214 else
215 make -j${NUM_CORES}
216 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800217 sudo make install
218 sudo ldconfig
219 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200220
221 sudo pip install -r requirements.txt
222 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800223}
224
225function do_libyang {
226 cd ${BUILD_DIR}
227 if [ ! -d libyang ]; then
228 git clone https://github.com/CESNET/libyang.git
229 fi
230 cd libyang
231 git fetch
232 git checkout ${LIBYANG_COMMIT}
233
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800234 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800235 cd build
236 cmake ..
237 make -j${NUM_CORES}
238 sudo make install
239 sudo ldconfig
240}
241
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800242function do_sysrepo_deps {
243 RELEASE=`lsb_release -rs`
244 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
245 do_protobuf-c
246 fi
247}
248
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800249function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800250 do_sysrepo_deps
251
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800252 cd ${BUILD_DIR}
253 if [ ! -d sysrepo ]; then
254 git clone https://github.com/sysrepo/sysrepo.git
255 fi
256 cd sysrepo
257 git fetch
258 git checkout ${SYSREPO_COMMIT}
259
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800260 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800261 cd build
262 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
263 -DCALL_TARGET_BINS_DIRECTLY=Off ..
264 make -j${NUM_CORES}
265 sudo make install
266 sudo ldconfig
267}
268
269function checkout_bmv2 {
270 cd ${BUILD_DIR}
271 if [ ! -d bmv2 ]; then
272 git clone https://github.com/p4lang/behavioral-model.git bmv2
273 fi
274 cd bmv2
275 git fetch
276 git checkout ${BMV2_COMMIT}
277}
278
279function do_pi_bmv2_deps {
280 checkout_bmv2
281 # From bmv2's install_deps.sh.
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200282 # Nanomsg is required also by PI.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800283 tmpdir=`mktemp -d -p .`
284 cd ${tmpdir}
285 bash ../travis/install-thrift.sh
286 bash ../travis/install-nanomsg.sh
287 sudo ldconfig
288 bash ../travis/install-nnpy.sh
289 cd ..
290 sudo rm -rf $tmpdir
291}
292
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200293function do_PI {
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800294 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200295 if [ ! -d PI ]; then
296 git clone https://github.com/p4lang/PI.git
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800297 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200298 cd PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800299 git fetch
300 git checkout ${PI_COMMIT}
301 git submodule update --init --recursive
302
303 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800304 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700305 # ./configure --with-proto --with-sysrepo
306 ./configure --with-proto --without-internal-rpc --without-cli
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800307 make -j${NUM_CORES}
308 sudo make install
309 sudo ldconfig
310
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800311 # FIXME: re-enable when gNMI support becomes more stable
312 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800313}
314
315function do_bmv2 {
316 checkout_bmv2
317
318 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200319 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700320 ./configure --with-pi --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200321 else
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700322 ./configure --with-pi --disable-elogger --without-nanomsg --disable-logging-macros
Carmelo Casconef02872d2018-06-20 08:49:02 +0200323 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800324 make -j${NUM_CORES}
325 sudo make install
326 sudo ldconfig
327
328 # Simple_switch_grpc target
329 cd targets/simple_switch_grpc
330 ./autogen.sh
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700331 ./configure --with-thrift
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800332 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700333 # ./configure --with-sysrepo --with-thrift
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800334 make -j${NUM_CORES}
335 sudo make install
336 sudo ldconfig
337}
338
339function do_p4c {
340 cd ${BUILD_DIR}
341 if [ ! -d p4c ]; then
342 git clone https://github.com/p4lang/p4c.git
343 fi
344 cd p4c
345 git fetch
346 git checkout ${P4C_COMMIT}
347 git submodule update --init --recursive
348
349 mkdir -p build
350 cd build
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700351 cmake .. -DENABLE_EBPF=OFF
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800352 make -j${NUM_CORES}
353 sudo make install
354 sudo ldconfig
355}
356
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200357function do_scapy-vxlan {
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800358 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200359 if [ ! -d scapy-vxlan ]; then
360 git clone https://github.com/p4lang/scapy-vxlan.git
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800361 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200362 cd scapy-vxlan
363
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800364 git pull origin master
365
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200366 sudo python setup.py install
367}
368
369function do_ptf {
370 cd ${BUILD_DIR}
371 if [ ! -d ptf ]; then
372 git clone https://github.com/p4lang/ptf.git
373 fi
374 cd ptf
375 git pull origin master
376
377 sudo python setup.py install
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800378}
379
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800380function check_commit {
381 if [ ! -e $2 ]; then
382 return 0 # true
383 fi
384 if [[ $(< $2) != "$1" ]]; then
385 return 0 # true
386 fi
387 return 1 # false
388}
389
390# The following is borrowed from Mininet's util/install.sh
391function version_ge {
392 # sort -V sorts by *version number*
393 latest=`printf "$1\n$2" | sort -V | tail -1`
394 # If $1 is latest version, then $1 >= $2
395 [ "$1" == "$latest" ]
396}
397
398MUST_DO_ALL=false
399DID_REQUIREMENTS=false
400function check_and_do {
401 # Check if the latest built commit is the same we are trying to build now,
402 # or if all projects must be built. If true builds this project.
403 commit_id="$1"
404 proj_dir="$2"
405 func_name="$3"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200406 step_name="$4"
407 commit_file=${BUILD_DIR}/${proj_dir}/.last_built_commit_${step_name}
Carmelo Cascone05354672018-04-10 13:24:03 -0700408 if [ ${MUST_DO_ALL} = true ] \
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200409 || check_commit ${commit_id} ${commit_file}; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800410 echo "#"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200411 echo "# Building ${step_name} (${commit_id})"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800412 echo "#"
413 # Print commands used to install to aid debugging
414 set -x
415 if ! ${DID_REQUIREMENTS} = true; then
416 do_requirements
417 # TODO consider other Linux distros; presently this script assumes
418 # that it is running on Ubuntu.
419 RELEASE=`lsb_release -rs`
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900420 if version_ge $RELEASE 18.04; then
421 do_requirements_1804
422 elif version_ge $RELEASE 16.04; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800423 do_requirements_1604
424 elif version_ge $RELEASE 14.04; then
425 do_requirements_1404
426 else
427 echo "Ubuntu version $RELEASE is not supported"
428 exit 1
429 fi
430 DID_REQUIREMENTS=true
431 fi
432 eval ${func_name}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200433 echo ${commit_id} > ${commit_file}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800434 # Build all next projects as they might depend on this one.
435 MUST_DO_ALL=true
436 # Disable printing to reduce output
437 set +x
438 else
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200439 echo "${step_name} is up to date (commit ${commit_id})"
440 fi
441 # Exit if last step.
442 if [ ${step_name} = ${LAST_STEP} ]; then
443 exit
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800444 fi
445}
446
447mkdir -p ${BUILD_DIR}
448cd ${BUILD_DIR}
449# In dependency order.
450check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
451check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800452# FIXME: re-enable when gNMI support becomes more stable
453# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
454# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800455check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200456check_and_do ${PI_COMMIT} PI do_PI PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800457check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
458check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200459check_and_do master scapy-vxlan do_scapy-vxlan scapy-vxlan
460check_and_do master ptf do_ptf ptf
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800461
462echo "Done!"