blob: 8807e06655ea21e3518b109e02b00cd105381131 [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
31function do_requirements {
32 sudo apt update
33 sudo apt-get install -y --no-install-recommends \
34 autoconf \
35 automake \
36 bison \
37 build-essential \
38 cmake \
39 cpp \
40 curl \
41 flex \
42 git \
43 libavl-dev \
44 libboost-dev \
45 libboost-program-options-dev \
46 libboost-system-dev \
47 libboost-filesystem-dev \
48 libboost-thread-dev \
49 libboost-filesystem-dev \
50 libboost-program-options-dev \
51 libboost-system-dev \
52 libboost-test-dev \
53 libboost-thread-dev \
54 libc6-dev \
55 libev-dev \
56 libevent-dev \
57 libffi-dev \
58 libfl-dev \
59 libgc-dev \
60 libgc1c2 \
61 libgflags-dev \
62 libgmp-dev \
63 libgmp10 \
64 libgmpxx4ldbl \
65 libjudy-dev \
66 libpcap-dev \
67 libpcre3-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080068 libreadline6 \
69 libreadline6-dev \
70 libssl-dev \
71 libtool \
72 make \
73 mktemp \
74 pkg-config \
75 protobuf-c-compiler \
Carmelo Cascone57defd32018-05-11 14:34:01 -070076 python2.7 \
77 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080078 tcpdump \
79 wget \
80 unzip
81
Carmelo Cascone57defd32018-05-11 14:34:01 -070082 sudo -H pip install setuptools cffi grpcio scapy ipaddr
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080083}
84
85function do_requirements_1404 {
86 sudo apt install -y python-software-properties software-properties-common
87 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
88 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
89 sudo apt update
90 sudo apt install -y \
91 dpkg-dev \
92 g++-4.9 \
93 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +080094 cmake \
95 libbz2-dev
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080096
97 # Needed for p4c.
98 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
99 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800100
101 if [ -z "$(ldconfig -p | grep libboost_iostreams.so.1.58.0)" ]; then
102 do_boost
103 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800104}
105
106function do_requirements_1604 {
107 sudo apt-get update
108 sudo apt-get install -y --no-install-recommends \
109 ca-certificates \
110 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800111 libboost-iostreams1.58-dev \
112 libprotobuf-c-dev
113}
114
115function do_boost {
116 cd ${BUILD_DIR}
117 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
118 tar --bzip2 -xf boost_1_58_0.tar.bz2
119 cd boost_1_58_0
120
121 ./bootstrap.sh --with-libraries=iostreams
122 sudo ./b2 install
123 sudo ldconfig
124
125 cd ..
126 sudo rm -rf boost_1_58_0
127}
128
129function do_protobuf-c {
130 cd ${BUILD_DIR}
131 git clone https://github.com/protobuf-c/protobuf-c.git
132 cd protobuf-c
133
134 ./autogen.sh
135 ./configure --prefix=/usr
136 make -j${NUM_CORES}
137 sudo make install
138 sudo ldconfig
139
140 cd ..
141 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800142}
143
144function do_protobuf {
145 cd ${BUILD_DIR}
146 if [ ! -d protobuf ]; then
147 git clone https://github.com/google/protobuf.git
148 fi
149 cd protobuf
150 git fetch
151 git checkout ${PROTOBUF_COMMIT}
152
153 export CFLAGS="-Os"
154 export CXXFLAGS="-Os"
155 export LDFLAGS="-Wl,-s"
156 ./autogen.sh
157 ./configure --prefix=/usr
158 make -j${NUM_CORES}
159 sudo make install
160 sudo ldconfig
161 unset CFLAGS CXXFLAGS LDFLAGS
162}
163
164function do_grpc {
165 cd ${BUILD_DIR}
166 if [ ! -d grpc ]; then
167 git clone https://github.com/grpc/grpc.git
168 fi
169 cd grpc
170 git fetch
171 git checkout ${GRPC_COMMIT}
172 git submodule update --init
173
174 export LDFLAGS="-Wl,-s"
175 make -j${NUM_CORES}
176 sudo make install
177 sudo ldconfig
178 unset LDFLAGS
179}
180
181function do_libyang {
182 cd ${BUILD_DIR}
183 if [ ! -d libyang ]; then
184 git clone https://github.com/CESNET/libyang.git
185 fi
186 cd libyang
187 git fetch
188 git checkout ${LIBYANG_COMMIT}
189
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800190 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800191 cd build
192 cmake ..
193 make -j${NUM_CORES}
194 sudo make install
195 sudo ldconfig
196}
197
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800198function do_sysrepo_deps {
199 RELEASE=`lsb_release -rs`
200 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
201 do_protobuf-c
202 fi
203}
204
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800205function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800206 do_sysrepo_deps
207
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800208 cd ${BUILD_DIR}
209 if [ ! -d sysrepo ]; then
210 git clone https://github.com/sysrepo/sysrepo.git
211 fi
212 cd sysrepo
213 git fetch
214 git checkout ${SYSREPO_COMMIT}
215
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800216 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800217 cd build
218 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
219 -DCALL_TARGET_BINS_DIRECTLY=Off ..
220 make -j${NUM_CORES}
221 sudo make install
222 sudo ldconfig
223}
224
225function checkout_bmv2 {
226 cd ${BUILD_DIR}
227 if [ ! -d bmv2 ]; then
228 git clone https://github.com/p4lang/behavioral-model.git bmv2
229 fi
230 cd bmv2
231 git fetch
232 git checkout ${BMV2_COMMIT}
233}
234
235function do_pi_bmv2_deps {
236 checkout_bmv2
237 # From bmv2's install_deps.sh.
238 # Nanomsg is required also by p4runtime.
239 tmpdir=`mktemp -d -p .`
240 cd ${tmpdir}
241 bash ../travis/install-thrift.sh
242 bash ../travis/install-nanomsg.sh
243 sudo ldconfig
244 bash ../travis/install-nnpy.sh
245 cd ..
246 sudo rm -rf $tmpdir
247}
248
249function do_p4runtime {
250 cd ${BUILD_DIR}
251 if [ ! -d p4runtime ]; then
252 git clone https://github.com/p4lang/PI.git p4runtime
253 fi
254 cd p4runtime
255 git fetch
256 git checkout ${PI_COMMIT}
257 git submodule update --init --recursive
258
259 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800260 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
261 # ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
262 ./configure --with-proto 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800263 make -j${NUM_CORES}
264 sudo make install
265 sudo ldconfig
266
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800267 # FIXME: re-enable when gNMI support becomes more stable
268 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800269}
270
271function do_bmv2 {
272 checkout_bmv2
273
274 ./autogen.sh
275 ./configure --enable-debugger --with-pi 'CXXFLAGS=-O0 -g'
276 make -j${NUM_CORES}
277 sudo make install
278 sudo ldconfig
279
280 # Simple_switch_grpc target
281 cd targets/simple_switch_grpc
282 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800283
284 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
285 # ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
286 ./configure --with-thrift 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800287 make -j${NUM_CORES}
288 sudo make install
289 sudo ldconfig
290}
291
292function do_p4c {
293 cd ${BUILD_DIR}
294 if [ ! -d p4c ]; then
295 git clone https://github.com/p4lang/p4c.git
296 fi
297 cd p4c
298 git fetch
299 git checkout ${P4C_COMMIT}
300 git submodule update --init --recursive
301
302 mkdir -p build
303 cd build
304 cmake ..
305 make -j${NUM_CORES}
306 sudo make install
307 sudo ldconfig
308}
309
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800310function do_p4rt_test {
311 cd ${BUILD_DIR}
312 if [ ! -d p4rt-test ]; then
313 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
314 fi
315 cd p4rt-test
316 git pull origin master
317
318 sudo rm -f /usr/local/bin/p4rt-test
319 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
320}
321
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800322function check_commit {
323 if [ ! -e $2 ]; then
324 return 0 # true
325 fi
326 if [[ $(< $2) != "$1" ]]; then
327 return 0 # true
328 fi
329 return 1 # false
330}
331
332# The following is borrowed from Mininet's util/install.sh
333function version_ge {
334 # sort -V sorts by *version number*
335 latest=`printf "$1\n$2" | sort -V | tail -1`
336 # If $1 is latest version, then $1 >= $2
337 [ "$1" == "$latest" ]
338}
339
340MUST_DO_ALL=false
341DID_REQUIREMENTS=false
342function check_and_do {
343 # Check if the latest built commit is the same we are trying to build now,
344 # or if all projects must be built. If true builds this project.
345 commit_id="$1"
346 proj_dir="$2"
347 func_name="$3"
348 simple_name="$4"
Carmelo Cascone05354672018-04-10 13:24:03 -0700349 if [ ${MUST_DO_ALL} = true ] \
350 || [ ${commit_id} = "master" ] \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800351 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
352 echo "#"
353 echo "# Building ${simple_name} (${commit_id})"
354 echo "#"
355 # Print commands used to install to aid debugging
356 set -x
357 if ! ${DID_REQUIREMENTS} = true; then
358 do_requirements
359 # TODO consider other Linux distros; presently this script assumes
360 # that it is running on Ubuntu.
361 RELEASE=`lsb_release -rs`
362 if version_ge $RELEASE 16.04; then
363 do_requirements_1604
364 elif version_ge $RELEASE 14.04; then
365 do_requirements_1404
366 else
367 echo "Ubuntu version $RELEASE is not supported"
368 exit 1
369 fi
370 DID_REQUIREMENTS=true
371 fi
372 eval ${func_name}
373 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
374 # Build all next projects as they might depend on this one.
375 MUST_DO_ALL=true
376 # Disable printing to reduce output
377 set +x
378 else
379 echo "${proj_dir} is up to date (commit ${commit_id})"
380 fi
381}
382
383mkdir -p ${BUILD_DIR}
384cd ${BUILD_DIR}
385# In dependency order.
386check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
387check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800388# FIXME: re-enable when gNMI support becomes more stable
389# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
390# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800391check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
392check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
393check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
394check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800395check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800396
397echo "Done!"