blob: 6a8d3a30de8834220a4c4ffe0516e414a6ce0bc8 [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)
12# -----------------------------------------------------------------------------
13
14# Exit on errors.
15set -e
16
17BUILD_DIR=~/p4tools
Esin Karaman971fb7f2017-12-28 13:44:52 +000018# in case BMV2_COMMIT value is updated, the same variable in
19# protocols/bmv2/thrift-api/BUCK file should also be updated
Carmelo Cascone6af4e172018-06-15 16:01:30 +020020BMV2_COMMIT="ed130d01be985d814c17de949839d484e76400b1"
21PI_COMMIT="59c940916b4f5b182f33b4788d8c410972eaecce"
22P4C_COMMIT="618d15155dcc2d784cc14a8e83131b407cf893e2"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080023PROTOBUF_COMMIT="tags/v3.2.0"
24GRPC_COMMIT="tags/v1.3.2"
25LIBYANG_COMMIT="v0.14-r1"
26SYSREPO_COMMIT="v0.7.2"
Carmelo Cascone76b3ee62018-01-30 15:45:27 -080027P4RT_TEST_COMMIT="master"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080028
29NUM_CORES=`grep -c ^processor /proc/cpuinfo`
30
Carmelo Casconef02872d2018-06-20 08:49:02 +020031# If false, build tools without debug features to improve throughput of BMv2 and
32# reduce CPU/memory footprint.
33DEBUG_FLAGS=${DEBUG_FLAGS:-true}
34
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080035function do_requirements {
36 sudo apt update
37 sudo apt-get install -y --no-install-recommends \
38 autoconf \
39 automake \
40 bison \
41 build-essential \
42 cmake \
43 cpp \
44 curl \
45 flex \
46 git \
47 libavl-dev \
48 libboost-dev \
49 libboost-program-options-dev \
50 libboost-system-dev \
51 libboost-filesystem-dev \
52 libboost-thread-dev \
53 libboost-filesystem-dev \
54 libboost-program-options-dev \
55 libboost-system-dev \
56 libboost-test-dev \
57 libboost-thread-dev \
58 libc6-dev \
59 libev-dev \
60 libevent-dev \
61 libffi-dev \
62 libfl-dev \
63 libgc-dev \
64 libgc1c2 \
65 libgflags-dev \
66 libgmp-dev \
67 libgmp10 \
68 libgmpxx4ldbl \
69 libjudy-dev \
70 libpcap-dev \
71 libpcre3-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080072 libreadline6 \
73 libreadline6-dev \
74 libssl-dev \
75 libtool \
76 make \
77 mktemp \
78 pkg-config \
79 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070080 python2.7 \
81 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080082 tcpdump \
83 wget \
84 unzip
85
Carmelo Cascone57defd32018-05-11 14:34:01 -070086 sudo -H pip install setuptools cffi grpcio scapy ipaddr
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080087}
88
89function do_requirements_1404 {
90 sudo apt install -y python-software-properties software-properties-common
91 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
92 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
93 sudo apt update
94 sudo apt install -y \
95 dpkg-dev \
96 g++-4.9 \
97 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +080098 cmake \
99 libbz2-dev
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800100
101 # Needed for p4c.
102 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
103 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800104
105 if [ -z "$(ldconfig -p | grep libboost_iostreams.so.1.58.0)" ]; then
106 do_boost
107 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800108}
109
110function do_requirements_1604 {
111 sudo apt-get update
112 sudo apt-get install -y --no-install-recommends \
113 ca-certificates \
114 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800115 libboost-iostreams1.58-dev \
116 libprotobuf-c-dev
117}
118
119function do_boost {
120 cd ${BUILD_DIR}
121 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
122 tar --bzip2 -xf boost_1_58_0.tar.bz2
123 cd boost_1_58_0
124
125 ./bootstrap.sh --with-libraries=iostreams
126 sudo ./b2 install
127 sudo ldconfig
128
129 cd ..
130 sudo rm -rf boost_1_58_0
131}
132
133function do_protobuf-c {
134 cd ${BUILD_DIR}
135 git clone https://github.com/protobuf-c/protobuf-c.git
136 cd protobuf-c
137
138 ./autogen.sh
139 ./configure --prefix=/usr
140 make -j${NUM_CORES}
141 sudo make install
142 sudo ldconfig
143
144 cd ..
145 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800146}
147
148function do_protobuf {
149 cd ${BUILD_DIR}
150 if [ ! -d protobuf ]; then
151 git clone https://github.com/google/protobuf.git
152 fi
153 cd protobuf
154 git fetch
155 git checkout ${PROTOBUF_COMMIT}
156
157 export CFLAGS="-Os"
158 export CXXFLAGS="-Os"
159 export LDFLAGS="-Wl,-s"
160 ./autogen.sh
161 ./configure --prefix=/usr
162 make -j${NUM_CORES}
163 sudo make install
164 sudo ldconfig
165 unset CFLAGS CXXFLAGS LDFLAGS
166}
167
168function do_grpc {
169 cd ${BUILD_DIR}
170 if [ ! -d grpc ]; then
171 git clone https://github.com/grpc/grpc.git
172 fi
173 cd grpc
174 git fetch
175 git checkout ${GRPC_COMMIT}
176 git submodule update --init
177
178 export LDFLAGS="-Wl,-s"
179 make -j${NUM_CORES}
180 sudo make install
181 sudo ldconfig
182 unset LDFLAGS
183}
184
185function do_libyang {
186 cd ${BUILD_DIR}
187 if [ ! -d libyang ]; then
188 git clone https://github.com/CESNET/libyang.git
189 fi
190 cd libyang
191 git fetch
192 git checkout ${LIBYANG_COMMIT}
193
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800194 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800195 cd build
196 cmake ..
197 make -j${NUM_CORES}
198 sudo make install
199 sudo ldconfig
200}
201
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800202function do_sysrepo_deps {
203 RELEASE=`lsb_release -rs`
204 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
205 do_protobuf-c
206 fi
207}
208
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800209function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800210 do_sysrepo_deps
211
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800212 cd ${BUILD_DIR}
213 if [ ! -d sysrepo ]; then
214 git clone https://github.com/sysrepo/sysrepo.git
215 fi
216 cd sysrepo
217 git fetch
218 git checkout ${SYSREPO_COMMIT}
219
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800220 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800221 cd build
222 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
223 -DCALL_TARGET_BINS_DIRECTLY=Off ..
224 make -j${NUM_CORES}
225 sudo make install
226 sudo ldconfig
227}
228
229function checkout_bmv2 {
230 cd ${BUILD_DIR}
231 if [ ! -d bmv2 ]; then
232 git clone https://github.com/p4lang/behavioral-model.git bmv2
233 fi
234 cd bmv2
235 git fetch
236 git checkout ${BMV2_COMMIT}
237}
238
239function do_pi_bmv2_deps {
240 checkout_bmv2
241 # From bmv2's install_deps.sh.
242 # Nanomsg is required also by p4runtime.
243 tmpdir=`mktemp -d -p .`
244 cd ${tmpdir}
245 bash ../travis/install-thrift.sh
246 bash ../travis/install-nanomsg.sh
247 sudo ldconfig
248 bash ../travis/install-nnpy.sh
249 cd ..
250 sudo rm -rf $tmpdir
251}
252
253function do_p4runtime {
254 cd ${BUILD_DIR}
255 if [ ! -d p4runtime ]; then
256 git clone https://github.com/p4lang/PI.git p4runtime
257 fi
258 cd p4runtime
259 git fetch
260 git checkout ${PI_COMMIT}
261 git submodule update --init --recursive
262
263 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800264 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
265 # ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
Carmelo Casconef02872d2018-06-20 08:49:02 +0200266 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef742a112018-07-03 19:28:18 +0200267 ./configure --with-proto "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200268 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200269 ./configure --with-proto
Carmelo Casconef02872d2018-06-20 08:49:02 +0200270 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800271 make -j${NUM_CORES}
272 sudo make install
273 sudo ldconfig
274
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800275 # FIXME: re-enable when gNMI support becomes more stable
276 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800277}
278
279function do_bmv2 {
280 checkout_bmv2
281
282 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200283 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef742a112018-07-03 19:28:18 +0200284 ./configure --with-pi --enable-debugger "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200285 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200286 ./configure --with-pi --disable-logging-macros --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200287 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800288 make -j${NUM_CORES}
289 sudo make install
290 sudo ldconfig
291
292 # Simple_switch_grpc target
293 cd targets/simple_switch_grpc
294 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800295
Carmelo Casconef02872d2018-06-20 08:49:02 +0200296 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef742a112018-07-03 19:28:18 +0200297 ./configure --with-thrift "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200298 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200299 ./configure --with-thrift
Carmelo Casconef02872d2018-06-20 08:49:02 +0200300 fi
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800301 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
302 # ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800303 make -j${NUM_CORES}
304 sudo make install
305 sudo ldconfig
306}
307
308function do_p4c {
309 cd ${BUILD_DIR}
310 if [ ! -d p4c ]; then
311 git clone https://github.com/p4lang/p4c.git
312 fi
313 cd p4c
314 git fetch
315 git checkout ${P4C_COMMIT}
316 git submodule update --init --recursive
317
318 mkdir -p build
319 cd build
320 cmake ..
321 make -j${NUM_CORES}
322 sudo make install
323 sudo ldconfig
324}
325
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800326function do_p4rt_test {
327 cd ${BUILD_DIR}
328 if [ ! -d p4rt-test ]; then
329 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
330 fi
331 cd p4rt-test
332 git pull origin master
333
334 sudo rm -f /usr/local/bin/p4rt-test
335 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
336}
337
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800338function check_commit {
339 if [ ! -e $2 ]; then
340 return 0 # true
341 fi
342 if [[ $(< $2) != "$1" ]]; then
343 return 0 # true
344 fi
345 return 1 # false
346}
347
348# The following is borrowed from Mininet's util/install.sh
349function version_ge {
350 # sort -V sorts by *version number*
351 latest=`printf "$1\n$2" | sort -V | tail -1`
352 # If $1 is latest version, then $1 >= $2
353 [ "$1" == "$latest" ]
354}
355
356MUST_DO_ALL=false
357DID_REQUIREMENTS=false
358function check_and_do {
359 # Check if the latest built commit is the same we are trying to build now,
360 # or if all projects must be built. If true builds this project.
361 commit_id="$1"
362 proj_dir="$2"
363 func_name="$3"
364 simple_name="$4"
Carmelo Cascone05354672018-04-10 13:24:03 -0700365 if [ ${MUST_DO_ALL} = true ] \
366 || [ ${commit_id} = "master" ] \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800367 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
368 echo "#"
369 echo "# Building ${simple_name} (${commit_id})"
370 echo "#"
371 # Print commands used to install to aid debugging
372 set -x
373 if ! ${DID_REQUIREMENTS} = true; then
374 do_requirements
375 # TODO consider other Linux distros; presently this script assumes
376 # that it is running on Ubuntu.
377 RELEASE=`lsb_release -rs`
378 if version_ge $RELEASE 16.04; then
379 do_requirements_1604
380 elif version_ge $RELEASE 14.04; then
381 do_requirements_1404
382 else
383 echo "Ubuntu version $RELEASE is not supported"
384 exit 1
385 fi
386 DID_REQUIREMENTS=true
387 fi
388 eval ${func_name}
389 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
390 # Build all next projects as they might depend on this one.
391 MUST_DO_ALL=true
392 # Disable printing to reduce output
393 set +x
394 else
395 echo "${proj_dir} is up to date (commit ${commit_id})"
396 fi
397}
398
399mkdir -p ${BUILD_DIR}
400cd ${BUILD_DIR}
401# In dependency order.
402check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
403check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800404# FIXME: re-enable when gNMI support becomes more stable
405# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
406# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800407check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
408check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
409check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
410check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800411check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800412
413echo "Done!"