blob: f3df6a47beee5dad7dc3226e56408c1b69612225 [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
262 ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
263 make -j${NUM_CORES}
264 sudo make install
265 sudo ldconfig
266
267 sudo proto/sysrepo/install_yangs.sh
268}
269
270function do_bmv2 {
271 checkout_bmv2
272
273 ./autogen.sh
274 ./configure --enable-debugger --with-pi 'CXXFLAGS=-O0 -g'
275 make -j${NUM_CORES}
276 sudo make install
277 sudo ldconfig
278
279 # Simple_switch_grpc target
280 cd targets/simple_switch_grpc
281 ./autogen.sh
282 ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
283 make -j${NUM_CORES}
284 sudo make install
285 sudo ldconfig
286}
287
288function do_p4c {
289 cd ${BUILD_DIR}
290 if [ ! -d p4c ]; then
291 git clone https://github.com/p4lang/p4c.git
292 fi
293 cd p4c
294 git fetch
295 git checkout ${P4C_COMMIT}
296 git submodule update --init --recursive
297
298 mkdir -p build
299 cd build
300 cmake ..
301 make -j${NUM_CORES}
302 sudo make install
303 sudo ldconfig
304}
305
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800306function do_p4rt_test {
307 cd ${BUILD_DIR}
308 if [ ! -d p4rt-test ]; then
309 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
310 fi
311 cd p4rt-test
312 git pull origin master
313
314 sudo rm -f /usr/local/bin/p4rt-test
315 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
316}
317
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800318function check_commit {
319 if [ ! -e $2 ]; then
320 return 0 # true
321 fi
322 if [[ $(< $2) != "$1" ]]; then
323 return 0 # true
324 fi
325 return 1 # false
326}
327
328# The following is borrowed from Mininet's util/install.sh
329function version_ge {
330 # sort -V sorts by *version number*
331 latest=`printf "$1\n$2" | sort -V | tail -1`
332 # If $1 is latest version, then $1 >= $2
333 [ "$1" == "$latest" ]
334}
335
336MUST_DO_ALL=false
337DID_REQUIREMENTS=false
338function check_and_do {
339 # Check if the latest built commit is the same we are trying to build now,
340 # or if all projects must be built. If true builds this project.
341 commit_id="$1"
342 proj_dir="$2"
343 func_name="$3"
344 simple_name="$4"
345 if ${MUST_DO_ALL} = true \
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800346 || ${commit_id} = "master" \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800347 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
348 echo "#"
349 echo "# Building ${simple_name} (${commit_id})"
350 echo "#"
351 # Print commands used to install to aid debugging
352 set -x
353 if ! ${DID_REQUIREMENTS} = true; then
354 do_requirements
355 # TODO consider other Linux distros; presently this script assumes
356 # that it is running on Ubuntu.
357 RELEASE=`lsb_release -rs`
358 if version_ge $RELEASE 16.04; then
359 do_requirements_1604
360 elif version_ge $RELEASE 14.04; then
361 do_requirements_1404
362 else
363 echo "Ubuntu version $RELEASE is not supported"
364 exit 1
365 fi
366 DID_REQUIREMENTS=true
367 fi
368 eval ${func_name}
369 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
370 # Build all next projects as they might depend on this one.
371 MUST_DO_ALL=true
372 # Disable printing to reduce output
373 set +x
374 else
375 echo "${proj_dir} is up to date (commit ${commit_id})"
376 fi
377}
378
379mkdir -p ${BUILD_DIR}
380cd ${BUILD_DIR}
381# In dependency order.
382check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
383check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
384check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
385check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
386check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
387check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
388check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
389check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800390check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800391
392echo "Done!"