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