xref: /spdk/configure (revision dabca256464e7c61f53ea1c1f79c566f835d2e7d)
1#!/usr/bin/env bash
2
3set -e
4
5trap 'echo -e "\n\nConfiguration failed\n\n" >&2' ERR
6
7rootdir=$(readlink -f $(dirname $0))
8source "$rootdir/scripts/common.sh"
9
10function usage() {
11	echo "'configure' configures SPDK to compile on supported platforms."
12	echo ""
13	echo "Usage: ./configure [OPTION]..."
14	echo ""
15	echo "Defaults for the options are specified in brackets."
16	echo ""
17	echo "General:"
18	echo " -h, --help                Display this help and exit"
19	echo ""
20	echo " --prefix=path             Configure installation prefix (default: /usr/local)"
21	echo " --target-arch=arch        Target build architecture. Must be a valid GNU arch. Default: native"
22	echo ""
23	echo " --cross-prefix=prefix     Prefix for cross compilation (default: none)"
24	echo "                           example: aarch64-linux-gnu"
25	echo ""
26	echo " --enable-debug            Configure for debug builds"
27	echo " --enable-werror           Treat compiler warnings as errors"
28	echo " --enable-asan             Enable address sanitizer"
29	echo " --enable-ubsan            Enable undefined behavior sanitizer"
30	echo " --enable-coverage         Enable code coverage tracking"
31	echo " --enable-lto              Enable link-time optimization"
32	echo " --enable-pgo-capture      Enable generation of profile guided optimization data"
33	echo " --enable-pgo-use          Use previously captured profile guided optimization data"
34	echo " --enable-cet              Enable Intel Control-flow Enforcement Technology (CET)"
35	echo " --disable-tests           Disable building of functional tests"
36	echo " --disable-unit-tests      Disable building of unit tests"
37	echo " --disable-examples        Disable building of examples"
38	echo " --disable-apps            Disable building of apps"
39	echo ""
40	echo "Specifying Dependencies:"
41	echo "--with-DEPENDENCY[=path]   Use the given dependency. Optionally, provide the"
42	echo "                           path."
43	echo "--without-DEPENDENCY       Do not link to the given dependency. This may"
44	echo "                           disable features and components."
45	echo ""
46	echo "Valid dependencies are listed below."
47	echo " --with-dpdk[=DIR]         Build against a custom dpdk version. By default, the dpdk"
48	echo " --without-dpdk            submodule in spdk tree will be used."
49	echo "                           example: /usr/share/dpdk/x86_64-default-linuxapp-gcc"
50	echo " --with-env=DIR            Use an alternate environment implementation instead of DPDK."
51	echo "                           Implies --without-dpdk."
52	echo " --with-idxd               Build the IDXD library and accel framework plug-in module."
53	echo " --without-idxd            Disabled while experimental. Only built for x86 when enabled."
54	echo " --with-crypto             Build vbdev crypto module."
55	echo " --without-crypto          No path required."
56	echo " --with-fio[=DIR]          Build fio_plugin."
57	echo " --without-fio             default: /usr/src/fio"
58	echo " --with-vhost              Build vhost target. Enabled by default."
59	echo " --without-vhost           No path required."
60	echo " --with-virtio             Build vhost initiator and virtio-pci bdev modules."
61	echo " --without-virtio          No path required."
62	echo " --with-vfio-user[=DIR]    Build custom vfio-user transport for NVMf target and NVMe initiator."
63	echo " --without-vfio-user       example: /usr/src/libvfio-user"
64	echo " --with-pmdk[=DIR]         Build persistent memory bdev.
65					 example: /usr/share/pmdk"
66	echo " --without-pmdk		 No path required."
67	echo " --with-reduce             Build vbdev compression module."
68	echo " --without-reduce          No path required."
69	echo " --with-rbd                Build Ceph RBD bdev module."
70	echo " --without-rbd             No path required."
71	echo " --with-rdma[=DIR]         Build RDMA transport for NVMf target and initiator."
72	echo " --without-rdma            Accepts optional RDMA provider name. Can be \"verbs\" or \"mlx5_dv\"."
73	echo "                           If no provider specified, \"verbs\" provider is used by default."
74	echo " --with-fc[=DIR]           Build FC transport for NVMf target."
75	echo " --without-fc              If an argument is provided, it is considered a directory containing"
76	echo "                           libufc.a and fc_lld.h. Otherwise the regular system paths will"
77	echo "                           be searched."
78	echo " --with-shared             Build spdk shared libraries."
79	echo " --without-shared          No path required."
80	echo " --with-iscsi-initiator    Build with iscsi bdev module."
81	echo " --without-iscsi-initiator No path required."
82	echo " --with-vtune=DIR          Required to profile I/O under Intel VTune Amplifier XE."
83	echo " --without-vtune           example: /opt/intel/vtune_amplifier_xe_version"
84	echo " --with-ocf[=DIR]          Build OCF library and bdev module."
85	echo " --without-ocf             If argument is directory, interpret it as root of OCF repo"
86	echo "                           If argument is file, interpret it as compiled OCF lib"
87	echo "                           If no argument is specified, OCF git submodule is used by default"
88	echo "                           example: /usr/src/ocf/"
89	echo " --with-isal               Build with ISA-L. Enabled by default on x86 and aarch64 architectures."
90	echo " --without-isal            No path required."
91	echo " --with-uring[=DIR]        Build I/O uring bdev or socket module."
92	echo " --without-uring           If an argument is provided, it is considered a directory containing"
93	echo "                           liburing.a and io_uring.h. Otherwise the regular system paths will"
94	echo "                           be searched."
95	echo " --with-fuse               Build FUSE components for mounting a blobfs filesystem."
96	echo " --without-fuse            No path required."
97	echo " --with-nvme-cuse          Build NVMe driver with support for CUSE-based character devices."
98	echo " --without-nvme-cuse       No path required."
99	echo " --with-raid5              Build with bdev_raid module RAID5 support."
100	echo " --without-raid5           No path required."
101	echo " --with-wpdk=DIR           Build using WPDK to provide support for Windows (experimental)."
102	echo " --without-wpdk            The argument must be a directory containing lib and include."
103	echo " --with-usdt               Build with userspace DTrace probes enabled."
104	echo " --without-usdt            No path required."
105	echo " --with-fuzzer             Build with LLVM fuzzing enabled."
106	echo "                           Path to clang_rt.fuzzer_no_main library required."
107	echo "                           Requires setting CC and CXX to clang."
108	echo "                           (Typically /usr/lib/llvm-VER/lib/clang/VER/lib/linux/libclang_rt.fuzzer_no_main-ARCH.a)"
109	echo " --with-sma                Generate Storage Management Agent's protobuf interface"
110	echo " --without-sma             No path required."
111	echo ""
112	echo "Environment variables:"
113	echo ""
114	echo "CC                         C compiler"
115	echo "CFLAGS                     C compiler flags"
116	echo "CXX                        C++ compiler"
117	echo "CXXFLAGS                   C++ compiler flags"
118	echo "LD                         Linker"
119	echo "LDFLAGS                    Linker flags"
120	echo "DESTDIR                    Destination for 'make install'"
121	echo ""
122}
123
124# Load default values
125# Convert config to sourceable configuration file
126sed -r 's/CONFIG_([[:alnum:]_]+)=(.*)/CONFIG[\1]=\2/g' $rootdir/CONFIG > $rootdir/CONFIG.sh
127declare -A CONFIG
128source $rootdir/CONFIG.sh
129rm $rootdir/CONFIG.sh
130
131# Try to expand literal ~ that might have been passed as an option via --long-opt=~/dir.
132set -- "${@//\~/~}"
133
134for i in "$@"; do
135	case "$i" in
136		--cross-prefix=*)
137			CONFIG[CROSS_PREFIX]="${i#*=}"
138			;;
139		--enable-lto)
140			CONFIG[LTO]=y
141			;;
142		--disable-lto)
143			CONFIG[LTO]=n
144			;;
145	esac
146done
147
148# Detect the compiler toolchain
149$rootdir/scripts/detect_cc.sh --cc="$CC" --cxx="$CXX" --lto="${CONFIG[LTO]}" --ld="$LD" --cross-prefix="${CONFIG[CROSS_PREFIX]}" > $rootdir/mk/cc.mk
150
151CC=$(grep "DEFAULT_CC=" "$rootdir/mk/cc.mk" | sed s/DEFAULT_CC=//)
152CC_TYPE=$(grep "CC_TYPE=" "$rootdir/mk/cc.mk" | cut -d "=" -f 2)
153
154arch=$($CC -dumpmachine)
155sys_name=$(uname -s)
156
157if [[ $arch == *mingw* ]] || [[ $arch == *windows* ]]; then
158	sys_name=Windows
159fi
160
161# Sanitize default configuration. All parameters set by user explicit should fail
162# Force no ISA-L if non-x86 or non-aarch64 architecture
163if [[ "${CONFIG[ISAL]}" = "y" ]]; then
164	if [[ $arch != x86_64* ]] && [[ $arch != aarch64* ]]; then
165		CONFIG[ISAL]=n
166		echo "Notice: ISA-L not supported for ${arch}. Turning off default feature."
167	fi
168fi
169
170if [[ $sys_name != "Linux" ]]; then
171	# Vhost, rte_vhost library and virtio are only supported on Linux.
172	CONFIG[VHOST]="n"
173	CONFIG[VIRTIO]="n"
174	echo "Notice: Vhost, rte_vhost library and virtio are only supported on Linux. Turning off default feature."
175fi
176
177#check nasm only on x86
178if [[ $arch == x86_64* ]]; then
179	ver=$(nasm -v 2> /dev/null | awk '{print $3}' | awk -Fr '{print $1}')
180	if lt "$ver" 2.14; then
181		# ISA-L, compression & crypto require NASM version 2.14 or newer.
182		CONFIG[ISAL]=n
183		CONFIG[CRYPTO]=n
184		CONFIG[IPSEC_MB]=n
185		CONFIG[REDUCE]=n
186		HAVE_NASM=n
187		echo "Notice: ISA-L, compression & crypto require NASM version 2.14 or newer. Turning off default ISA-L and crypto features."
188	else
189		HAVE_NASM=y
190	fi
191fi
192
193function check_dir() {
194	arg="$1"
195	dir="${arg#*=}"
196	if [ ! -d "$dir" ]; then
197		echo "$arg: directory not found"
198		exit 1
199	fi
200}
201
202# On x86_64 'clang -dumpmachine' produces x86_64-pc-linux-gnu
203# whereas the dpdk might be built with gcc and its libs lie in
204# x86_64-linux-gnu. Let's find the right libdir for dpdkd libs.
205function find_dpdk_arch_libdir() {
206	local dpdk_dir=$1
207
208	# Checking first what we have with $arch, then clang
209	# variant of arch.
210	arches=("$arch" "$(echo $arch | sed 's/-pc//g')")
211	for a in "${arches[@]}"; do
212		local libdir="$dpdk_dir/lib/$a"
213		if [[ -d $libdir ]]; then
214			echo $libdir
215			return
216		fi
217	done
218
219	# Fallback to the libdir without arch component
220	echo "$dpdk_dir/lib"
221}
222
223function check_IPSec_mb() {
224	local mode=$1
225	local dpdk_libdir=$2
226	local dpdk_incdir=$3
227	local have_ipsec_mb=n
228
229	if [[ $mode = "pkg-config" ]]; then
230		local dpdk_libs
231
232		# Request libdpdk pkg-config settings to figure out if the IPSec_MB is used
233		# as a dependency.
234		# Due to some reason pkg-config shows -lIPSec_MB only with --static option
235		dpdk_libs=$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --libs --static libdpdk)
236		if echo "$dpdk_libs" | grep "\-lIPSec_MB" > /dev/null 2>&1; then
237			have_ipsec_mb=y
238		fi
239	elif [[ $mode = "build-config" ]]; then
240		# Use dpdk build config header to check if the IPSec_MB was used.
241		if grep -F "define RTE_CRYPTO_IPSEC_MB 1" "$dpdk_incdir/rte_build_config.h" > /dev/null 2>&1; then
242			have_ipsec_mb=y
243		fi
244	else
245		echo "ERROR: Invalid IPSec_MB checking mode $mode."
246		echo "ERROR: Only \"pkg-config\" and \"build-config\" available."
247		exit 1
248	fi
249	if [[ $have_ipsec_mb = "n" ]]; then
250		CONFIG[IPSEC_MB]=n
251		return
252	fi
253
254	# Since we don't know the library path where the IPSec_MB is located
255	# let's find it out with the ldd utility. This can be a standard location
256	# or a custom build.
257	local librte_crypto_ipsec_mb="$dpdk_libdir/librte_crypto_ipsec_mb.so"
258	if [[ -f "$librte_crypto_ipsec_mb" ]]; then
259		local ipsec_mb_libdir
260
261		ipsec_mb_libdir=$(ldd "$librte_crypto_ipsec_mb" | grep "libIPSec_MB.so" \
262			| sed -e 's/\s*libIPSec_MB.so.*=>\s//' -e 's/\/libIPSec_MB.so.*$//')
263		if [[ -d $ipsec_mb_libdir ]]; then
264			CONFIG[IPSEC_MB]=y
265			CONFIG[IPSEC_MB_DIR]="$ipsec_mb_libdir"
266		elif [[ $ipsec_mb_libdir = "not found" ]]; then
267			# ldconfig cache is broken, old build with refs to non-existing libs, etc.
268			echo "ERROR: Invalid IPSec_MB installation. Library is not found and/or ldconfig cache is broken!"
269			exit 1
270		else
271			# Failed to check for IPSec_MB lib path. Let's just assume it is lives
272			# in one of the standard locations (/usr/lib, etc.).
273			CONFIG[IPSEC_MB]=y
274		fi
275	else
276		# pkg-config says there is IPSec_mb and dpdk lib does not have it. Let's just
277		# assume it is installed in the system in one of the standard locations.
278		CONFIG[IPSEC_MB]=y
279	fi
280}
281
282for i in "$@"; do
283	case "$i" in
284		-h | --help)
285			usage
286			exit 0
287			;;
288		--cross-prefix=*) ;&
289		--enable-lto) ;&
290		--disable-lto)
291			# Options handled before detecting CC.
292			;;
293		--prefix=*)
294			CONFIG[PREFIX]="${i#*=}"
295			;;
296		--target-arch=*)
297			CONFIG[ARCH]="${i#*=}"
298			;;
299		--enable-debug)
300			CONFIG[DEBUG]=y
301			;;
302		--disable-debug)
303			CONFIG[DEBUG]=n
304			;;
305		--enable-asan)
306			CONFIG[ASAN]=y
307			;;
308		--disable-asan)
309			CONFIG[ASAN]=n
310			;;
311		--enable-ubsan)
312			CONFIG[UBSAN]=y
313			;;
314		--disable-ubsan)
315			CONFIG[UBSAN]=n
316			;;
317		--enable-tsan)
318			CONFIG[TSAN]=y
319			;;
320		--disable-tsan)
321			CONFIG[TSAN]=n
322			;;
323		--enable-coverage)
324			CONFIG[COVERAGE]=y
325			;;
326		--disable-coverage)
327			CONFIG[COVERAGE]=n
328			;;
329		--enable-pgo-capture)
330			CONFIG[PGO_CAPTURE]=y
331			;;
332		--disable-pgo-capture)
333			CONFIG[PGO_CAPTURE]=n
334			;;
335		--enable-pgo-use)
336			CONFIG[PGO_USE]=y
337			;;
338		--disable-pgo-use)
339			CONFIG[PGO_USE]=n
340			;;
341		--enable-tests)
342			CONFIG[TESTS]=y
343			;;
344		--disable-tests)
345			CONFIG[TESTS]=n
346			;;
347		--enable-unit-tests)
348			CONFIG[UNIT_TESTS]=y
349			;;
350		--disable-unit-tests)
351			CONFIG[UNIT_TESTS]=n
352			;;
353		--enable-examples)
354			CONFIG[EXAMPLES]=y
355			;;
356		--disable-examples)
357			CONFIG[EXAMPLES]=n
358			;;
359		--enable-apps)
360			CONFIG[APPS]=y
361			;;
362		--disable-apps)
363			CONFIG[APPS]=N
364			;;
365		--enable-werror)
366			CONFIG[WERROR]=y
367			;;
368		--disable-werror)
369			CONFIG[WERROR]=n
370			;;
371		--enable-cet)
372			CONFIG[CET]=y
373			;;
374		--disable-cet)
375			CONFIG[CET]=n
376			;;
377		--with-dpdk)
378			# Can we use pkg-config?
379			if command -v "pkg-config" > /dev/null 2>&1 && pkg-config --exists libdpdk; then
380				dpdk_libdir=$(pkg-config --variable=libdir libdpdk)
381				dpdk_libdir=$(readlink -f $dpdk_libdir)
382				dpdk_incdir=$(pkg-config --variable=includedir libdpdk)
383				echo "Using DPDK lib dir $dpdk_libdir"
384				CONFIG[DPDK_LIB_DIR]=$dpdk_libdir
385				CONFIG[DPDK_INC_DIR]=$dpdk_incdir
386				CONFIG[DPDK_PKG_CONFIG]=y
387				if pkg-config --print-requires libdpdk | grep "libbsd" > /dev/null 2>&1; then
388					CONFIG[HAVE_LIBBSD]=y
389				fi
390				CFLAGS="${CFLAGS:+$CFLAGS }$(pkg-config --cflags libdpdk)"
391				check_IPSec_mb "pkg-config" "$dpdk_libdir" "$dpdk_incdir"
392			else
393				echo "libdpdk.pc not found, aborting"
394				exit 1
395			fi
396			;;
397		--with-dpdk=*)
398			check_dir "$i"
399			dpdk_dir=$(readlink -f ${i#*=})
400			dpdk_libdir=$(find_dpdk_arch_libdir $dpdk_dir)
401			dpdk_incdir="$dpdk_dir/include"
402
403			# Can we use pkg-config?
404			if command -v "pkg-config" > /dev/null 2>&1 && PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --exists libdpdk; then
405				echo "Using $dpdk_libdir/pkgconfig for additional libs..."
406				sysroot_dir=$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --variable=pc_sysrootdir libdpdk)
407				dpdk_libdir=$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --variable=libdir libdpdk)
408				dpdk_libdir=$(readlink -f "${sysroot_dir}$dpdk_libdir")
409				if ! echo $dpdk_libdir | grep $dpdk_dir > /dev/null 2>&1; then
410					echo "ERROR: pkg-config reported DPDK libdir $dpdk_libdir is out of the directory specified with --with-dpdk="
411					echo "ERROR: do you have another DPDK installed in the system?"
412					exit 1
413				fi
414				dpdk_reqs=$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --print-requires libdpdk)
415				if echo $dpdk_reqs | grep "libbsd" > /dev/null 2>&1; then
416					CONFIG[HAVE_LIBBSD]=y
417				fi
418				CFLAGS="${CFLAGS:+$CFLAGS }$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --cflags libdpdk)"
419				dpdk_incdir="${sysroot_dir}$(PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$dpdk_libdir/pkgconfig" pkg-config --variable=includedir libdpdk)"
420				check_IPSec_mb "pkg-config" "$dpdk_libdir" "$dpdk_incdir"
421			else
422				echo "Using $dpdk_incdir/rte_build_config.h for additional libs..."
423
424				if grep -F "define RTE_USE_LIBBSD 1" $dpdk_incdir/rte_build_config.h > /dev/null 2>&1; then
425					CONFIG[HAVE_LIBBSD]=y
426				fi
427				check_IPSec_mb "build-config" "$dpdk_libdir" "$dpdk_incdir"
428			fi
429			echo "DPDK libraries: $dpdk_libdir"
430			echo "DPDK includes: $dpdk_incdir"
431			CONFIG[DPDK_DIR]=$dpdk_dir
432			CONFIG[DPDK_LIB_DIR]="$dpdk_libdir"
433			CONFIG[DPDK_INC_DIR]="$dpdk_incdir"
434			CONFIG[DPDK_PKG_CONFIG]=n
435			;;
436		--without-dpdk)
437			CONFIG[DPDK_DIR]=
438			;;
439		--with-wpdk=*)
440			check_dir "$i"
441			CONFIG[WPDK_DIR]=$(readlink -f ${i#*=})
442			;;
443		--without-wpdk)
444			CONFIG[WPDK_DIR]=
445			;;
446		--with-env=*)
447			CONFIG[ENV]="${i#*=}"
448			;;
449		--with-rbd)
450			CONFIG[RBD]=y
451			;;
452		--without-rbd)
453			CONFIG[RBD]=n
454			;;
455		--with-rdma=*)
456			CONFIG[RDMA]=y
457			CONFIG[RDMA_PROV]=${i#*=}
458			;;
459		--with-rdma)
460			CONFIG[RDMA]=y
461			CONFIG[RDMA_PROV]="verbs"
462			;;
463		--without-rdma)
464			CONFIG[RDMA]=n
465			;;
466		--with-fc=*)
467			CONFIG[FC]=y
468			CONFIG[FC_PATH]=$(readlink -f ${i#*=})
469			;;
470		--with-fc)
471			CONFIG[FC]=y
472			CONFIG[FC_PATH]=
473			;;
474		--without-fc)
475			CONFIG[FC]=n
476			CONFIG[FC_PATH]=
477			;;
478		--with-shared)
479			CONFIG[SHARED]=y
480			;;
481		--without-shared)
482			CONFIG[SHARED]=n
483			;;
484		--with-iscsi-initiator)
485			CONFIG[ISCSI_INITIATOR]=y
486			;;
487		--without-iscsi-initiator)
488			CONFIG[ISCSI_INITIATOR]=n
489			;;
490		--with-crypto)
491			CONFIG[CRYPTO]=y
492			;;
493		--without-crypto)
494			CONFIG[CRYPTO]=n
495			;;
496		--with-vhost)
497			CONFIG[VHOST]=y
498			;;
499		--without-vhost)
500			CONFIG[VHOST]=n
501			;;
502		--with-virtio)
503			CONFIG[VIRTIO]=y
504			;;
505		--without-virtio)
506			CONFIG[VIRTIO]=n
507			;;
508		--with-vfio-user)
509			CONFIG[VFIO_USER]=y
510			CONFIG[VFIO_USER_DIR]=""
511			;;
512		--with-vfio-user=*)
513			CONFIG[VFIO_USER]=y
514			check_dir "$i"
515			CONFIG[VFIO_USER_DIR]=$(readlink -f ${i#*=})
516			;;
517		--without-vfio-user)
518			CONFIG[VFIO_USER]=n
519			;;
520		--with-pmdk)
521			CONFIG[PMDK]=y
522			CONFIG[PMDK_DIR]=""
523			;;
524		--with-pmdk=*)
525			CONFIG[PMDK]=y
526			check_dir "$i"
527			CONFIG[PMDK_DIR]=$(readlink -f ${i#*=})
528			;;
529		--without-pmdk)
530			CONFIG[PMDK]=n
531			;;
532		--with-reduce)
533			CONFIG[REDUCE]=y
534			;;
535		--without-reduce)
536			CONFIG[REDUCE]=n
537			;;
538		--with-fio) ;&
539		--with-fio=*)
540			if [[ ${i#*=} != "$i" ]]; then
541				CONFIG[FIO_SOURCE_DIR]=${i#*=}
542			fi
543			check_dir "--with-fio=${CONFIG[FIO_SOURCE_DIR]}"
544			CONFIG[FIO_SOURCE_DIR]=$(readlink -f "${CONFIG[FIO_SOURCE_DIR]}")
545			CONFIG[FIO_PLUGIN]=y
546			;;
547		--without-fio)
548			CONFIG[FIO_PLUGIN]=n
549			;;
550		--with-vtune=*)
551			check_dir "$i"
552			CONFIG[VTUNE_DIR]="${i#*=}"
553			CONFIG[VTUNE]=y
554			;;
555		--without-vtune)
556			CONFIG[VTUNE_DIR]=
557			CONFIG[VTUNE]=n
558			;;
559		--with-ocf)
560			CONFIG[OCF]=y
561			CONFIG[OCF_PATH]=$(readlink -f "./ocf")
562			;;
563		--with-ocf=*)
564			CONFIG[OCF]=y
565			CONFIG[OCF_PATH]=$(readlink -f ${i#*=})
566			;;
567		--without-ocf)
568			CONFIG[OCF]=n
569			CONFIG[OCF_PATH]=
570			;;
571		--with-isal)
572			CONFIG[ISAL]=y
573			;;
574		--without-isal)
575			CONFIG[ISAL]=n
576			;;
577		--with-uring=*)
578			CONFIG[URING]=y
579			CONFIG[URING_PATH]=$(readlink -f ${i#*=})
580			;;
581		--with-uring)
582			CONFIG[URING]=y
583			CONFIG[URING_PATH]=
584			;;
585		--without-uring)
586			CONFIG[URING]=n
587			CONFIG[URING_PATH]=
588			;;
589		--with-fuse)
590			CONFIG[FUSE]=y
591			;;
592		--without-fuse)
593			CONFIG[FUSE]=n
594			;;
595		--with-nvme-cuse)
596			CONFIG[NVME_CUSE]=y
597			;;
598		--without-nvme-cuse)
599			CONFIG[NVME_CUSE]=n
600			;;
601		--with-raid5)
602			CONFIG[RAID5]=y
603			;;
604		--without-raid5)
605			CONFIG[RAID5]=n
606			;;
607		--with-idxd)
608			CONFIG[IDXD]=y
609			CONFIG[IDXD_KERNEL]=n
610			;;
611		--without-idxd)
612			CONFIG[IDXD]=n
613			;;
614		--with-usdt)
615			CONFIG[USDT]=y
616			;;
617		--without-usdt)
618			CONFIG[USDT]=n
619			;;
620		--with-fuzzer)
621			echo "Must specify fuzzer library path with --with-fuzzer"
622			usage
623			exit 1
624			;;
625		--with-fuzzer=*)
626			CONFIG[FUZZER]=y
627			CONFIG[FUZZER_LIB]=$(readlink -f ${i#*=})
628			;;
629		--without-fuzzer)
630			CONFIG[FUZZER]=n
631			CONFIG[FUZZER_LIB]=
632			;;
633		--with-sma)
634			CONFIG[SMA]=y
635			;;
636		--without-sma)
637			CONFIG[SMA]=n
638			;;
639		--)
640			break
641			;;
642		*)
643			echo "Unrecognized option $i"
644			usage
645			exit 1
646			;;
647	esac
648done
649
650if [[ $arch == x86_64* ]]; then
651	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS "-march=native")
652else
653	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS)
654fi
655BUILD_CMD+=(-I/usr/local/include -L/usr/local/lib)
656
657if [[ "${CONFIG[VFIO_USER]}" = "y" ]]; then
658
659	if [[ ! -d /usr/include/json-c ]] && [[ ! -d /usr/local/include/json-c ]]; then
660		echo "ERROR: --with-vfio-user requires json-c-devel"
661		echo "Please install then re-run this script"
662		exit 1
663	fi
664	if [[ ! -e /usr/include/cmocka.h ]] && [[ ! -e /usr/local/include/cmocka.h ]]; then
665		echo "ERROR: --with-vfio-user requires libcmocka-devel"
666		echo "Please install then re-run this script"
667		exit 1
668	fi
669fi
670
671# IDXD uses Intel specific instructions.
672if [[ "${CONFIG[IDXD]}" = "y" ]]; then
673	if [ $(uname -s) == "FreeBSD" ]; then
674		intel="hw.model: Intel"
675		cpu_vendor=$(sysctl -a | grep hw.model | cut -c 1-15)
676	else
677		intel="GenuineIntel"
678		cpu_vendor=$(grep -i 'vendor' /proc/cpuinfo --max-count=1)
679	fi
680	if [[ "$cpu_vendor" != *"$intel"* ]]; then
681		echo "ERROR: IDXD cannot be used due to CPU incompatibility."
682		exit 1
683	fi
684	if [ -e /usr/include/accel-config/libaccel_config.h ]; then
685		CONFIG[IDXD_KERNEL]=y
686	fi
687
688fi
689
690# Detect architecture and force no ISA-L if non-x86 or non-aarch64 architecture
691if [[ "${CONFIG[ISAL]}" = "y" ]]; then
692	if [[ $arch != x86_64* ]] && [[ $arch != aarch64* ]]; then
693		echo "ERROR: ISA-L cannot be used due to CPU incompatibility."
694		exit 1
695	fi
696fi
697
698if [[ "${CONFIG[ISAL]}" = "n" ]] && [[ "${CONFIG[REDUCE]}" = "y" ]]; then
699	echo "ERROR Conflicting options: --with-reduce is not compatible with --without-isal."
700	exit 1
701fi
702
703if [ -z "${CONFIG[ENV]}" ]; then
704	CONFIG[ENV]=$rootdir/lib/env_dpdk
705	echo "Using default SPDK env in ${CONFIG[ENV]}"
706	if [[ -z "${CONFIG[DPDK_DIR]}" && "${CONFIG[DPDK_PKG_CONFIG]}" == n ]]; then
707		if [ ! -f "$rootdir"/dpdk/config/meson.build ]; then
708			echo "DPDK not found; please specify --with-dpdk=<path> or run:"
709			echo
710			echo "  git submodule update --init"
711			exit 1
712		else
713			CONFIG[DPDK_DIR]="${rootdir}/dpdk/build"
714			# Default ipsec libs
715			if [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
716				CONFIG[IPSEC_MB]=y
717				CONFIG[IPSEC_MB_DIR]="${rootdir}/intel-ipsec-mb/lib"
718			fi
719			echo "Using default DPDK in ${CONFIG[DPDK_DIR]}"
720		fi
721	fi
722else
723	if [[ -n "${CONFIG[DPDK_DIR]}" || "${CONFIG[DPDK_PKG_CONFIG]}" == y ]]; then
724		echo "--with-env and --with-dpdk are mutually exclusive."
725		exit 1
726	fi
727
728	if [ "${CONFIG[VHOST]}" = "y" ]; then
729		echo "Vhost is only supported when using the default DPDK environment. Disabling it."
730	fi
731	# Always disable vhost, but only print the error message if the user explicitly turned it on.
732	CONFIG[VHOST]="n"
733	if [ "${CONFIG[VIRTIO]}" = "y" ]; then
734		echo "Virtio is only supported when using the default DPDK environment. Disabling it."
735	fi
736	# Always disable virtio, but only print the error message if the user explicitly turned it on.
737	CONFIG[VIRTIO]="n"
738fi
739
740if [[ "${CONFIG[DPDK_PKG_CONFIG]}" == y ]]; then
741	if [[ "${CONFIG[SHARED]}" == n ]]; then
742		# dpdk-devel doesn't provide static libs
743		echo "Build against packaged DPDK requested, enabling shared libraries"
744		CONFIG[SHARED]=y
745	fi
746fi
747
748if [[ $sys_name == "Windows" ]]; then
749	if [ -z "${CONFIG[WPDK_DIR]}" ]; then
750		if [ ! -f "$rootdir"/wpdk/Makefile ]; then
751			echo "WPDK not found; please specify --with-wpdk=<path>. See https://wpdk.github.io."
752			exit 1
753		else
754			CONFIG[WPDK_DIR]="${rootdir}/wpdk/build"
755			echo "Using default WPDK in ${CONFIG[WPDK_DIR]}"
756		fi
757	fi
758else
759	if [ -n "${CONFIG[WPDK_DIR]}" ]; then
760		echo "ERROR: --with-wpdk is only supported for Windows"
761		exit 1
762	fi
763fi
764
765if [ "${CONFIG[VTUNE]}" = "y" ]; then
766	if [ -z "${CONFIG[VTUNE_DIR]}" ]; then
767		echo "When VTune is enabled, you must specify the VTune directory using --with-vtune=path"
768		exit 1
769	fi
770fi
771
772if [[ "${CONFIG[ASAN]}" = "y" && "${CONFIG[TSAN]}" = "y" ]]; then
773	echo "ERROR: ASAN and TSAN cannot be enabled at the same time."
774	exit 1
775fi
776
777if [[ "${CONFIG[FIO_PLUGIN]}" = "y" && "${CONFIG[EXAMPLES]}" = "n" ]]; then
778	echo "ERROR: --with-fio and --disable-examples are mutually exclusive."
779	exit 1
780fi
781
782if [[ $sys_name == "FreeBSD" ]]; then
783	# FreeBSD doesn't support all configurations
784	if [[ "${CONFIG[COVERAGE]}" == "y" ]]; then
785		echo "ERROR: CONFIG_COVERAGE not available on FreeBSD"
786		exit 1
787	fi
788fi
789
790if [[ $sys_name != "Linux" ]]; then
791	if [[ "${CONFIG[VHOST]}" == "y" ]]; then
792		echo "Vhost is only supported on Linux."
793		exit 1
794	fi
795	if [[ "${CONFIG[VIRTIO]}" == "y" ]]; then
796		echo "Virtio is only supported on Linux."
797		exit 1
798	fi
799fi
800
801if [ "${CONFIG[RDMA]}" = "y" ]; then
802	if [[ ! "${CONFIG[RDMA_PROV]}" == "verbs" ]] && [[ ! "${CONFIG[RDMA_PROV]}" == "mlx5_dv" ]]; then
803		echo "Invalid RDMA provider specified, must be \"verbs\" or \"mlx5_dv\""
804		exit 1
805	fi
806
807	if ! echo -e '#include <infiniband/verbs.h>\n#include <rdma/rdma_verbs.h>\n' \
808		'int main(void) { return 0; }\n' \
809		| "${BUILD_CMD[@]}" -libverbs -lrdmacm - 2> /dev/null; then
810		echo "--with-rdma requires libverbs and librdmacm."
811		echo "Please install then re-run this script."
812		exit 1
813	fi
814
815	if echo -e '#include <infiniband/verbs.h>\n' \
816		'int main(void) { return !!IBV_WR_SEND_WITH_INV; }\n' \
817		| "${BUILD_CMD[@]}" -c - 2> /dev/null; then
818		CONFIG[RDMA_SEND_WITH_INVAL]="y"
819	else
820		CONFIG[RDMA_SEND_WITH_INVAL]="n"
821		echo "
822*******************************************************************************
823WARNING: The Infiniband Verbs opcode Send With Invalidate is either not
824supported or is not functional with the current version of libibverbs installed
825on this system. Please upgrade to at least version 1.1.
826
827Beginning with Linux kernel 4.14, the kernel NVMe-oF initiator leverages Send
828With Invalidate RDMA operations to improve performance. Failing to use the
829Send With Invalidate operation on the NVMe-oF target side results in full
830functionality, but greatly reduced performance. The SPDK NVMe-oF target will
831be unable to leverage that operation using the currently installed version
832of libibverbs, so Linux kernel NVMe-oF initiators based on kernels greater
833than or equal to 4.14 will see significantly reduced performance.
834*******************************************************************************"
835	fi
836
837	if echo -e '#include <rdma/rdma_cma.h>\n' \
838		'int main(void) { return !!RDMA_OPTION_ID_ACK_TIMEOUT; }\n' \
839		| "${BUILD_CMD[@]}" -c - 2> /dev/null; then
840		CONFIG[RDMA_SET_ACK_TIMEOUT]="y"
841	else
842		CONFIG[RDMA_SET_ACK_TIMEOUT]="n"
843		echo "RDMA_OPTION_ID_ACK_TIMEOUT is not supported"
844	fi
845
846	if [ "${CONFIG[RDMA_PROV]}" == "mlx5_dv" ]; then
847		if ! echo -e '#include <spdk/stdinc.h>\n' \
848			'#include <infiniband/mlx5dv.h>\n' \
849			'#include <rdma/rdma_cma.h>\n' \
850			'int main(void) { return rdma_establish(NULL) || ' \
851			'!!IBV_QP_INIT_ATTR_SEND_OPS_FLAGS || !!MLX5_OPCODE_RDMA_WRITE; }\n' \
852			| "${BUILD_CMD[@]}" -lmlx5 -I${rootdir}/include -c - 2> /dev/null; then
853			echo "mlx5_dv provider is not supported"
854			exit 1
855		fi
856	fi
857
858	echo "Using '${CONFIG[RDMA_PROV]}' RDMA provider"
859fi
860
861if [[ "${CONFIG[FC]}" = "y" ]]; then
862	if [[ -n "${CONFIG[FC_PATH]}" ]]; then
863		if [ ! -d "${CONFIG[FC_PATH]}" ]; then
864			echo "${CONFIG[FC_PATH]}: directory not found"
865			exit 1
866		fi
867	fi
868fi
869
870if [[ "${CONFIG[ISAL]}" = "y" ]] || [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
871	if [[ "${HAVE_NASM}" = "n" ]] && [[ $arch == x86_64* ]]; then
872		echo "ERROR: ISA-L, compression & crypto require NASM version 2.14 or newer."
873		echo "Please install or upgrade them re-run this script."
874		exit 1
875	fi
876fi
877
878if [[ "${CONFIG[PMDK]}" = "y" ]]; then
879	if ! echo -e '#include <libpmemblk.h>\nint main(void) { return 0; }\n' \
880		| "${BUILD_CMD[@]}" -lpmemblk - 2> /dev/null; then
881		echo "--with-pmdk requires libpmemblk."
882		echo "Please install then re-run this script."
883		exit 1
884	fi
885fi
886
887function dpdk_version() {
888	# Check DPDK version to determine if mlx5_pci driver is supported
889	local dpdk_ver="none"
890	if [[ "${CONFIG[DPDK_DIR]}" == "$rootdir/dpdk/build" ]]; then
891		# DPDK_DIR points at our submodule so ./build may not exist yet. Use
892		# absolute path to lookup the version.
893		dpdk_ver=$(< "$rootdir/dpdk/VERSION")
894	elif [[ -f "${CONFIG[DPDK_DIR]}"/../VERSION ]]; then
895		dpdk_ver=$(< "${CONFIG[DPDK_DIR]}"/../VERSION)
896	fi
897	echo $dpdk_ver
898}
899
900function mlx5_build() {
901	# Check if libmlx5 exists to enable mlx5_pci compress/crypto PMD
902	if ! echo -e '#include <spdk/stdinc.h>\n' \
903		'#include <infiniband/mlx5dv.h>\n' \
904		'#include <infiniband/verbs.h>\n' \
905		'int main(void) { return 0; }\n' \
906		| "${BUILD_CMD[@]}" -lmlx5 -libverbs -I${rootdir}/include -c - 2> /dev/null; then
907		return 1
908	fi
909	return 0
910}
911
912if [[ "${CONFIG[REDUCE]}" = "y" ]]; then
913	if ! echo -e '#include <libpmem.h>\nint main(void) { return 0; }\n' \
914		| "${BUILD_CMD[@]}" -lpmem - 2> /dev/null; then
915		echo "--with-reduce requires libpmem."
916		echo "Please install then re-run this script."
917		exit 1
918	fi
919	# Try to enable mlx5 compress
920	CONFIG[REDUCE_MLX5]="y"
921
922	# Check if libmlx5 exists to enable mlx5_pci compress PMD
923	if ! mlx5_build; then
924		echo "libmlx5 is not found, so disabling DPDK mlx5_pci compress PMD"
925		CONFIG[REDUCE_MLX5]="n"
926	else
927		if [[ "${CONFIG[DPDK_PKG_CONFIG]}" = "y" ]]; then
928			# Check if librte_compress_mlx5 exists in DPDK package
929			if [ ! -f "${CONFIG[DPDK_LIB_DIR]}"/librte_compress_mlx5.so ]; then
930				echo "librte_compress_mlx5 is not found, so disabling DPDK mlx5_pci compress PMD"
931				CONFIG[REDUCE_MLX5]="n"
932			fi
933		else
934			# Check DPDK version to determine if mlx5_pci driver is supported
935			dpdk_ver=$(dpdk_version)
936			if [[ $dpdk_ver = "none" ]]; then
937				echo "Cannot get DPDK version, so disabling DPDK mlx5_pci compress PMD"
938				CONFIG[REDUCE_MLX5]="n"
939			elif [[ -n $dpdk_ver ]] && lt "$dpdk_ver" 21.02.0; then
940				# mlx5_pci for compress is supported by DPDK >- 21.02.0
941				echo "DPDK version ${dpdk_ver} doesn't support mlx5_pci compress PMD"
942				CONFIG[REDUCE_MLX5]="n"
943			elif [[ -n ${CONFIG[DPDK_LIB_DIR]} ]] && [ ! -f "${CONFIG[DPDK_LIB_DIR]}"/librte_compress_mlx5.so ]; then
944				# This is only checked when --with-dpdk or --with-dpdk=* is used
945				echo "librte_compress_mlx5 is not found, so disabling DPDK mlx5_pci compress PMD"
946				CONFIG[REDUCE_MLX5]="n"
947			fi
948		fi
949	fi
950fi
951
952if [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
953	# Try to enable mlx5 crypto
954	CONFIG[CRYPTO_MLX5]="y"
955
956	# Check if libmlx5 exists to enable mlx5_pci compress PMD
957	if ! mlx5_build; then
958		echo "libmlx5 is not found, so disabling DPDK mlx5_pci crypto PMD"
959		CONFIG[CRYPTO_MLX5]="n"
960	else
961		if [[ "${CONFIG[DPDK_PKG_CONFIG]}" = "y" ]]; then
962			# Check if librte_crypto_mlx5 exists in DPDK package
963			if [ ! -f "${CONFIG[DPDK_LIB_DIR]}"/librte_crypto_mlx5.so ]; then
964				echo "librte_crypto_mlx5 is not found, so disabling DPDK mlx5_pci crypto PMD"
965				CONFIG[CRYPTO_MLX5]="n"
966			fi
967		else
968			# Check DPDK version to determine if mlx5_pci driver is supported
969			dpdk_ver=$(dpdk_version)
970			if [[ $dpdk_ver = "none" ]]; then
971				echo "Cannot get DPDK version, so disabling DPDK mlx5_pci crypto PMD"
972				CONFIG[CRYPTO_MLX5]="n"
973			elif [[ -n $dpdk_ver ]] && lt "$dpdk_ver" 21.11.0; then
974				# mlx5_pci for crypto is supported by DPDK >- 21.11.0
975				echo "DPDK version ${dpdk_ver} doesn't support mlx5_pci crypto PMD"
976				CONFIG[CRYPTO_MLX5]="n"
977			elif [[ -n ${CONFIG[DPDK_LIB_DIR]} ]] && [ ! -f "${CONFIG[DPDK_LIB_DIR]}"/librte_crypto_mlx5.so ]; then
978				# This is only checked when --with-dpdk or --with-dpdk=* is used
979				echo "librte_crypto_mlx5 is not found, so disabling DPDK mlx5_pci crypto PMD"
980				CONFIG[CRYPTO_MLX5]="n"
981			fi
982		fi
983	fi
984fi
985
986if [[ "${CONFIG[NVME_CUSE]}" = "y" ]]; then
987	if ! echo -e '#define FUSE_USE_VERSION 31\n#include <fuse3/cuse_lowlevel.h>\n#include <fuse3/fuse_lowlevel.h>\n#include <fuse3/fuse_opt.h>\nint main(void) { return 0; }\n' \
988		| "${BUILD_CMD[@]}" -lfuse3 -D_FILE_OFFSET_BITS=64 - 2> /dev/null; then
989		echo "--with-cuse requires libfuse3."
990		echo "Please install then re-run this script."
991		exit 1
992	fi
993fi
994
995if [[ "${CONFIG[RBD]}" = "y" ]]; then
996	if ! echo -e '#include <rbd/librbd.h>\n#include <rados/librados.h>\n' \
997		'int main(void) { return 0; }\n' \
998		| "${BUILD_CMD[@]}" -lrados -lrbd - 2> /dev/null; then
999		echo "--with-rbd requires librados and librbd."
1000		echo "Please install then re-run this script."
1001		exit 1
1002	fi
1003fi
1004
1005if [[ "${CONFIG[ISCSI_INITIATOR]}" = "y" ]]; then
1006	# Fedora installs libiscsi to /usr/lib64/iscsi for some reason.
1007	if ! echo -e '#include <iscsi/iscsi.h>\n#include <iscsi/scsi-lowlevel.h>\n' \
1008		'#if LIBISCSI_API_VERSION < 20150621\n' \
1009		'#error\n' \
1010		'#endif\n' \
1011		'int main(void) { return 0; }\n' \
1012		| "${BUILD_CMD[@]}" -L/usr/lib64/iscsi -liscsi - 2> /dev/null; then
1013		echo "--with-iscsi-initiator requires libiscsi with"
1014		echo "LIBISCSI_API_VERSION >= 20150621."
1015		echo "Please install then re-run this script."
1016		exit 1
1017	fi
1018fi
1019
1020if [[ "${CONFIG[ASAN]}" = "y" ]]; then
1021	if ! echo -e 'int main(void) { return 0; }\n' \
1022		| "${BUILD_CMD[@]}" -fsanitize=address - 2> /dev/null; then
1023		echo "--enable-asan requires libasan."
1024		echo "Please install then re-run this script."
1025		exit 1
1026	fi
1027fi
1028
1029if [[ "${CONFIG[UBSAN]}" = "y" ]]; then
1030	if ! echo -e 'int main(void) { return 0; }\n' \
1031		| "${BUILD_CMD[@]}" -fsanitize=undefined - 2> /dev/null; then
1032		echo "--enable-ubsan requires libubsan."
1033		echo "Please install then re-run this script."
1034		echo "If installed, please check that the GCC version is at least 6.4"
1035		echo "and synchronize CC accordingly."
1036		exit 1
1037	fi
1038fi
1039
1040if [[ "${CONFIG[TSAN]}" = "y" ]]; then
1041	if ! echo -e 'int main(void) { return 0; }\n' \
1042		| "${BUILD_CMD[@]}" -fsanitize=thread - 2> /dev/null; then
1043		echo "--enable-tsan requires libtsan."
1044		echo "Please install then re-run this script."
1045		exit 1
1046	fi
1047fi
1048
1049if [[ "${CONFIG[OCF]}" = "y" ]]; then
1050	# If OCF_PATH is a file, assume it is a library and use it to compile with
1051	if [ -f ${CONFIG[OCF_PATH]} ]; then
1052		CONFIG[CUSTOMOCF]=y
1053	else
1054		CONFIG[CUSTOMOCF]=n
1055	fi
1056fi
1057
1058if [[ "${CONFIG[PGO_CAPTURE]}" = "y" && "${CONFIG[PGO_USE]}" = "y" ]]; then
1059	echo "ERROR: --enable-pgo-capture and --enable-pgo-use are mutually exclusive."
1060	exit 1
1061elif [[ "${CONFIG[PGO_USE]}" = "y" ]]; then
1062	if [[ "$CC_TYPE" = "clang" ]]; then
1063		# For clang we need to run an extra step on gathered profiling data.
1064		echo "Generating suitable profile data"
1065		llvm-profdata merge -output=build/pgo/default.profdata build/pgo
1066	fi
1067fi
1068
1069if [[ "${CONFIG[URING]}" = "y" ]]; then
1070	if [[ -n "${CONFIG[URING_PATH]}" ]]; then
1071		if [ ! -d "${CONFIG[URING_PATH]}" ]; then
1072			echo "${CONFIG[URING_PATH]}: directory not found"
1073			exit 1
1074		fi
1075	elif ! echo -e '#include <liburing.h>\nint main(void) { return 0; }\n' \
1076		| "${BUILD_CMD[@]}" -luring - 2> /dev/null; then
1077		echo "--with-uring requires liburing."
1078		echo "Please build and install then re-run this script."
1079		exit 1
1080	fi
1081fi
1082
1083if [[ "${CONFIG[FUSE]}" = "y" ]]; then
1084	if [[ ! -d /usr/include/fuse3 ]] && [[ ! -d /usr/local/include/fuse3 ]]; then
1085		echo "--with-fuse requires libfuse3."
1086		echo "Please install then re-run this script."
1087		exit 1
1088	fi
1089fi
1090
1091if [ "${CONFIG[CET]}" = "y" ]; then
1092	if ! echo -e 'int main(void) { return 0; }\n' | "${BUILD_CMD[@]}" -fcf-protection - 2> /dev/null; then
1093		echo "--enable-cet requires compiler/linker that supports CET."
1094		echo "Please install then re-run this script."
1095		exit 1
1096	fi
1097fi
1098
1099if [[ "${CONFIG[FUZZER]}" = "y" && "$CC_TYPE" != "clang" ]]; then
1100	echo "--with-fuzzer requires setting CC and CXX to clang."
1101	exit 1
1102fi
1103
1104if [[ "${CONFIG[ISAL]}" = "y" ]]; then
1105	if [ ! -f "$rootdir"/isa-l/autogen.sh ]; then
1106		echo "ISA-L was not found; To install ISA-L run:"
1107		echo "  git submodule update --init"
1108		exit 1
1109	fi
1110
1111	cd $rootdir/isa-l
1112	ISAL_LOG=$rootdir/isa-l/spdk-isal.log
1113	if [[ -n "${CONFIG[CROSS_PREFIX]}" ]]; then
1114		ISAL_OPTS=("--host=${CONFIG[CROSS_PREFIX]}")
1115	else
1116		ISAL_OPTS=()
1117	fi
1118	echo -n "Configuring ISA-L (logfile: $ISAL_LOG)..."
1119	./autogen.sh &> $ISAL_LOG
1120	./configure CFLAGS="-fPIC -g -O2" "${ISAL_OPTS[@]}" --enable-shared=no >> $ISAL_LOG 2>&1
1121	echo "done."
1122	cd $rootdir
1123fi
1124
1125if [[ "${CONFIG[SMA]}" = "y" ]]; then
1126	if ! python3 -c 'import grpc; import grpc_tools' 2> /dev/null; then
1127		echo "--with-sma requires grpcio and grpcio-tools python packages."
1128		echo "Please install then re-run this script."
1129		exit 1
1130	fi
1131fi
1132
1133# For ARM Neoverse-N1 platform, debug build needs gcc version newer than 8.4
1134if [[ "${CONFIG[DEBUG]}" = "y" && $arch = aarch64* && "$CC_TYPE" = "gcc" ]]; then
1135	GCC_VERSION=$($CC -dumpfullversion)
1136	PART_NUM=$(grep -i -m 1 "CPU part" /proc/cpuinfo | awk '{print $4}')
1137
1138	if [[ "$(printf '%s\n' "8.4.0" "$GCC_VERSION" | sort -V | head -n1)" != "8.4.0" ]]; then
1139		if [[ $PART_NUM = 0xd0c ]]; then
1140			echo "WARNING: For ARM Neoverse-N1 platform, debug build needs GCC version newer than 8.4."
1141			echo "         Will work around this by using armv8.2-a+crypto as target architecture for now."
1142			CONFIG[ARCH]=armv8.2-a+crypto
1143		fi
1144	fi
1145fi
1146
1147# We are now ready to generate final configuration. But first do sanity
1148# check to see if all keys in CONFIG array have its reflection in CONFIG file.
1149if (($(grep -cE "^\s*CONFIG_[[:alnum:]_]+=" "$rootdir/CONFIG") != ${#CONFIG[@]})); then
1150	echo ""
1151	echo "BUG: Some configuration options are not present in CONFIG file. Please update this file."
1152	echo "Missing options in CONFIG (+) file and in current config (-): "
1153	diff -u --label "CONFIG file" --label "CONFIG[@]" \
1154		<(sed -r -e '/^[[:space:]]*$/d; /^[[:space:]]*#.*/d; s/(CONFIG_[[:alnum:]_]+)=.*/\1/g' CONFIG | sort) \
1155		<(printf "CONFIG_%s\n" "${!CONFIG[@]}" | sort)
1156	exit 1
1157fi
1158
1159echo -n "Creating mk/config.mk..."
1160cp -f $rootdir/CONFIG $rootdir/mk/config.mk
1161for key in "${!CONFIG[@]}"; do
1162	sed -i.bak -r "s#[[:space:]]*CONFIG_${key}=.*#CONFIG_${key}\?=${CONFIG[$key]}#g" $rootdir/mk/config.mk
1163done
1164# On FreeBSD sed -i 'SUFFIX' - SUFFIX is mandatory. So no way but to delete the backed file.
1165rm -f $rootdir/mk/config.mk.bak
1166echo "done."
1167
1168# Environment variables
1169echo -n "Creating mk/cc.flags.mk..."
1170rm -f $rootdir/mk/cc.flags.mk
1171[ -n "$CFLAGS" ] && echo "CFLAGS?=$CFLAGS" > $rootdir/mk/cc.flags.mk
1172[ -n "$CXXFLAGS" ] && echo "CXXFLAGS?=$CXXFLAGS" >> $rootdir/mk/cc.flags.mk
1173[ -n "$LDFLAGS" ] && echo "LDFLAGS?=$LDFLAGS" >> $rootdir/mk/cc.flags.mk
1174[ -n "$DESTDIR" ] && echo "DESTDIR?=$DESTDIR" >> $rootdir/mk/cc.flags.mk
1175echo "done."
1176
1177# Create .sh with build config for easy sourcing|lookup during the tests.
1178for conf in "${!CONFIG[@]}"; do
1179	echo "CONFIG_$conf=${CONFIG[$conf]}"
1180done > "$rootdir/test/common/build_config.sh"
1181
1182if [[ $sys_name == "FreeBSD" ]]; then
1183	echo "Type 'gmake' to build."
1184else
1185	echo "Type 'make' to build."
1186fi
1187
1188exit 0
1189