blob: 00f1b4b8a80e2e71ad40ea59227c0c95ac2587c6 [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"
25
26NUM_CORES=`grep -c ^processor /proc/cpuinfo`
27
28function do_requirements {
29 sudo apt update
30 sudo apt-get install -y --no-install-recommends \
31 autoconf \
32 automake \
33 bison \
34 build-essential \
35 cmake \
36 cpp \
37 curl \
38 flex \
39 git \
40 libavl-dev \
41 libboost-dev \
42 libboost-program-options-dev \
43 libboost-system-dev \
44 libboost-filesystem-dev \
45 libboost-thread-dev \
46 libboost-filesystem-dev \
47 libboost-program-options-dev \
48 libboost-system-dev \
49 libboost-test-dev \
50 libboost-thread-dev \
51 libc6-dev \
52 libev-dev \
53 libevent-dev \
54 libffi-dev \
55 libfl-dev \
56 libgc-dev \
57 libgc1c2 \
58 libgflags-dev \
59 libgmp-dev \
60 libgmp10 \
61 libgmpxx4ldbl \
62 libjudy-dev \
63 libpcap-dev \
64 libpcre3-dev \
65 libprotobuf-c-dev \
66 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 \
96 libboost-iostreams-dev
97
98 # Needed for p4c.
99 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
100 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
101}
102
103function do_requirements_1604 {
104 sudo apt-get update
105 sudo apt-get install -y --no-install-recommends \
106 ca-certificates \
107 g++ \
108 libboost-iostreams1.58-dev
109}
110
111function do_protobuf {
112 cd ${BUILD_DIR}
113 if [ ! -d protobuf ]; then
114 git clone https://github.com/google/protobuf.git
115 fi
116 cd protobuf
117 git fetch
118 git checkout ${PROTOBUF_COMMIT}
119
120 export CFLAGS="-Os"
121 export CXXFLAGS="-Os"
122 export LDFLAGS="-Wl,-s"
123 ./autogen.sh
124 ./configure --prefix=/usr
125 make -j${NUM_CORES}
126 sudo make install
127 sudo ldconfig
128 unset CFLAGS CXXFLAGS LDFLAGS
129}
130
131function do_grpc {
132 cd ${BUILD_DIR}
133 if [ ! -d grpc ]; then
134 git clone https://github.com/grpc/grpc.git
135 fi
136 cd grpc
137 git fetch
138 git checkout ${GRPC_COMMIT}
139 git submodule update --init
140
141 export LDFLAGS="-Wl,-s"
142 make -j${NUM_CORES}
143 sudo make install
144 sudo ldconfig
145 unset LDFLAGS
146}
147
148function do_libyang {
149 cd ${BUILD_DIR}
150 if [ ! -d libyang ]; then
151 git clone https://github.com/CESNET/libyang.git
152 fi
153 cd libyang
154 git fetch
155 git checkout ${LIBYANG_COMMIT}
156
157 mkdir build
158 cd build
159 cmake ..
160 make -j${NUM_CORES}
161 sudo make install
162 sudo ldconfig
163}
164
165function do_sysrepo {
166 cd ${BUILD_DIR}
167 if [ ! -d sysrepo ]; then
168 git clone https://github.com/sysrepo/sysrepo.git
169 fi
170 cd sysrepo
171 git fetch
172 git checkout ${SYSREPO_COMMIT}
173
174 mkdir build
175 cd build
176 cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off \
177 -DCALL_TARGET_BINS_DIRECTLY=Off ..
178 make -j${NUM_CORES}
179 sudo make install
180 sudo ldconfig
181}
182
183function checkout_bmv2 {
184 cd ${BUILD_DIR}
185 if [ ! -d bmv2 ]; then
186 git clone https://github.com/p4lang/behavioral-model.git bmv2
187 fi
188 cd bmv2
189 git fetch
190 git checkout ${BMV2_COMMIT}
191}
192
193function do_pi_bmv2_deps {
194 checkout_bmv2
195 # From bmv2's install_deps.sh.
196 # Nanomsg is required also by p4runtime.
197 tmpdir=`mktemp -d -p .`
198 cd ${tmpdir}
199 bash ../travis/install-thrift.sh
200 bash ../travis/install-nanomsg.sh
201 sudo ldconfig
202 bash ../travis/install-nnpy.sh
203 cd ..
204 sudo rm -rf $tmpdir
205}
206
207function do_p4runtime {
208 cd ${BUILD_DIR}
209 if [ ! -d p4runtime ]; then
210 git clone https://github.com/p4lang/PI.git p4runtime
211 fi
212 cd p4runtime
213 git fetch
214 git checkout ${PI_COMMIT}
215 git submodule update --init --recursive
216
217 ./autogen.sh
218 ./configure --with-proto --with-sysrepo 'CXXFLAGS=-O0 -g'
219 make -j${NUM_CORES}
220 sudo make install
221 sudo ldconfig
222
223 sudo proto/sysrepo/install_yangs.sh
224}
225
226function do_bmv2 {
227 checkout_bmv2
228
229 ./autogen.sh
230 ./configure --enable-debugger --with-pi 'CXXFLAGS=-O0 -g'
231 make -j${NUM_CORES}
232 sudo make install
233 sudo ldconfig
234
235 # Simple_switch_grpc target
236 cd targets/simple_switch_grpc
237 ./autogen.sh
238 ./configure --with-sysrepo --with-thrift 'CXXFLAGS=-O0 -g'
239 make -j${NUM_CORES}
240 sudo make install
241 sudo ldconfig
242}
243
244function do_p4c {
245 cd ${BUILD_DIR}
246 if [ ! -d p4c ]; then
247 git clone https://github.com/p4lang/p4c.git
248 fi
249 cd p4c
250 git fetch
251 git checkout ${P4C_COMMIT}
252 git submodule update --init --recursive
253
254 mkdir -p build
255 cd build
256 cmake ..
257 make -j${NUM_CORES}
258 sudo make install
259 sudo ldconfig
260}
261
262function check_commit {
263 if [ ! -e $2 ]; then
264 return 0 # true
265 fi
266 if [[ $(< $2) != "$1" ]]; then
267 return 0 # true
268 fi
269 return 1 # false
270}
271
272# The following is borrowed from Mininet's util/install.sh
273function version_ge {
274 # sort -V sorts by *version number*
275 latest=`printf "$1\n$2" | sort -V | tail -1`
276 # If $1 is latest version, then $1 >= $2
277 [ "$1" == "$latest" ]
278}
279
280MUST_DO_ALL=false
281DID_REQUIREMENTS=false
282function check_and_do {
283 # Check if the latest built commit is the same we are trying to build now,
284 # or if all projects must be built. If true builds this project.
285 commit_id="$1"
286 proj_dir="$2"
287 func_name="$3"
288 simple_name="$4"
289 if ${MUST_DO_ALL} = true \
290 || check_commit ${commit_id} ${proj_dir}/.last_built_commit; then
291 echo "#"
292 echo "# Building ${simple_name} (${commit_id})"
293 echo "#"
294 # Print commands used to install to aid debugging
295 set -x
296 if ! ${DID_REQUIREMENTS} = true; then
297 do_requirements
298 # TODO consider other Linux distros; presently this script assumes
299 # that it is running on Ubuntu.
300 RELEASE=`lsb_release -rs`
301 if version_ge $RELEASE 16.04; then
302 do_requirements_1604
303 elif version_ge $RELEASE 14.04; then
304 do_requirements_1404
305 else
306 echo "Ubuntu version $RELEASE is not supported"
307 exit 1
308 fi
309 DID_REQUIREMENTS=true
310 fi
311 eval ${func_name}
312 echo ${commit_id} > ${BUILD_DIR}/${proj_dir}/.last_built_commit
313 # Build all next projects as they might depend on this one.
314 MUST_DO_ALL=true
315 # Disable printing to reduce output
316 set +x
317 else
318 echo "${proj_dir} is up to date (commit ${commit_id})"
319 fi
320}
321
322mkdir -p ${BUILD_DIR}
323cd ${BUILD_DIR}
324# In dependency order.
325check_and_do ${PROTOBUF_COMMIT} protobuf do_protobuf protobuf
326check_and_do ${GRPC_COMMIT} grpc do_grpc grpc
327check_and_do ${LIBYANG_COMMIT} libyang do_libyang libyang
328check_and_do ${SYSREPO_COMMIT} sysrepo do_sysrepo sysrepo
329check_and_do ${BMV2_COMMIT} bmv2 do_pi_bmv2_deps bmv2-deps
330check_and_do ${PI_COMMIT} p4runtime do_p4runtime p4runtime
331check_and_do ${BMV2_COMMIT} bmv2 do_bmv2 bmv2
332check_and_do ${P4C_COMMIT} p4c do_p4c p4c
333
334echo "Done!"