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