blob: 04b9bc6476bf61e76dce9f0d08e9fa20f9fb8711 [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
Carmelo Cascone6af4e172018-06-15 16:01:30 +020018BMV2_COMMIT="ed130d01be985d814c17de949839d484e76400b1"
19PI_COMMIT="59c940916b4f5b182f33b4788d8c410972eaecce"
20P4C_COMMIT="618d15155dcc2d784cc14a8e83131b407cf893e2"
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080021PROTOBUF_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 \
Carmelo Cascone57defd32018-05-11 14:34:01 -070074 python2.7 \
75 python2.7-dev \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080076 tcpdump \
77 wget \
78 unzip
79
Carmelo Cascone57defd32018-05-11 14:34:01 -070080 sudo -H pip install setuptools cffi grpcio scapy ipaddr
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080081}
82
83function do_requirements_1404 {
84 sudo apt install -y python-software-properties software-properties-common
85 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
86 sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
87 sudo apt update
88 sudo apt install -y \
89 dpkg-dev \
90 g++-4.9 \
91 gcc-4.9 \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +080092 cmake \
93 libbz2-dev
Carmelo Casconeb7e618d2018-01-12 18:31:33 -080094
95 # Needed for p4c.
96 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
97 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
Kevin Chuang53a9d5b2018-01-17 15:55:32 +080098
99 if [ -z "$(ldconfig -p | grep libboost_iostreams.so.1.58.0)" ]; then
100 do_boost
101 fi
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800102}
103
104function do_requirements_1604 {
105 sudo apt-get update
106 sudo apt-get install -y --no-install-recommends \
107 ca-certificates \
108 g++ \
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800109 libboost-iostreams1.58-dev \
110 libprotobuf-c-dev
111}
112
113function do_boost {
114 cd ${BUILD_DIR}
115 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
116 tar --bzip2 -xf boost_1_58_0.tar.bz2
117 cd boost_1_58_0
118
119 ./bootstrap.sh --with-libraries=iostreams
120 sudo ./b2 install
121 sudo ldconfig
122
123 cd ..
124 sudo rm -rf boost_1_58_0
125}
126
127function do_protobuf-c {
128 cd ${BUILD_DIR}
129 git clone https://github.com/protobuf-c/protobuf-c.git
130 cd protobuf-c
131
132 ./autogen.sh
133 ./configure --prefix=/usr
134 make -j${NUM_CORES}
135 sudo make install
136 sudo ldconfig
137
138 cd ..
139 sudo rm -rf protobuf-c
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800140}
141
142function do_protobuf {
143 cd ${BUILD_DIR}
144 if [ ! -d protobuf ]; then
145 git clone https://github.com/google/protobuf.git
146 fi
147 cd protobuf
148 git fetch
149 git checkout ${PROTOBUF_COMMIT}
150
151 export CFLAGS="-Os"
152 export CXXFLAGS="-Os"
153 export LDFLAGS="-Wl,-s"
154 ./autogen.sh
155 ./configure --prefix=/usr
156 make -j${NUM_CORES}
157 sudo make install
158 sudo ldconfig
159 unset CFLAGS CXXFLAGS LDFLAGS
160}
161
162function do_grpc {
163 cd ${BUILD_DIR}
164 if [ ! -d grpc ]; then
165 git clone https://github.com/grpc/grpc.git
166 fi
167 cd grpc
168 git fetch
169 git checkout ${GRPC_COMMIT}
170 git submodule update --init
171
172 export LDFLAGS="-Wl,-s"
173 make -j${NUM_CORES}
174 sudo make install
175 sudo ldconfig
176 unset LDFLAGS
177}
178
179function do_libyang {
180 cd ${BUILD_DIR}
181 if [ ! -d libyang ]; then
182 git clone https://github.com/CESNET/libyang.git
183 fi
184 cd libyang
185 git fetch
186 git checkout ${LIBYANG_COMMIT}
187
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800188 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800189 cd build
190 cmake ..
191 make -j${NUM_CORES}
192 sudo make install
193 sudo ldconfig
194}
195
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800196function do_sysrepo_deps {
197 RELEASE=`lsb_release -rs`
198 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
199 do_protobuf-c
200 fi
201}
202
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800203function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800204 do_sysrepo_deps
205
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800206 cd ${BUILD_DIR}
207 if [ ! -d sysrepo ]; then
208 git clone https://github.com/sysrepo/sysrepo.git
209 fi
210 cd sysrepo
211 git fetch
212 git checkout ${SYSREPO_COMMIT}
213
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800214 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800215 cd build
216 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
217 -DCALL_TARGET_BINS_DIRECTLY=Off ..
218 make -j${NUM_CORES}
219 sudo make install
220 sudo ldconfig
221}
222
223function checkout_bmv2 {
224 cd ${BUILD_DIR}
225 if [ ! -d bmv2 ]; then
226 git clone https://github.com/p4lang/behavioral-model.git bmv2
227 fi
228 cd bmv2
229 git fetch
230 git checkout ${BMV2_COMMIT}
231}
232
233function do_pi_bmv2_deps {
234 checkout_bmv2
235 # From bmv2's install_deps.sh.
236 # Nanomsg is required also by p4runtime.
237 tmpdir=`mktemp -d -p .`
238 cd ${tmpdir}
239 bash ../travis/install-thrift.sh
240 bash ../travis/install-nanomsg.sh
241 sudo ldconfig
242 bash ../travis/install-nnpy.sh
243 cd ..
244 sudo rm -rf $tmpdir
245}
246
247function do_p4runtime {
248 cd ${BUILD_DIR}
249 if [ ! -d p4runtime ]; then
250 git clone https://github.com/p4lang/PI.git p4runtime
251 fi
252 cd p4runtime
253 git fetch
254 git checkout ${PI_COMMIT}
255 git submodule update --init --recursive
256
257 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800258 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
259 # ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
260 ./configure --with-proto 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800261 make -j${NUM_CORES}
262 sudo make install
263 sudo ldconfig
264
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800265 # FIXME: re-enable when gNMI support becomes more stable
266 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800267}
268
269function do_bmv2 {
270 checkout_bmv2
271
272 ./autogen.sh
273 ./configure --enable-debugger --with-pi 'CXXFLAGS=-O0 -g'
274 make -j${NUM_CORES}
275 sudo make install
276 sudo ldconfig
277
278 # Simple_switch_grpc target
279 cd targets/simple_switch_grpc
280 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800281
282 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
283 # ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
284 ./configure --with-thrift 'CXXFLAGS=-O0 -g'
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800285 make -j${NUM_CORES}
286 sudo make install
287 sudo ldconfig
288}
289
290function do_p4c {
291 cd ${BUILD_DIR}
292 if [ ! -d p4c ]; then
293 git clone https://github.com/p4lang/p4c.git
294 fi
295 cd p4c
296 git fetch
297 git checkout ${P4C_COMMIT}
298 git submodule update --init --recursive
299
300 mkdir -p build
301 cd build
302 cmake ..
303 make -j${NUM_CORES}
304 sudo make install
305 sudo ldconfig
306}
307
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800308function do_p4rt_test {
309 cd ${BUILD_DIR}
310 if [ ! -d p4rt-test ]; then
311 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
312 fi
313 cd p4rt-test
314 git pull origin master
315
316 sudo rm -f /usr/local/bin/p4rt-test
317 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
318}
319
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800320function check_commit {
321 if [ ! -e $2 ]; then
322 return 0 # true
323 fi
324 if [[ $(< $2) != "$1" ]]; then
325 return 0 # true
326 fi
327 return 1 # false
328}
329
330# The following is borrowed from Mininet's util/install.sh
331function version_ge {
332 # sort -V sorts by *version number*
333 latest=`printf "$1\n$2" | sort -V | tail -1`
334 # If $1 is latest version, then $1 >= $2
335 [ "$1" == "$latest" ]
336}
337
338MUST_DO_ALL=false
339DID_REQUIREMENTS=false
340function check_and_do {
341 # Check if the latest built commit is the same we are trying to build now,
342 # or if all projects must be built. If true builds this project.
343 commit_id="$1"
344 proj_dir="$2"
345 func_name="$3"
346 simple_name="$4"
Carmelo Cascone05354672018-04-10 13:24:03 -0700347 if [ ${MUST_DO_ALL} = true ] \
348 || [ ${commit_id} = "master" ] \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800349 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
350 echo "#"
351 echo "# Building ${simple_name} (${commit_id})"
352 echo "#"
353 # Print commands used to install to aid debugging
354 set -x
355 if ! ${DID_REQUIREMENTS} = true; then
356 do_requirements
357 # TODO consider other Linux distros; presently this script assumes
358 # that it is running on Ubuntu.
359 RELEASE=`lsb_release -rs`
360 if version_ge $RELEASE 16.04; then
361 do_requirements_1604
362 elif version_ge $RELEASE 14.04; then
363 do_requirements_1404
364 else
365 echo "Ubuntu version $RELEASE is not supported"
366 exit 1
367 fi
368 DID_REQUIREMENTS=true
369 fi
370 eval ${func_name}
371 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
372 # Build all next projects as they might depend on this one.
373 MUST_DO_ALL=true
374 # Disable printing to reduce output
375 set +x
376 else
377 echo "${proj_dir} is up to date (commit ${commit_id})"
378 fi
379}
380
381mkdir -p ${BUILD_DIR}
382cd ${BUILD_DIR}
383# In dependency order.
384check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
385check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800386# FIXME: re-enable when gNMI support becomes more stable
387# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
388# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800389check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
390check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
391check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
392check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800393check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800394
395echo "Done!"