blob: 9bf8840c05c3483a9d9fac9a94b2dde58f98112d [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
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
166}
167
168function do_grpc {
169 cd ${BUILD_DIR}
170 if [ ! -d grpc ]; then
171 git clone https://github.com/grpc/grpc.git
172 fi
173 cd grpc
174 git fetch
175 git checkout ${GRPC_COMMIT}
176 git submodule update --init
177
178 export LDFLAGS="-Wl,-s"
179 make -j${NUM_CORES}
180 sudo make install
181 sudo ldconfig
182 unset LDFLAGS
183}
184
185function do_libyang {
186 cd ${BUILD_DIR}
187 if [ ! -d libyang ]; then
188 git clone https://github.com/CESNET/libyang.git
189 fi
190 cd libyang
191 git fetch
192 git checkout ${LIBYANG_COMMIT}
193
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800194 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800195 cd build
196 cmake ..
197 make -j${NUM_CORES}
198 sudo make install
199 sudo ldconfig
200}
201
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800202function do_sysrepo_deps {
203 RELEASE=`lsb_release -rs`
204 if version_ge $RELEASE 14.04 && [ -z "$(ldconfig -p | grep libprotobuf-c)" ]; then
205 do_protobuf-c
206 fi
207}
208
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800209function do_sysrepo {
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800210 do_sysrepo_deps
211
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800212 cd ${BUILD_DIR}
213 if [ ! -d sysrepo ]; then
214 git clone https://github.com/sysrepo/sysrepo.git
215 fi
216 cd sysrepo
217 git fetch
218 git checkout ${SYSREPO_COMMIT}
219
Kevin Chuang53a9d5b2018-01-17 15:55:32 +0800220 mkdir -p build
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800221 cd build
222 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
223 -DCALL_TARGET_BINS_DIRECTLY=Off ..
224 make -j${NUM_CORES}
225 sudo make install
226 sudo ldconfig
227}
228
229function checkout_bmv2 {
230 cd ${BUILD_DIR}
231 if [ ! -d bmv2 ]; then
232 git clone https://github.com/p4lang/behavioral-model.git bmv2
233 fi
234 cd bmv2
235 git fetch
236 git checkout ${BMV2_COMMIT}
237}
238
239function do_pi_bmv2_deps {
240 checkout_bmv2
241 # From bmv2's install_deps.sh.
242 # Nanomsg is required also by p4runtime.
243 tmpdir=`mktemp -d -p .`
244 cd ${tmpdir}
245 bash ../travis/install-thrift.sh
246 bash ../travis/install-nanomsg.sh
247 sudo ldconfig
248 bash ../travis/install-nnpy.sh
249 cd ..
250 sudo rm -rf $tmpdir
251}
252
253function do_p4runtime {
254 cd ${BUILD_DIR}
255 if [ ! -d p4runtime ]; then
256 git clone https://github.com/p4lang/PI.git p4runtime
257 fi
258 cd p4runtime
259 git fetch
260 git checkout ${PI_COMMIT}
261 git submodule update --init --recursive
262
263 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800264 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
265 # ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
Carmelo Casconef02872d2018-06-20 08:49:02 +0200266 if [ "${DEBUG_FLAGS}" = true ] ; then
267 CONF_FLAGS="'CXXFLAGS=-O0 -g'"
268 else
269 CONF_FLAGS=""
270 fi
271 ./configure --with-proto ${CONF_FLAGS}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800272 make -j${NUM_CORES}
273 sudo make install
274 sudo ldconfig
275
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800276 # FIXME: re-enable when gNMI support becomes more stable
277 # sudo proto/sysrepo/install_yangs.sh
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800278}
279
280function do_bmv2 {
281 checkout_bmv2
282
283 ./autogen.sh
Carmelo Casconef02872d2018-06-20 08:49:02 +0200284 if [ "${DEBUG_FLAGS}" = true ] ; then
285 CONF_FLAGS="--enable-debugger 'CXXFLAGS=-O0 -g'"
286 else
287 CONF_FLAGS="--disable-logging-macros --disable-elogger --without-nanomsg"
288 fi
289 ./configure --with-pi ${CONF_FLAGS}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800290 make -j${NUM_CORES}
291 sudo make install
292 sudo ldconfig
293
294 # Simple_switch_grpc target
295 cd targets/simple_switch_grpc
296 ./autogen.sh
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800297
Carmelo Casconef02872d2018-06-20 08:49:02 +0200298 if [ "${DEBUG_FLAGS}" = true ] ; then
299 CONF_FLAGS="'CXXFLAGS=-O0 -g'"
300 else
301 CONF_FLAGS=""
302 fi
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800303 # FIXME: re-enable --with-sysrepo when gNMI support becomes more stable
304 # ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
Carmelo Casconef02872d2018-06-20 08:49:02 +0200305 ./configure --with-thrift ${CONF_FLAGS}
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800306 make -j${NUM_CORES}
307 sudo make install
308 sudo ldconfig
309}
310
311function do_p4c {
312 cd ${BUILD_DIR}
313 if [ ! -d p4c ]; then
314 git clone https://github.com/p4lang/p4c.git
315 fi
316 cd p4c
317 git fetch
318 git checkout ${P4C_COMMIT}
319 git submodule update --init --recursive
320
321 mkdir -p build
322 cd build
323 cmake ..
324 make -j${NUM_CORES}
325 sudo make install
326 sudo ldconfig
327}
328
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800329function do_p4rt_test {
330 cd ${BUILD_DIR}
331 if [ ! -d p4rt-test ]; then
332 git clone https://github.com/TakeshiTseng/P4-runtime-test-tool.git p4rt-test
333 fi
334 cd p4rt-test
335 git pull origin master
336
337 sudo rm -f /usr/local/bin/p4rt-test
338 sudo ln -s ${BUILD_DIR}/p4rt-test/main.py /usr/local/bin/p4rt-test
339}
340
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800341function check_commit {
342 if [ ! -e $2 ]; then
343 return 0 # true
344 fi
345 if [[ $(< $2) != "$1" ]]; then
346 return 0 # true
347 fi
348 return 1 # false
349}
350
351# The following is borrowed from Mininet's util/install.sh
352function version_ge {
353 # sort -V sorts by *version number*
354 latest=`printf "$1\n$2" | sort -V | tail -1`
355 # If $1 is latest version, then $1 >= $2
356 [ "$1" == "$latest" ]
357}
358
359MUST_DO_ALL=false
360DID_REQUIREMENTS=false
361function check_and_do {
362 # Check if the latest built commit is the same we are trying to build now,
363 # or if all projects must be built. If true builds this project.
364 commit_id="$1"
365 proj_dir="$2"
366 func_name="$3"
367 simple_name="$4"
Carmelo Cascone05354672018-04-10 13:24:03 -0700368 if [ ${MUST_DO_ALL} = true ] \
369 || [ ${commit_id} = "master" ] \
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800370 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
371 echo "#"
372 echo "# Building ${simple_name} (${commit_id})"
373 echo "#"
374 # Print commands used to install to aid debugging
375 set -x
376 if ! ${DID_REQUIREMENTS} = true; then
377 do_requirements
378 # TODO consider other Linux distros; presently this script assumes
379 # that it is running on Ubuntu.
380 RELEASE=`lsb_release -rs`
381 if version_ge $RELEASE 16.04; then
382 do_requirements_1604
383 elif version_ge $RELEASE 14.04; then
384 do_requirements_1404
385 else
386 echo "Ubuntu version $RELEASE is not supported"
387 exit 1
388 fi
389 DID_REQUIREMENTS=true
390 fi
391 eval ${func_name}
392 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
393 # Build all next projects as they might depend on this one.
394 MUST_DO_ALL=true
395 # Disable printing to reduce output
396 set +x
397 else
398 echo "${proj_dir} is up to date (commit ${commit_id})"
399 fi
400}
401
402mkdir -p ${BUILD_DIR}
403cd ${BUILD_DIR}
404# In dependency order.
405check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
406check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
Carmelo Cascone4f985cd2018-02-11 17:36:42 -0800407# FIXME: re-enable when gNMI support becomes more stable
408# check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
409# check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800410check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
411check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
412check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
413check_and_do ${P4C_COMMIT} p4c do_p4c p4c
Carmelo Cascone76b3ee62018-01-30 15:45:27 -0800414check_and_do ${P4RT_TEST_COMMIT} p4rt-test do_p4rt_test p4rt-test
Carmelo Casconeb7e618d2018-01-12 18:31:33 -0800415
416echo "Done!"