xref: /dpdk/devtools/test-meson-builds.sh (revision b7d0c73851aef89fb64867243015b80a138fa758)
1#! /bin/sh -e
2# SPDX-License-Identifier: BSD-3-Clause
3# Copyright(c) 2018 Intel Corporation
4
5# Run meson to auto-configure the various builds.
6# * all builds get put in a directory whose name starts with "build-"
7# * if a build-directory already exists we assume it was properly configured
8# Run ninja after configuration is done.
9
10# set pipefail option if possible
11PIPEFAIL=""
12set -o | grep -q pipefail && set -o pipefail && PIPEFAIL=1
13
14srcdir=$(dirname $(readlink -f $0))/..
15
16# Load config options:
17# - DPDK_BUILD_TEST_DIR
18#
19# - DPDK_MESON_OPTIONS
20#
21# - DPDK_ABI_REF_DIR
22# - DPDK_ABI_REF_SRC
23# - DPDK_ABI_REF_VERSION
24#
25# - DPDK_BUILD_TEST_EXAMPLES
26. $srcdir/devtools/load-devel-config
27
28MESON=${MESON:-meson}
29use_shared="--default-library=shared"
30builds_dir=${DPDK_BUILD_TEST_DIR:-.}
31
32if command -v gmake >/dev/null 2>&1 ; then
33	MAKE=gmake
34else
35	MAKE=make
36fi
37if command -v ninja >/dev/null 2>&1 ; then
38	ninja_cmd=ninja
39elif command -v ninja-build >/dev/null 2>&1 ; then
40	ninja_cmd=ninja-build
41else
42	echo "ERROR: ninja is not found" >&2
43	exit 1
44fi
45if command -v ccache >/dev/null 2>&1 ; then
46	CCACHE=ccache
47else
48	CCACHE=
49fi
50
51default_path=$PATH
52default_cppflags=$CPPFLAGS
53default_cflags=$CFLAGS
54default_ldflags=$LDFLAGS
55default_meson_options=$DPDK_MESON_OPTIONS
56
57opt_verbose=
58opt_vverbose=
59if [ "$1" = "-v" ] ; then
60	opt_verbose=y
61elif [ "$1" = "-vv" ] ; then
62	opt_verbose=y
63	opt_vverbose=y
64fi
65# we can't use plain verbose when we don't have pipefail option so up-level
66if [ -z "$PIPEFAIL" -a -n "$opt_verbose" ] ; then
67	echo "# Missing pipefail shell option, changing VERBOSE to VERY_VERBOSE"
68	opt_vverbose=y
69fi
70[ -n "$opt_verbose" ] && exec 8>&1 || exec 8>/dev/null
71verbose=8
72[ -n "$opt_vverbose" ] && exec 9>&1 || exec 9>/dev/null
73veryverbose=9
74
75check_cc_flags () # <flag to check> <flag2> ...
76{
77	echo 'int main(void) { return 0; }' |
78		cc $@ -x c - -o /dev/null 2> /dev/null
79}
80
81load_env () # <target compiler>
82{
83	targetcc=$1
84	# reset variables before target-specific config
85	export PATH=$default_path
86	unset PKG_CONFIG_PATH # global default makes no sense
87	export CPPFLAGS=$default_cppflags
88	export CFLAGS=$default_cflags
89	export LDFLAGS=$default_ldflags
90	export DPDK_MESON_OPTIONS=$default_meson_options
91	# set target hint for use in the loaded config file
92	if [ -n "$target_override" ] ; then
93		DPDK_TARGET=$target_override
94	elif command -v $targetcc >/dev/null 2>&1 ; then
95		DPDK_TARGET=$($targetcc -v 2>&1 | sed -n 's,^Target: ,,p')
96	else # toolchain not yet in PATH: its name should be enough
97		DPDK_TARGET=$targetcc
98	fi
99	echo "Using DPDK_TARGET $DPDK_TARGET" >&$verbose
100	# config input: $DPDK_TARGET
101	. $srcdir/devtools/load-devel-config
102	# config output: $DPDK_MESON_OPTIONS, $PATH, $PKG_CONFIG_PATH, etc
103	command -v $targetcc >/dev/null 2>&1 || return 1
104}
105
106config () # <dir> <builddir> <meson options>
107{
108	dir=$1
109	shift
110	builddir=$1
111	shift
112	if [ -f "$builddir/build.ninja" ] ; then
113		# for existing environments, switch to debugoptimized if unset
114		# so that ABI checks can run
115		if ! $MESON configure $builddir |
116				awk '$1=="buildtype" {print $2}' |
117				grep -qw debugoptimized; then
118			$MESON configure --buildtype=debugoptimized $builddir
119		fi
120		return
121	fi
122	options=
123	# deprecated libs are disabled by default, so for complete builds
124	# enable them
125	if ! echo $* | grep -q -- 'enable_deprecated_libs' ; then
126		options="$options -Denable_deprecated_libs=*"
127	fi
128	if echo $* | grep -qw -- '--default-library=shared' ; then
129		options="$options -Dexamples=all"
130	else
131		options="$options -Dexamples=l3fwd" # save disk space
132	fi
133	options="$options --buildtype=debugoptimized"
134	for option in $DPDK_MESON_OPTIONS ; do
135		options="$options -D$option"
136	done
137	options="$options $*"
138	echo "$MESON setup $options $dir $builddir" >&$verbose
139	$MESON setup $options $dir $builddir
140}
141
142compile () # <builddir>
143{
144	builddir=$1
145	if [ -n "$opt_vverbose" ] ; then
146		# for full output from ninja use "-v"
147		echo "$ninja_cmd -v -C $builddir"
148		$ninja_cmd -v -C $builddir
149	elif [ -n "$opt_verbose" ] ; then
150		# for keeping the history of short cmds, pipe through cat
151		echo "$ninja_cmd -C $builddir | cat"
152		$ninja_cmd -C $builddir | cat
153	else
154		$ninja_cmd -C $builddir
155	fi
156}
157
158install_target () # <builddir> <installdir>
159{
160	rm -rf $2
161	echo "DESTDIR=$2 $MESON install -C $1" >&$verbose
162	DESTDIR=$2 $MESON install -C $1 >&$veryverbose
163}
164
165build () # <directory> <target cc | cross file> <ABI check> [meson options]
166{
167	targetdir=$1
168	shift
169	crossfile=
170	[ -r $1 ] && crossfile=$1 || targetcc=$1
171	shift
172	abicheck=$1
173	shift
174	# skip build if compiler not available
175	command -v ${CC##* } >/dev/null 2>&1 || return 0
176	if [ -n "$crossfile" ] ; then
177		cross="--cross-file $crossfile"
178		targetcc=$(sed -n 's,^c[[:space:]]*=[[:space:]]*,,p' \
179			$crossfile | cut -d ',' -f 2 | tr -d "'"'"] ')
180	else
181		cross=
182	fi
183	load_env $targetcc || return 0
184	config $srcdir $builds_dir/$targetdir $cross --werror $*
185	compile $builds_dir/$targetdir
186	if [ -n "$DPDK_ABI_REF_VERSION" -a "$abicheck" = ABI ] ; then
187		abirefdir=${DPDK_ABI_REF_DIR:-reference}/$DPDK_ABI_REF_VERSION
188		if [ ! -d $abirefdir/$targetdir ]; then
189			# clone current sources
190			if [ ! -d $abirefdir/src ]; then
191				abirefsrc=${DPDK_ABI_REF_SRC:-$srcdir}
192				abirefcloneopts=
193				if [ -d $abirefsrc ]; then
194					abirefcloneopts="--local --no-hardlinks"
195				fi
196				git clone $abirefcloneopts \
197					--single-branch \
198					-b $DPDK_ABI_REF_VERSION \
199					$abirefsrc $abirefdir/src
200			fi
201
202			rm -rf $abirefdir/build
203			config $abirefdir/src $abirefdir/build $cross \
204				-Dexamples= $*
205			compile $abirefdir/build
206			install_target $abirefdir/build $abirefdir/$targetdir
207
208			# save disk space by removing static libs and apps
209			find $abirefdir/$targetdir/usr/local -name '*.a' -delete
210			rm -rf $abirefdir/$targetdir/usr/local/bin
211			rm -rf $abirefdir/$targetdir/usr/local/share
212		fi
213
214		install_target $builds_dir/$targetdir \
215			$(readlink -f $builds_dir/$targetdir/install)
216		echo "Checking ABI compatibility of $targetdir" >&$verbose
217		echo $srcdir/devtools/check-abi.sh $abirefdir/$targetdir \
218			$(readlink -f $builds_dir/$targetdir/install) >&$veryverbose
219		$srcdir/devtools/check-abi.sh $abirefdir/$targetdir \
220			$(readlink -f $builds_dir/$targetdir/install) >&$verbose
221	fi
222}
223
224# shared and static linked builds with gcc and clang
225for c in gcc clang ; do
226	command -v $c >/dev/null 2>&1 || continue
227	for s in static shared ; do
228		if [ $s = shared ] ; then
229			abicheck=ABI
230			stdatomic=-Denable_stdatomic=true
231		else
232			abicheck=skipABI # save time and disk space
233			stdatomic=-Denable_stdatomic=false
234		fi
235		export CC="$CCACHE $c"
236		build build-$c-$s $c $abicheck $stdatomic --default-library=$s
237		unset CC
238	done
239done
240
241build build-mini cc skipABI $use_shared -Ddisable_libs=* \
242	-Denable_drivers=net/null
243
244# test compilation with minimal x86 instruction set
245# Set the install path for libraries to "lib" explicitly to prevent problems
246# with pkg-config prefixes if installed in "lib/x86_64-linux-gnu" later.
247generic_isa='nehalem'
248if ! check_cc_flags "-march=$generic_isa" ; then
249	generic_isa='corei7'
250fi
251build build-x86-generic cc skipABI -Dcheck_includes=true \
252	-Dlibdir=lib -Dcpu_instruction_set=$generic_isa $use_shared
253
254# 32-bit with default compiler
255if check_cc_flags '-m32' ; then
256	target_override='i386-pc-linux-gnu'
257	if [ -d '/usr/lib/i386-linux-gnu' ] ; then
258		# 32-bit pkgconfig on Debian/Ubuntu, use cross file
259		build build-32b $srcdir/config/x86/cross-32bit-debian.ini ABI
260	elif [ -d '/usr/lib32' ] ; then
261		# 32-bit pkgconfig on Arch
262		build build-32b $srcdir/config/x86/cross-32bit-arch.ini ABI
263	else
264		# 32-bit pkgconfig on RHEL/Fedora (lib vs lib64)
265		build build-32b $srcdir/config/x86/cross-32bit-fedora.ini ABI
266	fi
267	target_override=
268fi
269
270# x86 MinGW
271f=$srcdir/config/x86/cross-mingw
272build build-x86-mingw $f skipABI -Dexamples=helloworld
273
274# generic armv8
275f=$srcdir/config/arm/arm64_armv8_linux_gcc
276build build-arm64-generic-gcc $f ABI $use_shared
277
278# generic LoongArch
279f=$srcdir/config/loongarch/loongarch_loongarch64_linux_gcc
280build build-loongarch64-generic-gcc $f ABI $use_shared
281
282# IBM POWER
283f=$srcdir/config/ppc/ppc64le-power8-linux-gcc
284if grep -q 'NAME="Ubuntu"' /etc/os-release ; then
285	f=$f-ubuntu
286fi
287build build-ppc64-power8-gcc $f ABI $use_shared
288
289# generic RISC-V
290f=$srcdir/config/riscv/riscv64_linux_gcc
291build build-riscv64-generic-gcc $f ABI $use_shared
292
293# Test installation of the x86-generic target, to be used for checking
294# the sample apps build using the pkg-config file for cflags and libs
295load_env cc
296build_path=$(readlink -f $builds_dir/build-x86-generic)
297export DESTDIR=$build_path/install
298install_target $build_path $DESTDIR
299pc_file=$(find $DESTDIR -name libdpdk.pc)
300export PKG_CONFIG_PATH=$(dirname $pc_file):$PKG_CONFIG_PATH
301libdir=$(dirname $(find $DESTDIR -name librte_eal.so))
302export LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH
303export PATH=$(dirname $(find $DESTDIR -name dpdk-devbind.py)):$PATH
304examples=${DPDK_BUILD_TEST_EXAMPLES:-"cmdline helloworld l2fwd l3fwd skeleton timer"}
305if [ "$examples" = 'all' ]; then
306	examples=$(find $build_path/examples -maxdepth 1 -type f -name "dpdk-*" |
307	while read target; do
308		target=${target%%:*}
309		target=${target#$build_path/examples/dpdk-}
310		if [ -e $srcdir/examples/$target/Makefile ]; then
311			echo $target
312			continue
313		fi
314		# Some examples binaries are built from an example sub
315		# directory, discover the "top level" example name.
316		find $srcdir/examples -name Makefile |
317		sed -n "s,$srcdir/examples/\([^/]*\)\(/.*\|\)/$target/Makefile,\1,p"
318	done | sort -u |
319	tr '\n' ' ')
320fi
321# if pkg-config defines the necessary flags, test building some examples
322if pkg-config --define-prefix libdpdk >/dev/null 2>&1; then
323	export PKGCONF="pkg-config --define-prefix"
324	for example in $examples; do
325		echo "## Building $example"
326		[ $example = helloworld ] && static=static || static= # save disk space
327		$MAKE -C $DESTDIR/usr/local/share/dpdk/examples/$example \
328			clean shared $static >&$veryverbose
329	done
330fi
331