xref: /spdk/configure (revision 1fa071d332db21bf893d581a8e93b425ba788a24)
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-log-bt           Enable support of backtrace printing in SPDK logs (requires libunwind)."
28	echo " --enable-werror           Treat compiler warnings as errors"
29	echo " --enable-asan             Enable address sanitizer"
30	echo " --enable-ubsan            Enable undefined behavior sanitizer"
31	echo " --enable-coverage         Enable code coverage tracking"
32	echo " --enable-lto              Enable link-time optimization"
33	echo " --enable-pgo-capture      Enable generation of profile guided optimization data"
34	echo " --enable-pgo-use          Use previously captured profile guided optimization data"
35	echo " --disable-tests           Disable building of functional tests"
36	echo " --disable-unit-tests      Disable building of unit tests"
37	echo " --disable-examples        Disable building of examples"
38	echo ""
39	echo "Specifying Dependencies:"
40	echo "--with-DEPENDENCY[=path]   Use the given dependency. Optionally, provide the"
41	echo "                           path."
42	echo "--without-DEPENDENCY       Do not link to the given dependency. This may"
43	echo "                           disable features and components."
44	echo ""
45	echo "Valid dependencies are listed below."
46	echo " dpdk                      Build against a custom dpdk version. By default, the dpdk"
47	echo "                           submodule in spdk tree will be used."
48	echo "                           example: /usr/share/dpdk/x86_64-default-linuxapp-gcc"
49	echo " env                       Use an alternate environment implementation instead of DPDK."
50	echo "                           Implies --without-dpdk."
51	echo " igb-uio-driver            Build DPDK's igb-uio driver."
52	echo "                           Required on some systems to use qat devices. This flag is"
53	echo "                           effective only with the default dpdk submodule."
54	echo "                           No path required"
55	echo " crypto                    Build vbdev crypto module."
56	echo "                           No path required."
57	echo " fio                       Build fio_plugin."
58	echo "                           default: /usr/src/fio"
59	echo " vhost                     Build vhost target. Enabled by default."
60	echo "                           No path required."
61	echo " internal-vhost-lib        Use the internal copy of rte_vhost. By default, the upstream"
62	echo "                           rte_vhost from DPDK will be used."
63	echo "                           No path required."
64	echo " virtio                    Build vhost initiator and virtio-pci bdev modules."
65	echo "                           No path required."
66	echo " pmdk                      Build persistent memory bdev."
67	echo "                           example: /usr/share/pmdk"
68	echo " reduce                    Build vbdev compression module."
69	echo "                           No path required."
70	echo " vpp                       Build VPP net module."
71	echo "                           example: /vpp_repo/build-root/rpmbuild/vpp-18.01.1.0/build-root/install-vpp-native/vpp"
72	echo " rbd                       Build Ceph RBD bdev module."
73	echo "                           No path required."
74	echo " rdma                      Build RDMA transport for NVMf target and initiator."
75	echo "                           No path required."
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=" | cut -d "=" -f 2)
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 "213" ]] && [[ "${ver:0:5}" -lt "21303" ]]; then
167		# ISA-L, compression & crypto require NASM version 2.13.03 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.13.03 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-log-bt)
212			CONFIG[LOG_BACKTRACE]=y
213			;;
214		--disable-log-bt)
215			CONFIG[LOG_BACKTRACE]=n
216			;;
217		--enable-asan)
218			CONFIG[ASAN]=y
219			;;
220		--disable-asan)
221			CONFIG[ASAN]=n
222			;;
223		--enable-ubsan)
224			CONFIG[UBSAN]=y
225			;;
226		--disable-ubsan)
227			CONFIG[UBSAN]=n
228			;;
229		--enable-tsan)
230			CONFIG[TSAN]=y
231			;;
232		--disable-tsan)
233			CONFIG[TSAN]=n
234			;;
235		--enable-coverage)
236			CONFIG[COVERAGE]=y
237			;;
238		--disable-coverage)
239			CONFIG[COVERAGE]=n
240			;;
241		--enable-pgo-capture)
242			CONFIG[PGO_CAPTURE]=y
243			;;
244		--disable-pgo-capture)
245			CONFIG[PGO_CAPTURE]=n
246			;;
247		--enable-pgo-use)
248			CONFIG[PGO_USE]=y
249			;;
250		--disable-pgo-use)
251			CONFIG[PGO_USE]=n
252			;;
253		--enable-tests)
254			CONFIG[TESTS]=y
255			;;
256		--disable-tests)
257			CONFIG[TESTS]=n
258			;;
259		--enable-unit-tests)
260			CONFIG[UNIT_TESTS]=y
261			;;
262		--disable-unit-tests)
263			CONFIG[UNIT_TESTS]=n
264			;;
265		--enable-examples)
266			CONFIG[EXAMPLES]=y
267			;;
268		--disable-examples)
269			CONFIG[EXAMPLES]=n
270			;;
271		--enable-werror)
272			CONFIG[WERROR]=y
273			;;
274		--disable-werror)
275			CONFIG[WERROR]=n
276			;;
277		--with-dpdk=*)
278			check_dir "$i"
279			CONFIG[DPDK_DIR]=$(readlink -f ${i#*=})
280			;;
281		--without-dpdk)
282			CONFIG[DPDK_DIR]=
283			;;
284		--with-env=*)
285			CONFIG[ENV]="${i#*=}"
286			;;
287		--with-rbd)
288			CONFIG[RBD]=y
289			;;
290		--without-rbd)
291			CONFIG[RBD]=n
292			;;
293		--with-rdma)
294			CONFIG[RDMA]=y
295			;;
296		--without-rdma)
297			CONFIG[RDMA]=n
298			;;
299		--with-fc=*)
300			CONFIG[FC]=y
301			CONFIG[FC_PATH]=$(readlink -f ${i#*=})
302			;;
303		--with-fc)
304			CONFIG[FC]=y
305			CONFIG[FC_PATH]=
306			;;
307		--without-fc)
308			CONFIG[FC]=n
309			CONFIG[FC_PATH]=
310			;;
311		--with-shared)
312			CONFIG[SHARED]=y
313			;;
314		--without-shared)
315			CONFIG[SHARED]=n
316			;;
317		--with-iscsi-initiator)
318			CONFIG[ISCSI_INITIATOR]=y
319			;;
320		--without-iscsi-initiator)
321			CONFIG[ISCSI_INITIATOR]=n
322			;;
323		--with-crypto)
324			CONFIG[CRYPTO]=y
325			;;
326		--without-crypto)
327			CONFIG[CRYPTO]=n
328			;;
329		--with-vhost)
330			CONFIG[VHOST]=y
331			;;
332		--without-vhost)
333			CONFIG[VHOST]=n
334			;;
335		--with-internal-vhost-lib)
336			CONFIG[VHOST_INTERNAL_LIB]=y
337			;;
338		--without-internal-vhost-lib)
339			CONFIG[VHOST_INTERNAL_LIB]=n
340			;;
341		--with-virtio)
342			CONFIG[VIRTIO]=y
343			;;
344		--without-virtio)
345			CONFIG[VIRTIO]=n
346			;;
347		--with-pmdk)
348			CONFIG[PMDK]=y
349			CONFIG[PMDK_DIR]=""
350			;;
351		--with-pmdk=*)
352			CONFIG[PMDK]=y
353			check_dir "$i"
354			CONFIG[PMDK_DIR]=$(readlink -f ${i#*=})
355			;;
356		--without-pmdk)
357			CONFIG[PMDK]=n
358			;;
359		--with-reduce)
360			CONFIG[REDUCE]=y
361			;;
362		--without-reduce)
363			CONFIG[REDUCE]=n
364			;;
365		--with-vpp)
366			CONFIG[VPP]=y
367			;;
368		--with-vpp=*)
369			CONFIG[VPP]=y
370			check_dir "$i"
371			CONFIG[VPP_DIR]=$(readlink -f ${i#*=})
372			;;
373		--without-vpp)
374			CONFIG[VPP]=n
375			;;
376		--with-fio) ;&
377		--with-fio=*)
378			if [[ ${i#*=} != "$i" ]]; then
379				CONFIG[FIO_SOURCE_DIR]=$(readlink -f "${i#*=}")
380			fi
381			check_dir "--with-fio=${CONFIG[FIO_SOURCE_DIR]}"
382			CONFIG[FIO_PLUGIN]=y
383			;;
384		--without-fio)
385			CONFIG[FIO_PLUGIN]=n
386			;;
387		--with-vtune=*)
388			check_dir "$i"
389			CONFIG[VTUNE_DIR]="${i#*=}"
390			CONFIG[VTUNE]=y
391			;;
392		--without-vtune)
393			CONFIG[VTUNE_DIR]=
394			CONFIG[VTUNE]=n
395			;;
396		--with-igb-uio-driver)
397			CONFIG[IGB_UIO_DRIVER]=y
398			;;
399		--without-igb-uio-driver)
400			CONFIG[IGB_UIO_DRIVER]=n
401			;;
402		--with-ocf)
403			CONFIG[OCF]=y
404			CONFIG[OCF_PATH]=$(readlink -f "./ocf")
405			;;
406		--with-ocf=*)
407			CONFIG[OCF]=y
408			CONFIG[OCF_PATH]=$(readlink -f ${i#*=})
409			;;
410		--without-ocf)
411			CONFIG[OCF]=n
412			CONFIG[OCF_PATH]=
413			;;
414		--with-isal)
415			CONFIG[ISAL]=y
416			;;
417		--without-isal)
418			CONFIG[ISAL]=n
419			;;
420		--with-uring=*)
421			CONFIG[URING]=y
422			CONFIG[URING_PATH]=$(readlink -f ${i#*=})
423			;;
424		--with-uring)
425			CONFIG[URING]=y
426			CONFIG[URING_PATH]=
427			;;
428		--without-uring)
429			CONFIG[URING]=n
430			CONFIG[URING_PATH]=
431			;;
432		--with-fuse)
433			CONFIG[FUSE]=y
434			;;
435		--without-fuse)
436			CONFIG[FUSE]=n
437			;;
438		--with-nvme-cuse)
439			CONFIG[NVME_CUSE]=y
440			;;
441		--without-nvme-cuse)
442			CONFIG[NVME_CUSE]=n
443			;;
444		--with-raid5)
445			CONFIG[RAID5]=y
446			;;
447		--without-raid5)
448			CONFIG[RAID5]=n
449			;;
450		--)
451			break
452			;;
453		*)
454			echo "Unrecognized option $i"
455			usage
456			exit 1
457	esac
458done
459
460if [[ $arch == x86_64* ]]; then
461	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS -march=native)
462else
463	BUILD_CMD=($CC -o /dev/null -x c $CPPFLAGS $CFLAGS $LDFLAGS)
464fi
465
466# Detect architecture and force no ISA-L if non-x86 or non-aarch64 architecture
467if [[ "${CONFIG[ISAL]}" = "y" ]]; then
468	if [[ $arch != x86_64* ]] && [[ $arch != aarch64* ]]; then
469		echo "ERROR: ISA-L cannot be used due to CPU incompatiblity."
470		exit 1
471	fi
472fi
473
474if [[ "${CONFIG[ISAL]}" = "n" ]] && [[ "${CONFIG[REDUCE]}" = "y" ]]; then
475		echo "ERROR Conflicting options: --with-reduce is not compatible with --without-isal."
476		exit 1
477fi
478
479if [ -z "${CONFIG[ENV]}" ]; then
480	CONFIG[ENV]=$rootdir/lib/env_dpdk
481	echo "Using default SPDK env in ${CONFIG[ENV]}"
482	if [ -z "${CONFIG[DPDK_DIR]}" ]; then
483		if [ ! -f "$rootdir"/dpdk/config/common_base ]; then
484			echo "DPDK not found; please specify --with-dpdk=<path> or run:"
485			echo
486			echo "  git submodule update --init"
487			exit 1
488		else
489			CONFIG[DPDK_DIR]="${rootdir}/dpdk/build"
490			echo "Using default DPDK in ${CONFIG[DPDK_DIR]}"
491		fi
492
493		if [[ "${CONFIG[VHOST]}" = "y" ]] && [[ "${CONFIG[VHOST_INTERNAL_LIB]}" = "n" ]]; then
494			# We lookup "common_linux" file to check if DPDK version is >= 19.05.
495			# "common_linux" is available since exactly DPDK 19.05 - it was renamed
496			# from "common_linuxapp".
497			if [ ! -f "$rootdir"/dpdk/config/common_linux ]; then
498				echo "Notice: Using internal, legacy rte_vhost library due to DPDK" \
499				     "version < 19.05"
500				CONFIG[VHOST_INTERNAL_LIB]=y
501			fi
502		fi
503	else
504		if [[ "${CONFIG[VHOST]}" = "y" ]] && [[ "${CONFIG[VHOST_INTERNAL_LIB]}" = "n" ]]; then
505			# DPDK must be already built, so we can simply try to use the new rte_vhost.
506			# It has a number of internal dependencies though, so don't try to link the
507			# program, just compile it
508			if ! echo -e '#include <rte_vhost.h>\n' \
509				'int main(void) { return rte_vhost_extern_callback_register(0, NULL, NULL); }\n' \
510				| ${BUILD_CMD[@]} -c -Wno-deprecated-declarations -Werror \
511				-I"${CONFIG[DPDK_DIR]}/include" - &>/dev/null; then
512				echo "Notice: DPDK's rte_vhost not found or version < 19.05, using internal," \
513				     "legacy rte_vhost library."
514				CONFIG[VHOST_INTERNAL_LIB]=y
515			fi
516		fi
517	fi
518else
519	if [ -n "${CONFIG[DPDK_DIR]}" ]; then
520		echo "--with-env and --with-dpdk are mutually exclusive."
521		exit 1
522	fi
523
524	if [ "${CONFIG[VHOST]}" = "y" ]; then
525		echo "Vhost is only supported when using the default DPDK environment. Disabling it."
526	fi
527	# Always disable vhost, but only print the error message if the user explicitly turned it on.
528	CONFIG[VHOST]="n"
529	if [ "${CONFIG[VIRTIO]}" = "y" ]; then
530		echo "Virtio is only supported when using the default DPDK environment. Disabling it."
531	fi
532	# Always disable virtio, but only print the error message if the user explicitly turned it on.
533	CONFIG[VIRTIO]="n"
534fi
535
536if [ "${CONFIG[VTUNE]}" = "y" ]; then
537	if [ -z "${CONFIG[VTUNE_DIR]}" ]; then
538		echo "When VTune is enabled, you must specify the VTune directory using --with-vtune=path"
539		exit 1
540	fi
541fi
542
543if [ "${CONFIG[ASAN]}" = "y" -a "${CONFIG[TSAN]}" = "y" ]; then
544	echo "ERROR: ASAN and TSAN cannot be enabled at the same time."
545	exit 1
546fi
547
548if [[ $sys_name == "FreeBSD" ]]; then
549	# FreeBSD doesn't support all configurations
550	if [[ "${CONFIG[COVERAGE]}" == "y" ]]; then
551		echo "ERROR: CONFIG_COVERAGE not available on FreeBSD"
552		exit 1
553	fi
554fi
555
556if [[ $sys_name == "FreeBSD" ]]; then
557	if [[ "${CONFIG[VHOST]}" == "y" ]]; then
558		echo "Vhost is only supported on Linux."
559		exit 1
560	fi
561	if [[ "${CONFIG[VHOST_INTERNAL_LIB]}" == "y" ]]; then
562		echo "Internal rte_vhost library is only supported on Linux."
563		exit 1
564	fi
565	if [[ "${CONFIG[VIRTIO]}" == "y" ]]; then
566		echo "Virtio is only supported on Linux."
567		exit 1
568	fi
569fi
570
571if [ "${CONFIG[RDMA]}" = "y" ]; then
572	if ! echo -e '#include <infiniband/verbs.h>\n#include <rdma/rdma_verbs.h>\n' \
573		'int main(void) { return 0; }\n' \
574		| ${BUILD_CMD[@]} -libverbs -lrdmacm - 2>/dev/null; then
575		echo --with-rdma requires libverbs and librdmacm.
576		echo Please install then re-run this script.
577		exit 1
578	fi
579
580	if echo -e '#include <infiniband/verbs.h>\n' \
581		'int main(void) { return !!IBV_WR_SEND_WITH_INV; }\n' \
582		| ${BUILD_CMD[@]} -c - 2>/dev/null; then
583		CONFIG[RDMA_SEND_WITH_INVAL]="y"
584	else
585		CONFIG[RDMA_SEND_WITH_INVAL]="n"
586		echo "
587*******************************************************************************
588WARNING: The Infiniband Verbs opcode Send With Invalidate is either not
589supported or is not functional with the current version of libibverbs installed
590on this system. Please upgrade to at least version 1.1.
591
592Beginning with Linux kernel 4.14, the kernel NVMe-oF initiator leverages Send
593With Invalidate RDMA operations to improve performance. Failing to use the
594Send With Invalidate operation on the NVMe-oF target side results in full
595functionality, but greatly reduced performance. The SPDK NVMe-oF target will
596be unable to leverage that operation using the currently installed version
597of libibverbs, so Linux kernel NVMe-oF initiators based on kernels greater
598than or equal to 4.14 will see significantly reduced performance.
599*******************************************************************************"
600	fi
601
602	if echo -e '#include <rdma/rdma_cma.h>\n' \
603		'int main(void) { return !!RDMA_OPTION_ID_ACK_TIMEOUT; }\n' \
604		| ${BUILD_CMD[@]} -c - 2>/dev/null; then
605		CONFIG[RDMA_SET_ACK_TIMEOUT]="y"
606	else
607		CONFIG[RDMA_SET_ACK_TIMEOUT]="n"
608		echo "RDMA_OPTION_ID_ACK_TIMEOUT is not supported"
609	fi
610
611fi
612
613if [[ "${CONFIG[FC]}" = "y" ]]; then
614	if [[ -n "${CONFIG[FC_PATH]}" ]]; then
615		if [ ! -d "${CONFIG[FC_PATH]}" ]; then
616			echo "${CONFIG[FC_PATH]}: directory not found"
617			exit 1
618		fi
619	fi
620fi
621
622if [[ "${CONFIG[ISAL]}" = "y" ]] || [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
623	if [[ "${HAVE_NASM}" = "n" ]] && [[ $arch == x86_64* ]]; then
624		echo "ERROR: ISA-L, compression & crypto require NASM version 2.13.03 or newer."
625		echo "Please install or upgrade them re-run this script."
626		exit 1
627	else
628		if [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
629			CONFIG[IPSEC_MB]=y
630		fi
631	fi
632fi
633
634if [[ "${CONFIG[ISAL]}" = "y" ]]; then
635	if [ ! -f "$rootdir"/isa-l/autogen.sh ]; then
636		echo "ISA-L was not found; To install ISA-L run:"
637		echo "  git submodule update --init"
638		exit 1
639	fi
640
641	cd $rootdir/isa-l
642	ISAL_LOG=$rootdir/isa-l/spdk-isal.log
643	echo -n "Configuring ISA-L (logfile: $ISAL_LOG)..."
644	./autogen.sh &> $ISAL_LOG
645	./configure CFLAGS="-fPIC -g -O2" --enable-shared=no >> $ISAL_LOG 2>&1
646	echo "done."
647	cd $rootdir
648fi
649
650if [[ "${CONFIG[PMDK]}" = "y" ]]; then
651	if ! echo -e '#include <libpmemblk.h>\nint main(void) { return 0; }\n' \
652		| ${BUILD_CMD[@]} -lpmemblk - 2>/dev/null; then
653		echo --with-pmdk requires libpmemblk.
654		echo Please install then re-run this script.
655		exit 1
656	fi
657fi
658
659if [[ "${CONFIG[REDUCE]}" = "y" ]]; then
660	if ! echo -e '#include <libpmem.h>\nint main(void) { return 0; }\n' \
661		| ${BUILD_CMD[@]} -lpmem - 2>/dev/null; then
662		echo --with-reduce requires libpmem.
663		echo Please install then re-run this script.
664		exit 1
665	fi
666fi
667
668if [[ "${CONFIG[VPP]}" = "y" ]]; then
669	if [ ! -z "${CONFIG[VPP_DIR]}" ]; then
670		VPP_CFLAGS="-L${CONFIG[VPP_DIR]}/lib -I${CONFIG[VPP_DIR]}/include"
671	fi
672	if ! echo -e '#include <vnet/session/application_interface.h>\nint main(void) { return 0; }\n' \
673		| ${BUILD_CMD[@]} ${VPP_CFLAGS} -lvppinfra -lsvm -lvlibmemoryclient - 2>/dev/null; then
674		echo --with-vpp requires installed vpp.
675		echo Please install then re-run this script.
676		exit 1
677	fi
678fi
679
680if [[ "${CONFIG[NVME_CUSE]}" = "y" ]]; then
681	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' \
682		| ${BUILD_CMD[@]} -lfuse3 -D_FILE_OFFSET_BITS=64 - 2>/dev/null; then
683		echo --with-cuse requires libfuse3.
684		echo Please install then re-run this script.
685		exit 1
686	fi
687fi
688
689if [[ "${CONFIG[RBD]}" = "y" ]]; then
690	if ! echo -e '#include <rbd/librbd.h>\n#include <rados/librados.h>\n' \
691		'int main(void) { return 0; }\n' \
692		| ${BUILD_CMD[@]} -lrados -lrbd - 2>/dev/null; then
693		echo --with-rbd requires librados and librbd.
694		echo Please install then re-run this script.
695		exit 1
696	fi
697fi
698
699if [[ "${CONFIG[ISCSI_INITIATOR]}" = "y" ]]; then
700	# Fedora installs libiscsi to /usr/lib64/iscsi for some reason.
701	if ! echo -e '#include <iscsi/iscsi.h>\n#include <iscsi/scsi-lowlevel.h>\n' \
702		'#if LIBISCSI_API_VERSION < 20150621\n' \
703		'#error\n' \
704		'#endif\n' \
705		'int main(void) { return 0; }\n' \
706		| ${BUILD_CMD[@]} -L/usr/lib64/iscsi -liscsi - 2>/dev/null; then
707		echo --with-iscsi-initiator requires libiscsi with
708		echo 'LIBISCSI_API_VERSION >= 20150621.'
709		echo Please install then re-run this script.
710		exit 1
711	fi
712fi
713
714if [[ "${CONFIG[LOG_BACKTRACE]}" = "y" ]]; then
715	if ! echo -e '#include <libunwind.h>\nint main(void) { return 0; }\n' \
716		| ${BUILD_CMD[@]} -lunwind - 2>/dev/null; then
717		echo --enable-log-bt requires libunwind.
718		echo Please install then re-run this script.
719		exit 1
720	fi
721fi
722
723if [[ "${CONFIG[ASAN]}" = "y" ]]; then
724	if ! echo -e 'int main(void) { return 0; }\n' \
725		| ${BUILD_CMD[@]} -fsanitize=address - 2>/dev/null; then
726		echo --enable-asan requires libasan.
727		echo Please install then re-run this script.
728		exit 1
729	fi
730fi
731
732if [[ "${CONFIG[UBSAN]}" = "y" ]]; then
733	if ! echo -e 'int main(void) { return 0; }\n' \
734		| ${BUILD_CMD[@]} -fsanitize=undefined - 2>/dev/null; then
735		echo --enable-ubsan requires libubsan.
736		echo Please install then re-run this script.
737		exit 1
738	fi
739fi
740
741if [[ "${CONFIG[TSAN]}" = "y" ]]; then
742	if ! echo -e 'int main(void) { return 0; }\n' \
743		| ${BUILD_CMD[@]} -fsanitize=thread - 2>/dev/null; then
744		echo --enable-tsan requires libtsan.
745		echo Please install then re-run this script.
746		exit 1
747	fi
748fi
749
750if [[ "${CONFIG[OCF]}" = "y" ]]; then
751	# If OCF_PATH is a file, assume it is a library and use it to compile with
752	if [ -f ${CONFIG[OCF_PATH]} ]; then
753		CONFIG[CUSTOMOCF]=y
754	else
755		CONFIG[CUSTOMOCF]=n
756	fi
757fi
758
759if [[ "${CONFIG[PGO_CAPTURE]}" = "y" && "${CONFIG[PGO_USE]}" = "y" ]]; then
760	echo "ERROR: --enable-pgo-capture and --enable-pgo-use are mutually exclusive."
761	exit 1
762elif [[ "${CONFIG[PGO_USE]}" = "y" ]]; then
763	if [[ "$CC_TYPE" = "clang" ]]; then
764		# For clang we need to run an extra step on gathered profiling data.
765		echo "Generating suitable profile data"
766		llvm-profdata merge -output=build/pgo/default.profdata build/pgo
767	fi
768fi
769
770if [[ "${CONFIG[URING]}" = "y" ]]; then
771	if [[ -n "${CONFIG[URING_PATH]}" ]]; then
772		if [ ! -d "${CONFIG[URING_PATH]}" ]; then
773			echo "${CONFIG[URING_PATH]}: directory not found"
774			exit 1
775		fi
776	fi
777fi
778
779if [[ "${CONFIG[FUSE]}" = "y" ]]; then
780	if [[ ! -d /usr/include/fuse3 ]] && [[ ! -d /usr/local/include/fuse3 ]]; then
781		echo "--with-fuse requires libfuse3."
782		echo "Please install then re-run this script."
783		exit 1
784	fi
785fi
786
787# We are now ready to generate final configuration. But first do sanity
788# check to see if all keys in CONFIG array have its reflection in CONFIG file.
789if [ $(egrep -c "^\s*CONFIG_[[:alnum:]_]+=" $rootdir/CONFIG) -ne ${#CONFIG[@]} ]; then
790	echo ""
791	echo "BUG: Some configuration options are not present in CONFIG file. Please update this file."
792	echo "Missing options in CONFIG (+) file and in current config (-): "
793	diff -u --label "CONFIG file" --label "CONFIG[@]" \
794		<(sed -r -e '/^\s*$/d; /^\s*#.*/d; s/(CONFIG_[[:alnum:]_]+)=.*/\1/g' CONFIG | sort) \
795		<(printf "CONFIG_%s\n" ${!CONFIG[@]} | sort)
796	exit 1
797fi
798
799echo -n "Creating mk/config.mk..."
800cp -f $rootdir/CONFIG $rootdir/mk/config.mk
801for key in ${!CONFIG[@]}; do
802	sed -i.bak -r "s#^\s*CONFIG_${key}=.*#CONFIG_${key}\?=${CONFIG[$key]}#g" $rootdir/mk/config.mk
803done
804# On FreeBSD sed -i 'SUFFIX' - SUFFIX is mandatory. So no way but to delete the backed file.
805rm -f $rootdir/mk/config.mk.bak
806echo "done."
807
808# Environment variables
809echo -n "Creating mk/cc.flags.mk..."
810rm -f $rootdir/mk/cc.flags.mk
811[ -n "$CFLAGS" ] && echo "CFLAGS?=$CFLAGS" > $rootdir/mk/cc.flags.mk
812[ -n "$CXXFLAGS" ] && echo "CXXFLAGS?=$CXXFLAGS" >> $rootdir/mk/cc.flags.mk
813[ -n "$LDFLAGS" ] && echo "LDFLAGS?=$LDFLAGS" >> $rootdir/mk/cc.flags.mk
814[ -n "$DESTDIR" ] && echo "DESTDIR?=$DESTDIR" >> $rootdir/mk/cc.flags.mk
815echo "done."
816
817# Create .sh with build config for easy sourcing|lookup during the tests.
818for conf in "${!CONFIG[@]}"; do
819	echo "CONFIG_$conf=${CONFIG[$conf]}"
820done >"$rootdir/test/common/build_config.sh"
821
822if [[ $sys_name == "FreeBSD" ]]; then
823	echo "Type 'gmake' to build."
824else
825	echo "Type 'make' to build."
826fi
827
828exit 0
829