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