blob: e6c7269280f3c79a48c96006fc3a37ef7732444a [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 Casconef645e842018-07-16 18:31:52 +020020BMV2_COMMIT="a3f0ebe4c0f10a656f8aa1ad68cb20402a62b0ee"
21PI_COMMIT="7e94b025bac6db63bc8534e5dd21a008984e38bc"
22P4C_COMMIT="2d089af757212a057c6690998861ef67439305f4"
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
Carmelo Casconef645e842018-07-16 18:31:52 +0200166
167 cd python
168 sudo python setup.py install --cpp_implementation
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800169}
170
171function do_grpc {
172 cd ${BUILD_DIR}
173 if [ ! -d grpc ]; then
174 git clone https://github.com/grpc/grpc.git
175 fi
176 cd grpc
177 git fetch
178 git checkout ${GRPC_COMMIT}
179 git submodule update --init
180
181 export LDFLAGS="-Wl,-s"
182 make -j${NUM_CORES}
183 sudo make install
184 sudo ldconfig
185 unset LDFLAGS
Carmelo Casconef645e842018-07-16 18:31:52 +0200186
187 sudo pip install -r requirements.txt
188 sudo pip install .
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800189}
190
191function do_libyang {
192 cd ${BUILD_DIR}
193 if [ ! -d libyang ]; then
194 git clone https://github.com/CESNET/libyang.git
195 fi
196 cd libyang
197 git fetch
198 git checkout ${LIBYANG_COMMIT}
199
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800200 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800201 cd build
202 cmake ..
203 make -j${NUM_CORES}
204 sudo make install
205 sudo ldconfig
206}
207
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800208function do_sysrepo_deps {
209 RELEASE=`lsb_release -rs`
210 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
211 do_protobuf-c
212 fi
213}
214
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800215function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800216 do_sysrepo_deps
217
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800218 cd ${BUILD_DIR}
219 if [ ! -d sysrepo ]; then
220 git clone https://github.com/sysrepo/sysrepo.git
221 fi
222 cd sysrepo
223 git fetch
224 git checkout ${SYSREPO_COMMIT}
225
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800226 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800227 cd build
228 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
229 -DCALL_TARGET_BINS_DIRECTLY=Off ..
230 make -j${NUM_CORES}
231 sudo make install
232 sudo ldconfig
233}
234
235function checkout_bmv2 {
236 cd ${BUILD_DIR}
237 if [ ! -d bmv2 ]; then
238 git clone https://github.com/p4lang/behavioral-model.git bmv2
239 fi
240 cd bmv2
241 git fetch
242 git checkout ${BMV2_COMMIT}
243}
244
245function do_pi_bmv2_deps {
246 checkout_bmv2
247 # From bmv2's install_deps.sh.
248 # Nanomsg is required also by p4runtime.
249 tmpdir=`mktemp -d -p .`
250 cd ${tmpdir}
251 bash ../travis/install-thrift.sh
252 bash ../travis/install-nanomsg.sh
253 sudo ldconfig
254 bash ../travis/install-nnpy.sh
255 cd ..
256 sudo rm -rf $tmpdir
257}
258
259function do_p4runtime {
260 cd ${BUILD_DIR}
261 if [ ! -d p4runtime ]; then
262 git clone https://github.com/p4lang/PI.git p4runtime
263 fi
264 cd p4runtime
265 git fetch
266 git checkout ${PI_COMMIT}
267 git submodule update --init --recursive
268
269 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800270 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
271 # ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
Carmelo Casconef02872d2018-06-20 08:49:02 +0200272 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef742a112018-07-03 19:28:18 +0200273 ./configure --with-proto "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200274 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200275 ./configure --with-proto
Carmelo Casconef02872d2018-06-20 08:49:02 +0200276 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800277 make -j${NUM_CORES}
278 sudo make install
279 sudo ldconfig
280
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800281 # FIXME: re-enable when gNMI support becomes more stable
282 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800283}
284
285function do_bmv2 {
286 checkout_bmv2
287
288 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200289 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef645e842018-07-16 18:31:52 +0200290 ./configure --with-pi --enable-debugger --disable-elogger "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200291 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200292 ./configure --with-pi --disable-logging-macros --disable-elogger --without-nanomsg
Carmelo Casconef02872d2018-06-20 08:49:02 +0200293 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800294 make -j${NUM_CORES}
295 sudo make install
296 sudo ldconfig
297
298 # Simple_switch_grpc target
299 cd targets/simple_switch_grpc
300 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800301
Carmelo Casconef02872d2018-06-20 08:49:02 +0200302 if [ "${DEBUG_FLAGS}" = true ] ; then
Carmelo Casconef742a112018-07-03 19:28:18 +0200303 ./configure --with-thrift "CXXFLAGS=-O0 -g"
Carmelo Casconef02872d2018-06-20 08:49:02 +0200304 else
Carmelo Casconef742a112018-07-03 19:28:18 +0200305 ./configure --with-thrift
Carmelo Casconef02872d2018-06-20 08:49:02 +0200306 fi
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800307 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
308 # ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800309 make -j${NUM_CORES}
310 sudo make install
311 sudo ldconfig
312}
313
314function do_p4c {
315 cd ${BUILD_DIR}
316 if [ ! -d p4c ]; then
317 git clone https://github.com/p4lang/p4c.git
318 fi
319 cd p4c
320 git fetch
321 git checkout ${P4C_COMMIT}
322 git submodule update --init --recursive
323
324 mkdir -p build
325 cd build
326 cmake ..
327 make -j${NUM_CORES}
328 sudo make install
329 sudo ldconfig
330}
331
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800332function do_p4rt_test {
333 cd ${BUILD_DIR}
334 if [ ! -d p4rt-test ]; then
335 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
336 fi
337 cd p4rt-test
338 git pull origin master
339
340 sudo rm -f /usr/local/bin/p4rt-test
341 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
342}
343
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800344function check_commit {
345 if [ ! -e $2 ]; then
346 return 0 # true
347 fi
348 if [[ $(< $2) != "$1" ]]; then
349 return 0 # true
350 fi
351 return 1 # false
352}
353
354# The following is borrowed from Mininet's util/install.sh
355function version_ge {
356 # sort -V sorts by *version number*
357 latest=`printf "$1\n$2" | sort -V | tail -1`
358 # If $1 is latest version, then $1 >= $2
359 [ "$1" == "$latest" ]
360}
361
362MUST_DO_ALL=false
363DID_REQUIREMENTS=false
364function check_and_do {
365 # Check if the latest built commit is the same we are trying to build now,
366 # or if all projects must be built. If true builds this project.
367 commit_id="$1"
368 proj_dir="$2"
369 func_name="$3"
370 simple_name="$4"
Carmelo Cascone05354672018-04-10 13:24:03 -0700371 if [ ${MUST_DO_ALL} = true ] \
372 || [ ${commit_id} = "master" ] \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800373 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
374 echo "#"
375 echo "# Building ${simple_name} (${commit_id})"
376 echo "#"
377 # Print commands used to install to aid debugging
378 set -x
379 if ! ${DID_REQUIREMENTS} = true; then
380 do_requirements
381 # TODO consider other Linux distros; presently this script assumes
382 # that it is running on Ubuntu.
383 RELEASE=`lsb_release -rs`
384 if version_ge $RELEASE 16.04; then
385 do_requirements_1604
386 elif version_ge $RELEASE 14.04; then
387 do_requirements_1404
388 else
389 echo "Ubuntu version $RELEASE is not supported"
390 exit 1
391 fi
392 DID_REQUIREMENTS=true
393 fi
394 eval ${func_name}
395 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
396 # Build all next projects as they might depend on this one.
397 MUST_DO_ALL=true
398 # Disable printing to reduce output
399 set +x
400 else
401 echo "${proj_dir} is up to date (commit ${commit_id})"
402 fi
403}
404
405mkdir -p ${BUILD_DIR}
406cd ${BUILD_DIR}
407# In dependency order.
408check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
409check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800410# FIXME: re-enable when gNMI support becomes more stable
411# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
412# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800413check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
414check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
415check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
416check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800417check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800418
419echo "Done!"