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