scripts: add ABI checking utility
[dpdk.git] / scripts / validate-abi.sh
1 #!/bin/sh
2 #   BSD LICENSE
3 #
4 #   Copyright(c) 2015 Neil Horman. All rights reserved.
5 #   All rights reserved.
6 #
7 #   Redistribution and use in source and binary forms, with or without
8 #   modification, are permitted provided that the following conditions
9 #   are met:
10 #
11 #     * Redistributions of source code must retain the above copyright
12 #       notice, this list of conditions and the following disclaimer.
13 #     * Redistributions in binary form must reproduce the above copyright
14 #       notice, this list of conditions and the following disclaimer in
15 #       the documentation and/or other materials provided with the
16 #       distribution.
17 #
18 #   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 #   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 #   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 #   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 #   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 #   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 #   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 TAG1=$1
31 TAG2=$2
32 TARGET=$3
33 ABI_DIR=`mktemp -d -p /tmp ABI.XXXXXX`
34
35 usage() {
36         echo "$0 <TAG1> <TAG2> <TARGET>"
37 }
38
39 log() {
40         local level=$1
41         shift
42         echo "$*"
43 }
44
45 validate_tags() {
46         git tag -l | grep -q "$TAG1"
47         if [ $? -ne 0 ]
48         then
49                 echo "$TAG1 is invalid"
50                 return
51         fi
52         git tag -l | grep -q "$TAG2"
53         if [ $? -ne 0 ]
54         then
55                 echo "$TAG2 is invalid"
56                 return
57         fi
58 }
59
60 validate_args() {
61         if [ -z "$TAG1" ]
62         then
63                 echo "Must Specify TAG1"
64                 return
65         fi
66         if [ -z "$TAG2" ]
67         then
68                 echo "Must Specify TAG2"
69                 return
70         fi
71         if [ -z "$TARGET" ]
72         then
73                 echo "Must Specify a build target"
74         fi
75 }
76
77
78 cleanup_and_exit() {
79         rm -rf $ABI_DIR
80         git checkout $CURRENT_BRANCH
81         exit $1
82 }
83
84 ###########################################
85 #START
86 ############################################
87
88 #trap on ctrl-c to clean up
89 trap cleanup_and_exit SIGINT
90
91 #Save the current branch
92 CURRENT_BRANCH=`git branch | grep \* | cut -d' ' -f2`
93
94 if [ -z "$CURRENT_BRANCH" ]
95 then
96         CURRENT_BRANCH=`git log --pretty=format:%H HEAD~1..HEAD`
97 fi
98
99 if [ -n "$VERBOSE" ]
100 then
101         export VERBOSE=/dev/stdout
102 else
103         export VERBOSE=/dev/null
104 fi
105
106 # Validate that we have all the arguments we need
107 res=$(validate_args)
108 if [ -n "$res" ]
109 then
110         echo $res
111         usage
112         cleanup_and_exit 1
113 fi
114
115 # Make sure our tags exist
116 res=$(validate_tags)
117 if [ -n "$res" ]
118 then
119         echo $res
120         cleanup_and_exit 1
121 fi
122
123 ABICHECK=`which abi-compliance-checker 2>/dev/null`
124 if [ $? -ne 0 ]
125 then
126         log "INFO" "Cant find abi-compliance-checker utility"
127         cleanup_and_exit 1
128 fi
129
130 ABIDUMP=`which abi-dumper 2>/dev/null`
131 if [ $? -ne 0 ]
132 then
133         log "INFO" "Cant find abi-dumper utility"
134         cleanup_and_exit 1
135 fi
136
137 log "INFO" "We're going to check and make sure that applications built"
138 log "INFO" "against DPDK DSOs from tag $TAG1 will still run when executed"
139 log "INFO" "against DPDK DSOs built from tag $TAG2."
140 log "INFO" ""
141
142 # Check to make sure we have a clean tree
143 git status | grep -q clean
144 if [ $? -ne 0 ]
145 then
146         log "WARN" "Working directory not clean, aborting"
147         cleanup_and_exit 1
148 fi
149
150 # Move to the root of the git tree
151 cd $(dirname $0)/..
152
153 log "INFO" "Checking out version $TAG1 of the dpdk"
154 # Move to the old version of the tree
155 git checkout $TAG1
156
157 # Make sure we configure SHARED libraries
158 # Also turn off IGB and KNI as those require kernel headers to build
159 sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
160 sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
161 sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
162
163 # Checking abi compliance relies on using the dwarf information in
164 # The shared objects.  Thats only included in the DSO's if we build
165 # with -g
166 export EXTRA_CFLAGS=-g
167 export EXTRA_LDFLAGS=-g
168
169 # Now configure the build
170 log "INFO" "Configuring DPDK $TAG1"
171 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
172
173 log "INFO" "Building DPDK $TAG1. This might take a moment"
174 make O=$TARGET > $VERBOSE 2>&1
175
176 if [ $? -ne 0 ]
177 then
178         log "INFO" "THE BUILD FAILED.  ABORTING"
179         cleanup_and_exit 1
180 fi
181
182 # Move to the lib directory
183 cd $TARGET/lib
184 log "INFO" "COLLECTING ABI INFORMATION FOR $TAG1"
185 for i in `ls *.so`
186 do
187         $ABIDUMP $i -o $ABI_DIR/$i-ABI-0.dump -lver $TAG1
188 done
189 cd ../..
190
191 # Now clean the tree, checkout the second tag, and rebuild
192 git clean -f -d
193 git reset --hard
194 # Move to the new version of the tree
195 log "INFO" "Checking out version $TAG2 of the dpdk"
196 git checkout $TAG2
197
198 # Make sure we configure SHARED libraries
199 # Also turn off IGB and KNI as those require kernel headers to build
200 sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" config/defconfig_$TARGET
201 sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" config/defconfig_$TARGET
202 sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" config/defconfig_$TARGET
203
204 # Now configure the build
205 log "INFO" "Configuring DPDK $TAG2"
206 make config T=$TARGET O=$TARGET > $VERBOSE 2>&1
207
208 log "INFO" "Building DPDK $TAG2. This might take a moment"
209 make O=$TARGET > $VERBOSE 2>&1
210
211 if [ $? -ne 0 ]
212 then
213         log "INFO" "THE BUILD FAILED.  ABORTING"
214         cleanup_and_exit 1
215 fi
216
217 cd $TARGET/lib
218 log "INFO" "COLLECTING ABI INFORMATION FOR $TAG2"
219 for i in `ls *.so`
220 do
221         $ABIDUMP $i -o $ABI_DIR/$i-ABI-1.dump -lver $TAG2
222 done
223 cd ../..
224
225 # Start comparison of ABI dumps
226 for i in `ls $ABI_DIR/*-1.dump`
227 do
228         NEWNAME=`basename $i`
229         OLDNAME=`basename $i | sed -e"s/1.dump/0.dump/"`
230         LIBNAME=`basename $i | sed -e"s/-ABI-1.dump//"`
231
232         if [ ! -f $ABI_DIR/$OLDNAME ]
233         then
234                 log "INFO" "$OLDNAME DOES NOT EXIST IN $TAG1. SKIPPING..."
235         fi
236
237         #compare the abi dumps
238         $ABICHECK -l $LIBNAME -old $ABI_DIR/$OLDNAME -new $ABI_DIR/$NEWNAME
239 done
240
241 git reset --hard
242 log "INFO" "ABI CHECK COMPLETE.  REPORTS ARE IN compat_report directory"
243 cleanup_and_exit 0
244
245