4 # Copyright(c) 2015 Neil Horman. All rights reserved.
5 # Copyright(c) 2017 6WIND S.A.
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in
16 # the documentation and/or other materials provided with the
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 abicheck=abi-compliance-checker
36 default_target=x86_64-native-linuxapp-gcc
40 echo "$0: error at line $1"
42 trap 'err_report $LINENO' ERR
46 $(basename $0) [options] <rev1> <rev2>
48 This script compares the ABI of 2 git revisions of the current
49 workspace. The output is a html report and a compilation log.
51 The objective is to make sure that applications built against
52 DSOs from the first revision can still run when executed using
53 the DSOs built from the second revision.
55 <rev1> and <rev2> are git commit id or tags.
59 -j <num> enable parallel compilation with <num> threads
60 -v show compilation logs on the console
61 -d <dir> change working directory (default is ${default_dst})
62 -t <target> the dpdk target to use (default is ${default_target})
63 -f overwrite existing files in destination directory
65 The script returns 0 on success, or the value of last failing
66 call of ${abicheck} (incompatible abi or the tool has run with errors).
67 The errors returned by ${abidump} are ignored.
72 # log in the file, and on stdout if verbose
74 # $2: string to be logged
77 if [ "${verbose}" != "true" ]; then
82 # launch a command and log it, taking care of surrounding spaces with quotes
84 local i s whitespace ret
86 whitespace="[[:space:]]"
88 if [[ $i =~ $whitespace ]]; then
101 if [ "$ret" != "0" ]; then
102 log "CMD" "previous command returned $ret"
108 # redirect or copy stderr/stdout to a file
109 # the syntax is unfamiliar, but it makes the rest of the
110 # code easier to read, avoiding the use of pipes
112 # save original stdout and stderr in fd 3 and 4
115 # create a new fd 5 that send to a file
117 # send stdout and stderr to fd 5
118 if [ "${verbose}" = "true" ]; then
119 exec 1> >(tee /dev/fd/5 >&3)
120 exec 2> >(tee /dev/fd/5 >&4)
127 # Make sure we configure SHARED libraries
128 # Also turn off IGB and KNI as those require kernel headers to build
130 local conf=config/defconfig_$target
131 cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
132 cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
133 cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
134 cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
135 cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
138 # build dpdk for the given tag and dump abi
139 # $1: hash of the revision
143 cmd git clone ${dpdkroot} ${dst}/${1}
146 log "INFO" "Checking out version ${1} of the dpdk"
147 # Move to the old version of the tree
148 cmd git checkout ${1}
152 # Now configure the build
153 log "INFO" "Configuring DPDK ${1}"
154 cmd make config T=$target O=$target
156 # Checking abi compliance relies on using the dwarf information in
157 # the shared objects. Build with -g to include them.
158 log "INFO" "Building DPDK ${1}. This might take a moment"
159 cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
160 EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
162 # Move to the lib directory
163 cmd cd ${PWD}/$target/lib
164 log "INFO" "Collecting ABI information for ${1}"
167 cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
168 # hack to ignore empty SymbolsInfo section (no public ABI)
169 if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
171 log "INFO" "${i} has no public ABI, remove dump file"
172 cmd rm -f $dst/${1}/${i}.dump
180 target=${default_target}
182 while getopts j:vd:t:fh ARG ; do
184 j ) parallel=$OPTARG ;;
187 t ) target=$OPTARG ;;
189 h ) print_usage ; exit 0 ;;
190 ? ) print_usage ; exit 1 ;;
193 shift $(($OPTIND - 1))
203 # convert path to absolute
206 *) dst=${PWD}/${dst} ;;
208 dpdkroot=$(readlink -e $(dirname $0)/..)
210 if [ -e "${dst}" -a "$force" = 0 ]; then
211 echo "The ${dst} directory is not empty. Remove it, use another"
212 echo "one (-d <dir>), or force overriding (-f)"
218 set_log_file ${dst}/abi-check.log
219 log "INFO" "Logs available in ${dst}/abi-check.log"
221 command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
222 command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
224 hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
225 hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
227 # Make hashes available in output for non-local reference
228 tag1="$tag1 ($hash1)"
229 tag2="$tag2 ($hash2)"
231 if [ "$hash1" = "$hash2" ]; then
232 log "ERROR" "$tag1 and $tag2 are the same revisions"
238 # dump abi for each revision
242 # compare the abi dumps
246 for i in ${hash2}/*.dump; do
248 libname=${name%.dump}
250 if [ ! -f ${hash1}/$name ]; then
251 log "INFO" "$NAME does not exist in $tag1. skipping..."
256 cmd $abicheck -l $libname \
257 -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
258 if [ $local_ret != 0 ]; then
259 log "NOTICE" "$abicheck returned $local_ret"
261 list="$list $libname"
265 if [ $ret != 0 ]; then
266 log "NOTICE" "ABI may be incompatible, check reports/logs for details."
267 log "NOTICE" "Incompatible list: $list"
269 log "NOTICE" "No error detected, ABI is compatible."
272 log "INFO" "Logs are in ${dst}/abi-check.log"
273 log "INFO" "HTML reports are in ${dst}/compat_reports directory"