blob: e2ca92839ae6f8130d73b89dc89fa764d9a30385 [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 \
53 libavl-dev \
54 libboost-dev \
55 libboost-program-options-dev \
56 libboost-system-dev \
57 libboost-filesystem-dev \
58 libboost-thread-dev \
59 libboost-filesystem-dev \
60 libboost-program-options-dev \
61 libboost-system-dev \
62 libboost-test-dev \
63 libboost-thread-dev \
64 libc6-dev \
65 libev-dev \
66 libevent-dev \
67 libffi-dev \
68 libfl-dev \
69 libgc-dev \
70 libgc1c2 \
71 libgflags-dev \
72 libgmp-dev \
73 libgmp10 \
74 libgmpxx4ldbl \
75 libjudy-dev \
76 libpcap-dev \
77 libpcre3-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080078 libssl-dev \
79 libtool \
80 make \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080081 pkg-config \
82 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070083 python2.7 \
84 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080085 tcpdump \
86 wget \
87 unzip
88
Charles Chan87dc82e2018-08-05 16:27:10 -070089 sudo -H pip install setuptools cffi ipaddr ipaddress pypcap
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080090}
91
92function do_requirements_1404 {
93 sudo apt install -y python-software-properties software-properties-common
94 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
95 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
96 sudo apt update
97 sudo apt install -y \
98 dpkg-dev \
99 g++-4.9 \
100 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800101 cmake \
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900102 libbz2-dev \
103 libreadline6 \
104 libreadline6-dev \
105 mktemp
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800106
107 # Needed for p4c.
108 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
109 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800110
111 if [ -z "$(ldconfig -p | grep libboost_iostreams.so.1.58.0)" ]; then
112 do_boost
113 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800114}
115
116function do_requirements_1604 {
117 sudo apt-get update
118 sudo apt-get install -y --no-install-recommends \
119 ca-certificates \
120 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800121 libboost-iostreams1.58-dev \
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900122 libprotobuf-c-dev \
123 libreadline6 \
124 libreadline6-dev \
125 mktemp
126}
127
128function do_requirements_1804 {
129 sudo apt-get update
130 sudo apt-get install -y --no-install-recommends \
131 ca-certificates \
132 g++ \
133 libboost1.65-dev \
134 libboost-regex1.65-dev \
135 libboost-iostreams1.65-dev \
136 libreadline-dev \
137 libssl1.0-dev \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800138 libprotobuf-c-dev
139}
140
141function do_boost {
142 cd ${BUILD_DIR}
143 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
144 tar --bzip2 -xf boost_1_58_0.tar.bz2
145 cd boost_1_58_0
146
147 ./bootstrap.sh --with-libraries=iostreams
148 sudo ./b2 install
149 sudo ldconfig
150
151 cd ..
152 sudo rm -rf boost_1_58_0
153}
154
155function do_protobuf-c {
156 cd ${BUILD_DIR}
157 git clone https://github.com/protobuf-c/protobuf-c.git
158 cd protobuf-c
159
160 ./autogen.sh
161 ./configure --prefix=/usr
162 make -j${NUM_CORES}
163 sudo make install
164 sudo ldconfig
165
166 cd ..
167 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800168}
169
170function do_protobuf {
171 cd ${BUILD_DIR}
172 if [ ! -d protobuf ]; then
173 git clone https://github.com/google/protobuf.git
174 fi
175 cd protobuf
176 git fetch
177 git checkout ${PROTOBUF_COMMIT}
178
179 export CFLAGS="-Os"
180 export CXXFLAGS="-Os"
181 export LDFLAGS="-Wl,-s"
182 ./autogen.sh
183 ./configure --prefix=/usr
184 make -j${NUM_CORES}
185 sudo make install
186 sudo ldconfig
187 unset CFLAGS CXXFLAGS LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200188
189 cd python
190 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800191}
192
193function do_grpc {
194 cd ${BUILD_DIR}
195 if [ ! -d grpc ]; then
196 git clone https://github.com/grpc/grpc.git
197 fi
198 cd grpc
199 git fetch
200 git checkout ${GRPC_COMMIT}
201 git submodule update --init
202
203 export LDFLAGS="-Wl,-s"
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900204 RELEASE=`lsb_release -rs`
205 if version_ge $RELEASE 18.04; then
206 # Ubuntu 18.04 ships OpenSSL 1.1 by default, which has breaking changes in the API.
207 # Here, we will build grpc with OpenSSL 1.0.
208 # (Reference: https://github.com/grpc/grpc/issues/10589)
209 # Also, set CFLAGS to avoid compilcation error caused by gcc7.
210 # (Reference: https://github.com/grpc/grpc/issues/13854)
211 PKG_CONFIG_PATH=/usr/lib/openssl-1.0/pkgconfig make -j${NUM_CORES} CFLAGS='-Wno-error'
212 else
213 make -j${NUM_CORES}
214 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800215 sudo make install
216 sudo ldconfig
217 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200218
219 sudo pip install -r requirements.txt
220 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800221}
222
223function do_libyang {
224 cd ${BUILD_DIR}
225 if [ ! -d libyang ]; then
226 git clone https://github.com/CESNET/libyang.git
227 fi
228 cd libyang
229 git fetch
230 git checkout ${LIBYANG_COMMIT}
231
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800232 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800233 cd build
234 cmake ..
235 make -j${NUM_CORES}
236 sudo make install
237 sudo ldconfig
238}
239
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800240function do_sysrepo_deps {
241 RELEASE=`lsb_release -rs`
242 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
243 do_protobuf-c
244 fi
245}
246
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800247function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800248 do_sysrepo_deps
249
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800250 cd ${BUILD_DIR}
251 if [ ! -d sysrepo ]; then
252 git clone https://github.com/sysrepo/sysrepo.git
253 fi
254 cd sysrepo
255 git fetch
256 git checkout ${SYSREPO_COMMIT}
257
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800258 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800259 cd build
260 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
261 -DCALL_TARGET_BINS_DIRECTLY=Off ..
262 make -j${NUM_CORES}
263 sudo make install
264 sudo ldconfig
265}
266
267function checkout_bmv2 {
268 cd ${BUILD_DIR}
269 if [ ! -d bmv2 ]; then
270 git clone https://github.com/p4lang/behavioral-model.git bmv2
271 fi
272 cd bmv2
273 git fetch
274 git checkout ${BMV2_COMMIT}
275}
276
277function do_pi_bmv2_deps {
278 checkout_bmv2
279 # From bmv2's install_deps.sh.
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200280 # Nanomsg is required also by PI.
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800281 tmpdir=`mktemp -d -p .`
282 cd ${tmpdir}
283 bash ../travis/install-thrift.sh
284 bash ../travis/install-nanomsg.sh
285 sudo ldconfig
286 bash ../travis/install-nnpy.sh
287 cd ..
288 sudo rm -rf $tmpdir
289}
290
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200291function do_PI {
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800292 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200293 if [ ! -d PI ]; then
294 git clone https://github.com/p4lang/PI.git
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800295 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200296 cd PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800297 git fetch
298 git checkout ${PI_COMMIT}
299 git submodule update --init --recursive
300
301 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800302 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700303 # ./configure --with-proto --with-sysrepo
304 ./configure --with-proto --without-internal-rpc --without-cli
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800305 make -j${NUM_CORES}
306 sudo make install
307 sudo ldconfig
308
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800309 # FIXME: re-enable when gNMI support becomes more stable
310 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800311}
312
313function do_bmv2 {
314 checkout_bmv2
315
316 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200317 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700318 ./configure --with-pi --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200319 else
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700320 ./configure --with-pi --disable-elogger --without-nanomsg --disable-logging-macros
Carmelo Casconef02872d2018-06-20 08:49:02 +0200321 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800322 make -j${NUM_CORES}
323 sudo make install
324 sudo ldconfig
325
326 # Simple_switch_grpc target
327 cd targets/simple_switch_grpc
328 ./autogen.sh
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700329 ./configure --with-thrift
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800330 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700331 # ./configure --with-sysrepo --with-thrift
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800332 make -j${NUM_CORES}
333 sudo make install
334 sudo ldconfig
335}
336
337function do_p4c {
338 cd ${BUILD_DIR}
339 if [ ! -d p4c ]; then
340 git clone https://github.com/p4lang/p4c.git
341 fi
342 cd p4c
343 git fetch
344 git checkout ${P4C_COMMIT}
345 git submodule update --init --recursive
346
347 mkdir -p build
348 cd build
Carmelo Cascone03ae0ac2018-10-11 08:31:59 -0700349 cmake .. -DENABLE_EBPF=OFF
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800350 make -j${NUM_CORES}
351 sudo make install
352 sudo ldconfig
353}
354
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200355function do_scapy-vxlan {
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800356 cd ${BUILD_DIR}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200357 if [ ! -d scapy-vxlan ]; then
358 git clone https://github.com/p4lang/scapy-vxlan.git
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800359 fi
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200360 cd scapy-vxlan
361
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800362 git pull origin master
363
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200364 sudo python setup.py install
365}
366
367function do_ptf {
368 cd ${BUILD_DIR}
369 if [ ! -d ptf ]; then
370 git clone https://github.com/p4lang/ptf.git
371 fi
372 cd ptf
373 git pull origin master
374
375 sudo python setup.py install
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800376}
377
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800378function check_commit {
379 if [ ! -e $2 ]; then
380 return 0 # true
381 fi
382 if [[ $(< $2) != "$1" ]]; then
383 return 0 # true
384 fi
385 return 1 # false
386}
387
388# The following is borrowed from Mininet's util/install.sh
389function version_ge {
390 # sort -V sorts by *version number*
391 latest=`printf "$1\n$2" | sort -V | tail -1`
392 # If $1 is latest version, then $1 >= $2
393 [ "$1" == "$latest" ]
394}
395
396MUST_DO_ALL=false
397DID_REQUIREMENTS=false
398function check_and_do {
399 # Check if the latest built commit is the same we are trying to build now,
400 # or if all projects must be built. If true builds this project.
401 commit_id="$1"
402 proj_dir="$2"
403 func_name="$3"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200404 step_name="$4"
405 commit_file=${BUILD_DIR}/${proj_dir}/.last_built_commit_${step_name}
Carmelo Cascone05354672018-04-10 13:24:03 -0700406 if [ ${MUST_DO_ALL} = true ] \
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200407 || check_commit ${commit_id} ${commit_file}; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800408 echo "#"
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200409 echo "# Building ${step_name} (${commit_id})"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800410 echo "#"
411 # Print commands used to install to aid debugging
412 set -x
413 if ! ${DID_REQUIREMENTS} = true; then
414 do_requirements
415 # TODO consider other Linux distros; presently this script assumes
416 # that it is running on Ubuntu.
417 RELEASE=`lsb_release -rs`
Jonghwan Hyunbfb3a212018-11-16 11:42:18 +0900418 if version_ge $RELEASE 18.04; then
419 do_requirements_1804
420 elif version_ge $RELEASE 16.04; then
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800421 do_requirements_1604
422 elif version_ge $RELEASE 14.04; then
423 do_requirements_1404
424 else
425 echo "Ubuntu version $RELEASE is not supported"
426 exit 1
427 fi
428 DID_REQUIREMENTS=true
429 fi
430 eval ${func_name}
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200431 echo ${commit_id} > ${commit_file}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800432 # Build all next projects as they might depend on this one.
433 MUST_DO_ALL=true
434 # Disable printing to reduce output
435 set +x
436 else
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200437 echo "${step_name} is up to date (commit ${commit_id})"
438 fi
439 # Exit if last step.
440 if [ ${step_name} = ${LAST_STEP} ]; then
441 exit
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800442 fi
443}
444
445mkdir -p ${BUILD_DIR}
446cd ${BUILD_DIR}
447# In dependency order.
448check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
449check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800450# FIXME: re-enable when gNMI support becomes more stable
451# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
452# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800453check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200454check_and_do ${PI_COMMIT} PI do_PI PI
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800455check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
456check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone95e5afd2018-07-17 14:45:23 +0200457check_and_do master scapy-vxlan do_scapy-vxlan scapy-vxlan
458check_and_do master ptf do_ptf ptf
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800459
460echo "Done!"