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