xref: /spdk/configure (revision 06b537bfdb4393dea857e204b85d8df46a351d8a)
1#!/usr/bin/env bash
2
3set -e
4
5trap 'echo -e "\n\nConfiguration failed\n\n" >&2' ERR
6
7rootdir=$(readlink -f $(dirname $0))
8
9function usage()
10{
11	echo "'configure' configures SPDK to compile on supported platforms."
12	echo ""
13	echo "Usage: ./configure [OPTION]..."
14	echo ""
15	echo "Defaults for the options are specified in brackets."
16	echo ""
17	echo "General:"
18	echo " -h, --help                Display this help and exit"
19	echo ""
20	echo " --prefix=path             Configure installation prefix (default: /usr/local)"
21	echo " --target-arch=arch        Target build architecture. Must be a valid GNU arch. Default: native"
22	echo ""
23	echo " --cross-prefix=prefix     Prefix for cross compilation (default: none)"
24	echo "                           example: aarch64-linux-gnu"
25	echo ""
26	echo " --enable-debug            Configure for debug builds"
27	echo " --enable-werror           Treat compiler warnings as errors"
28	echo " --enable-asan             Enable address sanitizer"
29	echo " --enable-ubsan            Enable undefined behavior sanitizer"
30	echo " --enable-coverage         Enable code coverage tracking"
31	echo " --enable-lto              Enable link-time optimization"
32	echo " --enable-pgo-capture      Enable generation of profile guided optimization data"
33	echo " --enable-pgo-use          Use previously captured profile guided optimization data"
34	echo " --disable-tests           Disable building of functional tests"
35	echo " --disable-unit-tests      Disable building of unit tests"
36	echo " --disable-examples        Disable building of examples"
37	echo ""
38	echo "Specifying Dependencies:"
39	echo "--with-DEPENDENCY[=path]   Use the given dependency. Optionally, provide the"
40	echo "                           path."
41	echo "--without-DEPENDENCY       Do not link to the given dependency. This may"
42	echo "                           disable features and components."
43	echo ""
44	echo "Valid dependencies are listed below."
45	echo " dpdk                      Build against a custom dpdk version. By default, the dpdk"
46	echo "                           submodule in spdk tree will be used."
47	echo "                           example: /usr/share/dpdk/x86_64-default-linuxapp-gcc"
48	echo " env                       Use an alternate environment implementation instead of DPDK."
49	echo "                           Implies --without-dpdk."
50	echo " igb-uio-driver            Build DPDK's igb-uio driver."
51	echo "                           Required on some systems to use qat devices. This flag is"
52	echo "                           effective only with the default dpdk submodule."
53	echo "                           No path required"
54	echo " idxd                      Build the IDXD library and accel framework plug-in module."
55	echo "                           Disabled while experimental. Only built for x86 when enabled."
56	echo " crypto                    Build vbdev crypto module."
57	echo "                           No path required."
58	echo " fio                       Build fio_plugin."
59	echo "                           default: /usr/src/fio"
60	echo " vhost                     Build vhost target. Enabled by default."
61	echo "                           No path required."
62	echo " internal-vhost-lib        Use the internal copy of rte_vhost. By default, the upstream"
63	echo "                           rte_vhost from DPDK will be used."
64	echo "                           No path required."
65	echo " virtio                    Build vhost initiator and virtio-pci bdev modules."
66	echo "                           No path required."
67	echo " pmdk                      Build persistent memory bdev."
68	echo "                           example: /usr/share/pmdk"
69	echo " reduce                    Build vbdev compression module."
70	echo "                           No path required."
71	echo " rbd                       Build Ceph RBD bdev module."
72	echo "                           No path required."
73	echo " rdma                      Build RDMA transport for NVMf target and initiator."
74	echo "                           Accepts optional RDMA provider name. Can be \"verbs\" or \"mlx5_dv\"."
75	echo "                           If no provider specified, \"verbs\" provider is used by default."
76	echo " fc                        Build FC transport for NVMf target."
77	echo "                           If an argument is provided, it is considered a directory containing"
78	echo "                           libufc.a and fc_lld.h. Otherwise the regular system paths will"
79	echo "                           be searched."
80	echo " shared                    Build spdk shared libraries."
81	echo "                           No path required."
82	echo " iscsi-initiator           Build with iscsi bdev module."
83	echo "                           No path required."
84	echo " vtune                     Required to profile I/O under Intel VTune Amplifier XE."
85	echo "                           example: /opt/intel/vtune_amplifier_xe_version"
86	echo " ocf                       Build OCF library and bdev module."
87	echo "                           If argument is directory, interpret it as root of OCF repo"
88	echo "                           If argument is file, interpret it as compiled OCF lib"
89	echo "                           If no argument is specified, OCF git submodule is used by default"
90	echo "                           example: /usr/src/ocf/"
91	echo " isal                      Build with ISA-L. Enabled by default on x86 and aarch64 architectures."
92	echo "                           No path required."
93	echo " uring                     Build I/O uring bdev or socket module."
94	echo "                           If an argument is provided, it is considered a directory containing"
95	echo "                           liburing.a and io_uring.h. Otherwise the regular system paths will"
96	echo "                           be searched."
97	echo " fuse                      Build FUSE components for mounting a blobfs filesystem."
98	echo "                           No path required."
99	echo " nvme-cuse                 Build NVMe driver with support for CUSE-based character devices."
100	echo "                           No path required."
101	echo " raid5                     Build with bdev_raid module RAID5 support."
102	echo "                           No path required."
103	echo ""
104	echo "Environment variables:"
105	echo ""
106	echo "CC                         C compiler"
107	echo "CFLAGS                     C compiler flags"
108	echo "CXX                        C++ compiler"
109	echo "CXXFLAGS                   C++ compiler flags"
110	echo "LD                         Linker"
111	echo "LDFLAGS                    Linker flags"
112	echo "DESTDIR                    Destination for 'make install'"
113	echo ""
114}
115
116# Load default values
117# Convert config to sourcable configuration file
118sed -r 's/CONFIG_([[:alnum:]_]+)=(.*)/CONFIG[\1]=\2/g' $rootdir/CONFIG > $rootdir/CONFIG.sh
119declare -A CONFIG
120source $rootdir/CONFIG.sh
121rm $rootdir/CONFIG.sh
122
123for i in "$@"; do
124	case "$i" in
125		--cross-prefix=*)
126			CONFIG[CROSS_PREFIX]="${i#*=}"
127			;;
128		--enable-lto)
129			CONFIG[LTO]=y
130			;;
131		--disable-lto)
132			CONFIG[LTO]=n
133			;;
134	esac
135done
136
137# Detect the compiler toolchain
138$rootdir/scripts/detect_cc.sh --cc="$CC" --cxx="$CXX" --lto="${CONFIG[LTO]}" --ld="$LD" --cross-prefix="${CONFIG[CROSS_PREFIX]}"  > $rootdir/mk/cc.mk
139
140CC=$(cat $rootdir/mk/cc.mk | grep "DEFAULT_CC=" | sed s/DEFAULT_CC=//)
141CC_TYPE=$(cat $rootdir/mk/cc.mk | grep "CC_TYPE=" | cut -d "=" -f 2)
142
143arch=$($CC -dumpmachine)
144sys_name=$(uname -s)
145
146# Sanitize default configuration. All parameters set by user explicit should fail
147# Force no ISA-L if non-x86 or non-aarch64 architecture
148if [[ "${CONFIG[ISAL]}" = "y" ]]; then
149	if [[ $arch != x86_64* ]] && [[ $arch != aarch64* ]]; then
150		CONFIG[ISAL]=n
151		echo "Notice: ISA-L not supported for ${arch}. Turning off default feature."
152	fi
153fi
154
155if [[ $sys_name == "FreeBSD" ]]; then
156	# Vhost, rte_vhost library and virtio are only supported on Linux.
157	CONFIG[VHOST]="n"
158	CONFIG[VHOST_INTERNAL_LIB]="n"
159	CONFIG[VIRTIO]="n"
160	echo "Notice: Vhost, rte_vhost library and virtio are only supported on Linux. Turning off default feature."
161fi
162
163#check nasm only on x86
164if [[ $arch == x86_64* ]]; then
165	ver=$(nasm -v 2>/dev/null | awk '{print $3}' | sed 's/[^0-9]*//g')
166	if [[ "${ver:0:1}" -le "2" ]] && [[ "${ver:0:3}" -le "214" ]] && [[ "${ver:0:5}" -lt "21400" ]]; then
167		# ISA-L, compression & crypto require NASM version 2.14 or newer.
168		CONFIG[ISAL]=n
169		CONFIG[CRYPTO]=n
170		CONFIG[IPSEC_MB]=n
171		CONFIG[REDUCE]=n
172		HAVE_NASM=n
173		echo "Notice: ISA-L, compression & crypto require NASM version 2.14 or newer. Turning off default ISA-L and crypto features."
174	else
175		HAVE_NASM=y
176	fi
177fi
178
179function check_dir() {
180	arg="$1"
181	dir="${arg#*=}"
182	if [ ! -d "$dir" ]; then
183		echo "$arg: directory not found"
184		exit 1
185	fi
186}
187
188for i in "$@"; do
189	case "$i" in
190		-h|--help)
191			usage
192			exit 0
193			;;
194		--cross-prefix=*) ;&
195		--enable-lto) ;&
196		--disable-lto)
197			# Options handled before detecting CC.
198			;;
199		--prefix=*)
200			CONFIG[PREFIX]="${i#*=}"
201			;;
202		--target-arch=*)
203			CONFIG[ARCH]="${i#*=}"
204			;;
205		--enable-debug)
206			CONFIG[DEBUG]=y
207			;;
208		--disable-debug)
209			CONFIG[DEBUG]=n
210			;;
211		--enable-asan)
212			CONFIG[ASAN]=y
213			;;
214		--disable-asan)
215			CONFIG[ASAN]=n
216			;;
217		--enable-ubsan)
218			CONFIG[UBSAN]=y
219			;;
220		--disable-ubsan)
221			CONFIG[UBSAN]=n
222			;;
223		--enable-tsan)
224			CONFIG[TSAN]=y
225			;;
226		--disable-tsan)
227			CONFIG[TSAN]=n
228			;;
229		--enable-coverage)
230			CONFIG[COVERAGE]=y
231			;;
232		--disable-coverage)
233			CONFIG[COVERAGE]=n
234			;;
235		--enable-pgo-capture)
236			CONFIG[PGO_CAPTURE]=y
237			;;
238		--disable-pgo-capture)
239			CONFIG[PGO_CAPTURE]=n
240			;;
241		--enable-pgo-use)
242			CONFIG[PGO_USE]=y
243			;;
244		--disable-pgo-use)
245			CONFIG[PGO_USE]=n
246			;;
247		--enable-tests)
248			CONFIG[TESTS]=y
249			;;
250		--disable-tests)
251			CONFIG[TESTS]=n
252			;;
253		--enable-unit-tests)
254			CONFIG[UNIT_TESTS]=y
255			;;
256		--disable-unit-tests)
257			CONFIG[UNIT_TESTS]=n
258			;;
259		--enable-examples)
260			CONFIG[EXAMPLES]=y
261			;;
262		--disable-examples)
263			CONFIG[EXAMPLES]=n
264			;;
265		--enable-werror)
266			CONFIG[WERROR]=y
267			;;
268		--disable-werror)
269			CONFIG[WERROR]=n
270			;;
271		--with-dpdk=*)
272			check_dir "$i"
273			CONFIG[DPDK_DIR]=$(readlink -f ${i#*=})
274			;;
275		--without-dpdk)
276			CONFIG[DPDK_DIR]=
277			;;
278		--with-env=*)
279			CONFIG[ENV]="${i#*=}"
280			;;
281		--with-rbd)
282			CONFIG[RBD]=y
283			;;
284		--without-rbd)
285			CONFIG[RBD]=n
286			;;
287		--with-rdma=*)
288			CONFIG[RDMA]=y
289			CONFIG[RDMA_PROV]=${i#*=}
290			;;
291		--with-rdma)
292			CONFIG[RDMA]=y
293			CONFIG[RDMA_PROV]="verbs"
294			;;
295		--without-rdma)
296			CONFIG[RDMA]=n
297			;;
298		--with-fc=*)
299			CONFIG[FC]=y
300			CONFIG[FC_PATH]=$(readlink -f ${i#*=})
301			;;
302		--with-fc)
303			CONFIG[FC]=y
304			CONFIG[FC_PATH]=
305			;;
306		--without-fc)
307			CONFIG[FC]=n
308			CONFIG[FC_PATH]=
309			;;
310		--with-shared)
311			CONFIG[SHARED]=y
312			;;
313		--without-shared)
314			CONFIG[SHARED]=n
315			;;
316		--with-iscsi-initiator)
317			CONFIG[ISCSI_INITIATOR]=y
318			;;
319		--without-iscsi-initiator)
320			CONFIG[ISCSI_INITIATOR]=n
321			;;
322		--with-crypto)
323			CONFIG[CRYPTO]=y
324			;;
325		--without-crypto)
326			CONFIG[CRYPTO]=n
327			;;
328		--with-vhost)
329			CONFIG[VHOST]=y
330			;;
331		--without-vhost)
332			CONFIG[VHOST]=n
333			;;
334		--with-internal-vhost-lib)
335			CONFIG[VHOST_INTERNAL_LIB]=y
336			;;
337		--without-internal-vhost-lib)
338			CONFIG[VHOST_INTERNAL_LIB]=n
339			;;
340		--with-virtio)
341			CONFIG[VIRTIO]=y
342			;;
343		--without-virtio)
344			CONFIG[VIRTIO]=n
345			;;
346		--with-pmdk)
347			CONFIG[PMDK]=y
348			CONFIG[PMDK_DIR]=""
349			;;
350		--with-pmdk=*)
351			CONFIG[PMDK]=y
352			check_dir "$i"
353			CONFIG[PMDK_DIR]=$(readlink -f ${i#*=})
354			;;
355		--without-pmdk)
356			CONFIG[PMDK]=n
357			;;
358		--with-reduce)
359			CONFIG[REDUCE]=y
360			;;
361		--without-reduce)
362			CONFIG[REDUCE]=n
363			;;
364		--with-fio) ;&
365		--with-fio=*)
366			if [[ ${i#*=} != "$i" ]]; then
367				CONFIG[FIO_SOURCE_DIR]=$(readlink -f "${i#*=}")
368			fi
369			check_dir "--with-fio=${CONFIG[FIO_SOURCE_DIR]}"
370			CONFIG[FIO_PLUGIN]=y
371			;;
372		--without-fio)
373			CONFIG[FIO_PLUGIN]=n
374			;;
375		--with-vtune=*)
376			check_dir "$i"
377			CONFIG[VTUNE_DIR]="${i#*=}"
378			CONFIG[VTUNE]=y
379			;;
380		--without-vtune)
381			CONFIG[VTUNE_DIR]=
382			CONFIG[VTUNE]=n
383			;;
384		--with-igb-uio-driver)
385			CONFIG[IGB_UIO_DRIVER]=y
386			;;
387		--without-igb-uio-driver)
388			CONFIG[IGB_UIO_DRIVER]=n
389			;;
390		--with-ocf)
391			CONFIG[OCF]=y
392			CONFIG[OCF_PATH]=$(readlink -f "./ocf")
393			;;
394		--with-ocf=*)
395			CONFIG[OCF]=y
396			CONFIG[OCF_PATH]=$(readlink -f ${i#*=})
397			;;
398		--without-ocf)
399			CONFIG[OCF]=n
400			CONFIG[OCF_PATH]=
401			;;
402		--with-isal)
403			CONFIG[ISAL]=y
404			;;
405		--without-isal)
406			CONFIG[ISAL]=n
407			;;
408		--with-uring=*)
409			CONFIG[URING]=y
410			CONFIG[URING_PATH]=$(readlink -f ${i#*=})
411			;;
412		--with-uring)
413			CONFIG[URING]=y
414			CONFIG[URING_PATH]=
415			;;
416		--without-uring)
417			CONFIG[URING]=n
418			CONFIG[URING_PATH]=
419			;;
420		--with-fuse)
421			CONFIG[FUSE]=y
422			;;
423		--without-fuse)
424			CONFIG[FUSE]=n
425			;;
426		--with-nvme-cuse)
427			CONFIG[NVME_CUSE]=y
428			;;
429		--without-nvme-cuse)
430			CONFIG[NVME_CUSE]=n
431			;;
432		--with-raid5)
433			CONFIG[RAID5]=y
434			;;
435		--without-raid5)
436			CONFIG[RAID5]=n
437			;;
438		--with-idxd)
439			CONFIG[IDXD]=y
440			;;
441		--without-idxd)
442			CONFIG[IDXD]=n
443			;;
444		--)
445			break
446			;;
447		*)
448			echo "Unrecognized option $i"
449			usage
450			exit 1
451	esac
452done
453
454if [[ $arch == x86_64* ]]; then
455	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS -march=native)
456else
457	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS)
458fi
459BUILD_CMD+=(-I/usr/local/include -L/usr/local/lib)
460
461# IDXD uses Intel specific instructions.
462if [[ "${CONFIG[IDXD]}" = "y" ]]; then
463	if [ $(uname -s) == "FreeBSD" ]; then
464		intel="hw.model: Intel"
465		cpu_vendor=$(sysctl -a | grep hw.model | cut -c 1-15)
466	else
467		intel="GenuineIntel"
468		cpu_vendor=$(grep -i 'vendor' /proc/cpuinfo  --max-count=1)
469	fi
470	if [[ "$cpu_vendor" != *"$intel"* ]]; then
471		echo "ERROR: IDXD cannot be used due to CPU incompatiblity."
472		exit 1
473	fi
474fi
475
476# Detect architecture and force no ISA-L if non-x86 or non-aarch64 architecture
477if [[ "${CONFIG[ISAL]}" = "y" ]]; then
478	if [[ $arch != x86_64* ]] && [[ $arch != aarch64* ]]; then
479		echo "ERROR: ISA-L cannot be used due to CPU incompatiblity."
480		exit 1
481	fi
482fi
483
484if [[ "${CONFIG[ISAL]}" = "n" ]] && [[ "${CONFIG[REDUCE]}" = "y" ]]; then
485		echo "ERROR Conflicting options: --with-reduce is not compatible with --without-isal."
486		exit 1
487fi
488
489if [ -z "${CONFIG[ENV]}" ]; then
490	CONFIG[ENV]=$rootdir/lib/env_dpdk
491	echo "Using default SPDK env in ${CONFIG[ENV]}"
492	if [ -z "${CONFIG[DPDK_DIR]}" ]; then
493		if [ ! -f "$rootdir"/dpdk/config/common_base ]; then
494			echo "DPDK not found; please specify --with-dpdk=<path> or run:"
495			echo
496			echo "  git submodule update --init"
497			exit 1
498		else
499			CONFIG[DPDK_DIR]="${rootdir}/dpdk/build"
500			echo "Using default DPDK in ${CONFIG[DPDK_DIR]}"
501		fi
502
503		if [[ "${CONFIG[VHOST]}" = "y" ]] && [[ "${CONFIG[VHOST_INTERNAL_LIB]}" = "n" ]]; then
504			# We lookup "common_linux" file to check if DPDK version is >= 19.05.
505			# "common_linux" is available since exactly DPDK 19.05 - it was renamed
506			# from "common_linuxapp".
507			if [ ! -f "$rootdir"/dpdk/config/common_linux ]; then
508				echo "Notice: Using internal, legacy rte_vhost library due to DPDK" \
509				     "version < 19.05"
510				CONFIG[VHOST_INTERNAL_LIB]=y
511			fi
512		fi
513	else
514		if [[ "${CONFIG[VHOST]}" = "y" ]] && [[ "${CONFIG[VHOST_INTERNAL_LIB]}" = "n" ]]; then
515			# DPDK must be already built, so we can simply try to use the new rte_vhost.
516			# It has a number of internal dependencies though, so don't try to link the
517			# program, just compile it
518			if ! echo -e '#include <rte_vhost.h>\n' \
519				'int main(void) { return rte_vhost_extern_callback_register(0, NULL, NULL); }\n' \
520				| ${BUILD_CMD[@]} -c -Wno-deprecated-declarations -Werror \
521				-I"${CONFIG[DPDK_DIR]}/include" - &>/dev/null; then
522				echo "Notice: DPDK's rte_vhost not found or version < 19.05, using internal," \
523				     "legacy rte_vhost library."
524				CONFIG[VHOST_INTERNAL_LIB]=y
525			fi
526		fi
527	fi
528else
529	if [ -n "${CONFIG[DPDK_DIR]}" ]; then
530		echo "--with-env and --with-dpdk are mutually exclusive."
531		exit 1
532	fi
533
534	if [ "${CONFIG[VHOST]}" = "y" ]; then
535		echo "Vhost is only supported when using the default DPDK environment. Disabling it."
536	fi
537	# Always disable vhost, but only print the error message if the user explicitly turned it on.
538	CONFIG[VHOST]="n"
539	if [ "${CONFIG[VIRTIO]}" = "y" ]; then
540		echo "Virtio is only supported when using the default DPDK environment. Disabling it."
541	fi
542	# Always disable virtio, but only print the error message if the user explicitly turned it on.
543	CONFIG[VIRTIO]="n"
544fi
545
546if [ "${CONFIG[VTUNE]}" = "y" ]; then
547	if [ -z "${CONFIG[VTUNE_DIR]}" ]; then
548		echo "When VTune is enabled, you must specify the VTune directory using --with-vtune=path"
549		exit 1
550	fi
551fi
552
553if [ "${CONFIG[ASAN]}" = "y" -a "${CONFIG[TSAN]}" = "y" ]; then
554	echo "ERROR: ASAN and TSAN cannot be enabled at the same time."
555	exit 1
556fi
557
558if [[ $sys_name == "FreeBSD" ]]; then
559	# FreeBSD doesn't support all configurations
560	if [[ "${CONFIG[COVERAGE]}" == "y" ]]; then
561		echo "ERROR: CONFIG_COVERAGE not available on FreeBSD"
562		exit 1
563	fi
564fi
565
566if [[ $sys_name == "FreeBSD" ]]; then
567	if [[ "${CONFIG[VHOST]}" == "y" ]]; then
568		echo "Vhost is only supported on Linux."
569		exit 1
570	fi
571	if [[ "${CONFIG[VHOST_INTERNAL_LIB]}" == "y" ]]; then
572		echo "Internal rte_vhost library is only supported on Linux."
573		exit 1
574	fi
575	if [[ "${CONFIG[VIRTIO]}" == "y" ]]; then
576		echo "Virtio is only supported on Linux."
577		exit 1
578	fi
579fi
580
581if [ "${CONFIG[RDMA]}" = "y" ]; then
582  if [[ ! "${CONFIG[RDMA_PROV]}" == "verbs" ]] && [[ ! "${CONFIG[RDMA_PROV]}" == "mlx5_dv" ]]; then
583    echo "Invalid RDMA provider specified, must be \"verbs\" or \"mlx5_dv\""
584    exit 1
585  fi
586
587	if ! echo -e '#include <infiniband/verbs.h>\n#include <rdma/rdma_verbs.h>\n' \
588		'int main(void) { return 0; }\n' \
589		| ${BUILD_CMD[@]} -libverbs -lrdmacm - 2>/dev/null; then
590		echo --with-rdma requires libverbs and librdmacm.
591		echo Please install then re-run this script.
592		exit 1
593	fi
594
595	if echo -e '#include <infiniband/verbs.h>\n' \
596		'int main(void) { return !!IBV_WR_SEND_WITH_INV; }\n' \
597		| ${BUILD_CMD[@]} -c - 2>/dev/null; then
598		CONFIG[RDMA_SEND_WITH_INVAL]="y"
599	else
600		CONFIG[RDMA_SEND_WITH_INVAL]="n"
601		echo "
602*******************************************************************************
603WARNING: The Infiniband Verbs opcode Send With Invalidate is either not
604supported or is not functional with the current version of libibverbs installed
605on this system. Please upgrade to at least version 1.1.
606
607Beginning with Linux kernel 4.14, the kernel NVMe-oF initiator leverages Send
608With Invalidate RDMA operations to improve performance. Failing to use the
609Send With Invalidate operation on the NVMe-oF target side results in full
610functionality, but greatly reduced performance. The SPDK NVMe-oF target will
611be unable to leverage that operation using the currently installed version
612of libibverbs, so Linux kernel NVMe-oF initiators based on kernels greater
613than or equal to 4.14 will see significantly reduced performance.
614*******************************************************************************"
615	fi
616
617	if echo -e '#include <rdma/rdma_cma.h>\n' \
618		'int main(void) { return !!RDMA_OPTION_ID_ACK_TIMEOUT; }\n' \
619		| ${BUILD_CMD[@]} -c - 2>/dev/null; then
620		CONFIG[RDMA_SET_ACK_TIMEOUT]="y"
621	else
622		CONFIG[RDMA_SET_ACK_TIMEOUT]="n"
623		echo "RDMA_OPTION_ID_ACK_TIMEOUT is not supported"
624	fi
625
626	if [ "${CONFIG[RDMA_PROV]}" == "mlx5_dv" ]; then
627	  if ! echo -e '#include <spdk/stdinc.h>\n' \
628	    '#include <infiniband/mlx5dv.h>\n' \
629	    '#include <rdma/rdma_cma.h>\n' \
630		  'int main(void) { return rdma_establish(NULL) || ' \
631		  '!!IBV_QP_INIT_ATTR_SEND_OPS_FLAGS || !!MLX5_OPCODE_RDMA_WRITE; }\n' \
632		  | ${BUILD_CMD[@]} -lmlx5 -I${rootdir}/include -c - 2>/dev/null; then
633      echo "mlx5_dv provider is not supported"
634		  exit 1
635	  fi
636	fi
637
638	echo "Using "${CONFIG[RDMA_PROV]}" RDMA provider"
639fi
640
641if [[ "${CONFIG[FC]}" = "y" ]]; then
642	if [[ -n "${CONFIG[FC_PATH]}" ]]; then
643		if [ ! -d "${CONFIG[FC_PATH]}" ]; then
644			echo "${CONFIG[FC_PATH]}: directory not found"
645			exit 1
646		fi
647	fi
648fi
649
650if [[ "${CONFIG[ISAL]}" = "y" ]] || [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
651	if [[ "${HAVE_NASM}" = "n" ]] && [[ $arch == x86_64* ]]; then
652		echo "ERROR: ISA-L, compression & crypto require NASM version 2.14 or newer."
653		echo "Please install or upgrade them re-run this script."
654		exit 1
655	else
656		if [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
657			CONFIG[IPSEC_MB]=y
658		fi
659	fi
660fi
661
662if [[ "${CONFIG[ISAL]}" = "y" ]]; then
663	if [ ! -f "$rootdir"/isa-l/autogen.sh ]; then
664		echo "ISA-L was not found; To install ISA-L run:"
665		echo "  git submodule update --init"
666		exit 1
667	fi
668
669	cd $rootdir/isa-l
670	ISAL_LOG=$rootdir/isa-l/spdk-isal.log
671	echo -n "Configuring ISA-L (logfile: $ISAL_LOG)..."
672	./autogen.sh &> $ISAL_LOG
673	./configure CFLAGS="-fPIC -g -O2" --enable-shared=no >> $ISAL_LOG 2>&1
674	echo "done."
675	cd $rootdir
676fi
677
678if [[ "${CONFIG[PMDK]}" = "y" ]]; then
679	if ! echo -e '#include <libpmemblk.h>\nint main(void) { return 0; }\n' \
680		| ${BUILD_CMD[@]} -lpmemblk - 2>/dev/null; then
681		echo --with-pmdk requires libpmemblk.
682		echo Please install then re-run this script.
683		exit 1
684	fi
685fi
686
687if [[ "${CONFIG[REDUCE]}" = "y" ]]; then
688	if ! echo -e '#include <libpmem.h>\nint main(void) { return 0; }\n' \
689		| ${BUILD_CMD[@]} -lpmem - 2>/dev/null; then
690		echo --with-reduce requires libpmem.
691		echo Please install then re-run this script.
692		exit 1
693	fi
694fi
695
696if [[ "${CONFIG[NVME_CUSE]}" = "y" ]]; then
697	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' \
698		| ${BUILD_CMD[@]} -lfuse3 -D_FILE_OFFSET_BITS=64 - 2>/dev/null; then
699		echo --with-cuse requires libfuse3.
700		echo Please install then re-run this script.
701		exit 1
702	fi
703fi
704
705if [[ "${CONFIG[RBD]}" = "y" ]]; then
706	if ! echo -e '#include <rbd/librbd.h>\n#include <rados/librados.h>\n' \
707		'int main(void) { return 0; }\n' \
708		| ${BUILD_CMD[@]} -lrados -lrbd - 2>/dev/null; then
709		echo --with-rbd requires librados and librbd.
710		echo Please install then re-run this script.
711		exit 1
712	fi
713fi
714
715if [[ "${CONFIG[ISCSI_INITIATOR]}" = "y" ]]; then
716	# Fedora installs libiscsi to /usr/lib64/iscsi for some reason.
717	if ! echo -e '#include <iscsi/iscsi.h>\n#include <iscsi/scsi-lowlevel.h>\n' \
718		'#if LIBISCSI_API_VERSION < 20150621\n' \
719		'#error\n' \
720		'#endif\n' \
721		'int main(void) { return 0; }\n' \
722		| ${BUILD_CMD[@]} -L/usr/lib64/iscsi -liscsi - 2>/dev/null; then
723		echo --with-iscsi-initiator requires libiscsi with
724		echo 'LIBISCSI_API_VERSION >= 20150621.'
725		echo Please install then re-run this script.
726		exit 1
727	fi
728fi
729
730if [[ "${CONFIG[ASAN]}" = "y" ]]; then
731	if ! echo -e 'int main(void) { return 0; }\n' \
732		| ${BUILD_CMD[@]} -fsanitize=address - 2>/dev/null; then
733		echo --enable-asan requires libasan.
734		echo Please install then re-run this script.
735		exit 1
736	fi
737fi
738
739if [[ "${CONFIG[UBSAN]}" = "y" ]]; then
740	if ! echo -e 'int main(void) { return 0; }\n' \
741		| ${BUILD_CMD[@]} -fsanitize=undefined - 2>/dev/null; then
742		echo --enable-ubsan requires libubsan.
743		echo Please install then re-run this script.
744		echo If installed, please check that the GCC version is at least 6.4 \
745		     and synchronize CC accordingly.
746		exit 1
747	fi
748fi
749
750if [[ "${CONFIG[TSAN]}" = "y" ]]; then
751	if ! echo -e 'int main(void) { return 0; }\n' \
752		| ${BUILD_CMD[@]} -fsanitize=thread - 2>/dev/null; then
753		echo --enable-tsan requires libtsan.
754		echo Please install then re-run this script.
755		exit 1
756	fi
757fi
758
759if [[ "${CONFIG[OCF]}" = "y" ]]; then
760	# If OCF_PATH is a file, assume it is a library and use it to compile with
761	if [ -f ${CONFIG[OCF_PATH]} ]; then
762		CONFIG[CUSTOMOCF]=y
763	else
764		CONFIG[CUSTOMOCF]=n
765	fi
766fi
767
768if [[ "${CONFIG[PGO_CAPTURE]}" = "y" && "${CONFIG[PGO_USE]}" = "y" ]]; then
769	echo "ERROR: --enable-pgo-capture and --enable-pgo-use are mutually exclusive."
770	exit 1
771elif [[ "${CONFIG[PGO_USE]}" = "y" ]]; then
772	if [[ "$CC_TYPE" = "clang" ]]; then
773		# For clang we need to run an extra step on gathered profiling data.
774		echo "Generating suitable profile data"
775		llvm-profdata merge -output=build/pgo/default.profdata build/pgo
776	fi
777fi
778
779if [[ "${CONFIG[URING]}" = "y" ]]; then
780	if [[ -n "${CONFIG[URING_PATH]}" ]]; then
781		if [ ! -d "${CONFIG[URING_PATH]}" ]; then
782			echo "${CONFIG[URING_PATH]}: directory not found"
783			exit 1
784		fi
785	fi
786fi
787
788if [[ "${CONFIG[FUSE]}" = "y" ]]; then
789	if [[ ! -d /usr/include/fuse3 ]] && [[ ! -d /usr/local/include/fuse3 ]]; then
790		echo "--with-fuse requires libfuse3."
791		echo "Please install then re-run this script."
792		exit 1
793	fi
794fi
795
796# We are now ready to generate final configuration. But first do sanity
797# check to see if all keys in CONFIG array have its reflection in CONFIG file.
798if [ $(egrep -c "^\s*CONFIG_[[:alnum:]_]+=" $rootdir/CONFIG) -ne ${#CONFIG[@]} ]; then
799	echo ""
800	echo "BUG: Some configuration options are not present in CONFIG file. Please update this file."
801	echo "Missing options in CONFIG (+) file and in current config (-): "
802	diff -u --label "CONFIG file" --label "CONFIG[@]" \
803		<(sed -r -e '/^\s*$/d; /^\s*#.*/d; s/(CONFIG_[[:alnum:]_]+)=.*/\1/g' CONFIG | sort) \
804		<(printf "CONFIG_%s\n" ${!CONFIG[@]} | sort)
805	exit 1
806fi
807
808echo -n "Creating mk/config.mk..."
809cp -f $rootdir/CONFIG $rootdir/mk/config.mk
810for key in ${!CONFIG[@]}; do
811	sed -i.bak -r "s#^\s*CONFIG_${key}=.*#CONFIG_${key}\?=${CONFIG[$key]}#g" $rootdir/mk/config.mk
812done
813# On FreeBSD sed -i 'SUFFIX' - SUFFIX is mandatory. So no way but to delete the backed file.
814rm -f $rootdir/mk/config.mk.bak
815echo "done."
816
817# Environment variables
818echo -n "Creating mk/cc.flags.mk..."
819rm -f $rootdir/mk/cc.flags.mk
820[ -n "$CFLAGS" ] && echo "CFLAGS?=$CFLAGS" > $rootdir/mk/cc.flags.mk
821[ -n "$CXXFLAGS" ] && echo "CXXFLAGS?=$CXXFLAGS" >> $rootdir/mk/cc.flags.mk
822[ -n "$LDFLAGS" ] && echo "LDFLAGS?=$LDFLAGS" >> $rootdir/mk/cc.flags.mk
823[ -n "$DESTDIR" ] && echo "DESTDIR?=$DESTDIR" >> $rootdir/mk/cc.flags.mk
824echo "done."
825
826# Create .sh with build config for easy sourcing|lookup during the tests.
827for conf in "${!CONFIG[@]}"; do
828	echo "CONFIG_$conf=${CONFIG[$conf]}"
829done >"$rootdir/test/common/build_config.sh"
830
831if [[ $sys_name == "FreeBSD" ]]; then
832	echo "Type 'gmake' to build."
833else
834	echo "Type 'make' to build."
835fi
836
837exit 0
838