1#!/bin/sh 2 3set -e 4 5cc=${CC:-gcc} 6cxx=${CXX:-g++} 7 8for opt do 9 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)' || true) 10 case "$opt" in 11 --help|-h) show_help=yes 12 ;; 13 --prefix=*) prefix="$(realpath -s $optarg)" 14 ;; 15 --includedir=*) includedir="$optarg" 16 ;; 17 --libdir=*) libdir="$optarg" 18 ;; 19 --libdevdir=*) libdevdir="$optarg" 20 ;; 21 --mandir=*) mandir="$optarg" 22 ;; 23 --datadir=*) datadir="$optarg" 24 ;; 25 --cc=*) cc="$optarg" 26 ;; 27 --cxx=*) cxx="$optarg" 28 ;; 29 --use-libc) use_libc=yes 30 ;; 31 --enable-sanitizer) use_sanitizer=yes 32 ;; 33 *) 34 echo "ERROR: unknown option $opt" 35 echo "Try '$0 --help' for more information" 36 exit 1 37 ;; 38 esac 39done 40 41if test -z "$prefix"; then 42 prefix=/usr 43fi 44if test -z "$includedir"; then 45 includedir="$prefix/include" 46fi 47if test -z "$libdir"; then 48 libdir="$prefix/lib" 49fi 50if test -z "$libdevdir"; then 51 libdevdir="$prefix/lib" 52fi 53if test -z "$mandir"; then 54 mandir="$prefix/man" 55fi 56if test -z "$datadir"; then 57 datadir="$prefix/share" 58fi 59 60if test x"$libdir" = x"$libdevdir"; then 61 relativelibdir="" 62else 63 relativelibdir="$libdir/" 64fi 65 66if test "$show_help" = "yes"; then 67cat <<EOF 68 69Usage: configure [options] 70Options: [defaults in brackets after descriptions] 71 --help print this message 72 --prefix=PATH install in PATH [$prefix] 73 --includedir=PATH install headers in PATH [$includedir] 74 --libdir=PATH install runtime libraries in PATH [$libdir] 75 --libdevdir=PATH install development libraries in PATH [$libdevdir] 76 --mandir=PATH install man pages in PATH [$mandir] 77 --datadir=PATH install shared data in PATH [$datadir] 78 --cc=CMD use CMD as the C compiler 79 --cxx=CMD use CMD as the C++ compiler 80 --use-libc use libc for liburing (useful for hardening) 81 --enable-sanitizer compile liburing with the address and undefined behaviour sanitizers. (useful for debugging) 82EOF 83exit 0 84fi 85 86TMP_DIRECTORY="$(mktemp -d)" 87TMPC="$TMP_DIRECTORY/liburing-conf.c" 88TMPC2="$TMP_DIRECTORY/liburing-conf-2.c" 89TMPCXX="$TMP_DIRECTORY/liburing-conf-2.cpp" 90TMPO="$TMP_DIRECTORY/liburing-conf.o" 91TMPE="$TMP_DIRECTORY/liburing-conf.exe" 92 93touch $TMPC $TMPC2 $TMPCXX $TMPO $TMPE 94 95# NB: do not call "exit" in the trap handler; this is buggy with some shells; 96# see <1285349658-3122-1-git-send-email-loic.minier@linaro.org> 97trap "rm -rf $TMP_DIRECTORY" EXIT INT QUIT TERM 98 99rm -rf config.log 100 101config_host_mak="config-host.mak" 102config_host_h="config-host.h" 103 104rm -rf $config_host_mak 105rm -rf $config_host_h 106 107fatal() { 108 echo $@ 109 echo "Configure failed, check config.log and/or the above output" 110 rm -rf $config_host_mak 111 rm -rf $config_host_h 112 exit 1 113} 114 115# Print result for each configuration test 116print_config() { 117 printf "%-30s%s\n" "$1" "$2" 118} 119 120# Default CFLAGS 121CFLAGS="-D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -include config-host.h" 122BUILD_CFLAGS="" 123 124# Print configure header at the top of $config_host_h 125echo "/*" > $config_host_h 126echo " * Automatically generated by configure - do not modify" >> $config_host_h 127printf " * Configured with:" >> $config_host_h 128printf " * '%s'" "$0" "$@" >> $config_host_h 129echo "" >> $config_host_h 130echo " */" >> $config_host_h 131 132echo "# Automatically generated by configure - do not modify" > $config_host_mak 133printf "# Configured with:" >> $config_host_mak 134printf " '%s'" "$0" "$@" >> $config_host_mak 135echo >> $config_host_mak 136 137do_cxx() { 138 # Run the compiler, capturing its output to the log. 139 echo $cxx "$@" >> config.log 140 $cxx "$@" >> config.log 2>&1 || return $? 141 return 0 142} 143 144do_cc() { 145 # Run the compiler, capturing its output to the log. 146 echo $cc "$@" >> config.log 147 $cc "$@" >> config.log 2>&1 || return $? 148 # Test passed. If this is an --enable-werror build, rerun 149 # the test with -Werror and bail out if it fails. This 150 # makes warning-generating-errors in configure test code 151 # obvious to developers. 152 if test "$werror" != "yes"; then 153 return 0 154 fi 155 # Don't bother rerunning the compile if we were already using -Werror 156 case "$*" in 157 *-Werror*) 158 return 0 159 ;; 160 esac 161 echo $cc -Werror "$@" >> config.log 162 $cc -Werror "$@" >> config.log 2>&1 && return $? 163 echo "ERROR: configure test passed without -Werror but failed with -Werror." 164 echo "This is probably a bug in the configure script. The failing command" 165 echo "will be at the bottom of config.log." 166 fatal "You can run configure with --disable-werror to bypass this check." 167} 168 169compile_prog() { 170 local_cflags="$1" 171 local_ldflags="$2 $LIBS" 172 echo "Compiling test case $3" >> config.log 173 do_cc $CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags 174} 175 176compile_prog_cxx() { 177 local_cflags="$1" 178 local_ldflags="$2 $LIBS" 179 echo "Compiling test case $3" >> config.log 180 do_cxx $CFLAGS $local_cflags -o $TMPE $TMPCXX $LDFLAGS $local_ldflags 181} 182 183has() { 184 type "$1" >/dev/null 2>&1 185} 186 187output_mak() { 188 echo "$1=$2" >> $config_host_mak 189} 190 191output_sym() { 192 output_mak "$1" "y" 193 echo "#define $1" >> $config_host_h 194} 195 196print_and_output_mak() { 197 print_config "$1" "$2" 198 output_mak "$1" "$2" 199} 200print_and_output_mak "prefix" "$prefix" 201print_and_output_mak "includedir" "$includedir" 202print_and_output_mak "libdir" "$libdir" 203print_and_output_mak "libdevdir" "$libdevdir" 204print_and_output_mak "relativelibdir" "$relativelibdir" 205print_and_output_mak "mandir" "$mandir" 206print_and_output_mak "datadir" "$datadir" 207 208#################################################### 209# Check for correct compiler runtime library to link with 210libgcc_link_flag="-lgcc" 211if $cc -print-libgcc-file-name >/dev/null 2>&1; then 212 libgcc_link_flag="$($cc $CFLAGS $LDFLAGS -print-libgcc-file-name)" 213fi 214print_and_output_mak "libgcc_link_flag" "$libgcc_link_flag" 215#################################################### 216 217########################################## 218# check for compiler -Wstringop-overflow 219stringop_overflow="no" 220cat > $TMPC << EOF 221#include <linux/fs.h> 222int main(int argc, char **argv) 223{ 224 return 0; 225} 226EOF 227if compile_prog "-Werror -Wstringop-overflow=0" "" "stringop_overflow"; then 228 stringop_overflow="yes" 229fi 230print_config "stringop_overflow" "$stringop_overflow" 231 232########################################## 233# check for compiler -Warryr-bounds 234array_bounds="no" 235cat > $TMPC << EOF 236#include <linux/fs.h> 237int main(int argc, char **argv) 238{ 239 return 0; 240} 241EOF 242if compile_prog "-Werror -Warray-bounds=0" "" "array_bounds"; then 243 array_bounds="yes" 244fi 245print_config "array_bounds" "$array_bounds" 246 247 248########################################## 249# check for __kernel_rwf_t 250__kernel_rwf_t="no" 251cat > $TMPC << EOF 252#include <linux/fs.h> 253int main(int argc, char **argv) 254{ 255 __kernel_rwf_t x; 256 x = 0; 257 return x; 258} 259EOF 260if compile_prog "" "" "__kernel_rwf_t"; then 261 __kernel_rwf_t="yes" 262fi 263print_config "__kernel_rwf_t" "$__kernel_rwf_t" 264 265########################################## 266# check for __kernel_timespec 267__kernel_timespec="no" 268cat > $TMPC << EOF 269#include <linux/time.h> 270#include <linux/time_types.h> 271int main(int argc, char **argv) 272{ 273 struct __kernel_timespec ts; 274 ts.tv_sec = 0; 275 ts.tv_nsec = 1; 276 return 0; 277} 278EOF 279if compile_prog "" "" "__kernel_timespec"; then 280 __kernel_timespec="yes" 281fi 282print_config "__kernel_timespec" "$__kernel_timespec" 283 284########################################## 285# check for open_how 286open_how="no" 287cat > $TMPC << EOF 288#include <sys/types.h> 289#include <fcntl.h> 290#include <string.h> 291#include <linux/openat2.h> 292int main(int argc, char **argv) 293{ 294 struct open_how how; 295 how.flags = 0; 296 how.mode = 0; 297 how.resolve = 0; 298 return 0; 299} 300EOF 301if compile_prog "" "" "open_how"; then 302 open_how="yes" 303fi 304print_config "open_how" "$open_how" 305 306########################################## 307# check for statx 308statx="no" 309cat > $TMPC << EOF 310#include <sys/types.h> 311#include <sys/stat.h> 312#include <unistd.h> 313#include <fcntl.h> 314#include <string.h> 315int main(int argc, char **argv) 316{ 317 struct statx x; 318 319 return memset(&x, 0, sizeof(x)) != NULL; 320} 321EOF 322if compile_prog "" "" "statx"; then 323 statx="yes" 324fi 325print_config "statx" "$statx" 326 327########################################## 328# check for glibc statx 329glibc_statx="no" 330cat > $TMPC << EOF 331#include <sys/types.h> 332#include <unistd.h> 333#include <fcntl.h> 334#include <string.h> 335#include <sys/stat.h> 336int main(int argc, char **argv) 337{ 338 struct statx x; 339 340 return memset(&x, 0, sizeof(x)) != NULL; 341} 342EOF 343if compile_prog "" "" "glibc_statx"; then 344 glibc_statx="yes" 345fi 346print_config "glibc_statx" "$glibc_statx" 347 348########################################## 349# check for C++ 350has_cxx="no" 351cat > $TMPCXX << EOF 352#include <iostream> 353int main(int argc, char **argv) 354{ 355 std::cout << "Test"; 356 return 0; 357} 358EOF 359if compile_prog_cxx "" "" "C++"; then 360 has_cxx="yes" 361fi 362print_config "C++" "$has_cxx" 363 364########################################## 365# check for ucontext support 366has_ucontext="no" 367cat > $TMPC << EOF 368#include <ucontext.h> 369int main(int argc, char **argv) 370{ 371 ucontext_t ctx; 372 getcontext(&ctx); 373 makecontext(&ctx, 0, 0); 374 return 0; 375} 376EOF 377if compile_prog "" "" "has_ucontext"; then 378 has_ucontext="yes" 379fi 380print_config "has_ucontext" "$has_ucontext" 381 382########################################## 383# Check NVME_URING_CMD support 384nvme_uring_cmd="no" 385cat > $TMPC << EOF 386#include <linux/nvme_ioctl.h> 387int main(void) 388{ 389 struct nvme_uring_cmd *cmd; 390 391 return sizeof(struct nvme_uring_cmd); 392} 393EOF 394if compile_prog "" "" "nvme uring cmd"; then 395 nvme_uring_cmd="yes" 396fi 397print_config "NVMe uring command support" "$nvme_uring_cmd" 398 399########################################## 400# Check futexv support 401futexv="no" 402cat > $TMPC << EOF 403#include <linux/futex.h> 404#include <unistd.h> 405#include <string.h> 406int main(void) 407{ 408 struct futex_waitv fw; 409 410 memset(&fw, FUTEX_32, sizeof(fw)); 411 412 return sizeof(struct futex_waitv); 413} 414EOF 415if compile_prog "" "" "futexv"; then 416 futexv="yes" 417fi 418print_config "futex waitv support" "$futexv" 419 420########################################## 421# Check block discard cmd support 422discard_cmd="no" 423cat > $TMPC << EOF 424#include <linux/blkdev.h> 425int main(void) 426{ 427 return BLOCK_URING_CMD_DISCARD; 428} 429EOF 430if compile_prog "" "" "discard command"; then 431 discard_cmd="yes" 432fi 433print_config "io_uring discard command support" "$discard_cmd" 434 435########################################## 436# Check idtype_t support 437has_idtype_t="no" 438cat > $TMPC << EOF 439#include <sys/wait.h> 440int main(void) 441{ 442 idtype_t v; 443 return 0; 444} 445EOF 446if compile_prog "" "" "idtype_t"; then 447 has_idtype_t="yes" 448fi 449print_config "has_idtype_t" "$has_idtype_t" 450 451############################################################################# 452liburing_nolibc="no" 453if test "$use_libc" != "yes"; then 454 455 # 456 # Currently, CONFIG_NOLIBC only supports x86-64, x86 (32-bit), aarch64 and riscv64. 457 # 458 cat > $TMPC << EOF 459int main(void){ 460#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) 461 return 0; 462#else 463#error libc is needed 464#endif 465} 466EOF 467 468 if compile_prog "" "" "nolibc"; then 469 liburing_nolibc="yes" 470 fi 471fi 472 473print_config "nolibc" "$liburing_nolibc"; 474############################################################################# 475 476#################################################### 477# Most Android devices don't have sys/fanotify.h 478has_fanotify="no" 479cat > $TMPC << EOF 480#include <sys/fanotify.h> 481int main(void) 482{ 483 return 0; 484} 485EOF 486if compile_prog "" "" "fanotify"; then 487 has_fanotify="yes" 488fi 489print_config "has_fanotify" "$has_fanotify" 490#################################################### 491 492########################################## 493# check for ublk headers 494ublk_header="no" 495cat > $TMPC << EOF 496#include <string.h> 497#include <sys/ioctl.h> 498#include <linux/ublk_cmd.h> 499int main(int argc, char **argv) 500{ 501 struct ublksrv_ctrl_cmd cmd = { }; 502 503 cmd.addr = UBLK_U_CMD_START_DEV; 504 return cmd.queue_id; 505} 506EOF 507if compile_prog "" "" "ublk_header"; then 508 ublk_header="yes" 509fi 510print_config "ublk_header" "$ublk_header" 511 512if test "$liburing_nolibc" = "yes"; then 513 output_sym "CONFIG_NOLIBC" 514fi 515if test "$__kernel_rwf_t" = "yes"; then 516 output_sym "CONFIG_HAVE_KERNEL_RWF_T" 517fi 518if test "$__kernel_timespec" = "yes"; then 519 output_sym "CONFIG_HAVE_KERNEL_TIMESPEC" 520fi 521if test "$open_how" = "yes"; then 522 output_sym "CONFIG_HAVE_OPEN_HOW" 523fi 524if test "$statx" = "yes"; then 525 output_sym "CONFIG_HAVE_STATX" 526fi 527if test "$glibc_statx" = "yes"; then 528 output_sym "CONFIG_HAVE_GLIBC_STATX" 529fi 530if test "$has_cxx" = "yes"; then 531 output_sym "CONFIG_HAVE_CXX" 532fi 533if test "$has_ucontext" = "yes"; then 534 output_sym "CONFIG_HAVE_UCONTEXT" 535fi 536if test "$stringop_overflow" = "yes"; then 537 output_sym "CONFIG_HAVE_STRINGOP_OVERFLOW" 538fi 539if test "$array_bounds" = "yes"; then 540 output_sym "CONFIG_HAVE_ARRAY_BOUNDS" 541fi 542if test "$nvme_uring_cmd" = "yes"; then 543 output_sym "CONFIG_HAVE_NVME_URING" 544fi 545if test "$has_fanotify" = "yes"; then 546 output_sym "CONFIG_HAVE_FANOTIFY" 547fi 548if test "$futexv" = "yes"; then 549 output_sym "CONFIG_HAVE_FUTEXV" 550fi 551if test "$ublk_header" = "yes"; then 552 output_sym "CONFIG_HAVE_UBLK_HEADER" 553fi 554if test "$use_sanitizer" = "yes"; then 555 output_sym "CONFIG_USE_SANITIZER" 556 print_config "use sanitizer" "yes" 557else 558 print_config "use sanitizer" "no" 559fi 560 561echo "CC=$cc" >> $config_host_mak 562print_config "CC" "$cc" 563echo "CXX=$cxx" >> $config_host_mak 564print_config "CXX" "$cxx" 565 566# generate io_uring_version.h 567# Reset MAKEFLAGS 568MAKEFLAGS= 569MAKE_PRINT_VARS="include Makefile.common\nprint-%%: ; @echo \$(\$*)\n" 570VERSION_MAJOR=$(printf "$MAKE_PRINT_VARS" | make -s --no-print-directory -f - print-VERSION_MAJOR) 571VERSION_MINOR=$(printf "$MAKE_PRINT_VARS" | make -s --no-print-directory -f - print-VERSION_MINOR) 572io_uring_version_h="src/include/liburing/io_uring_version.h" 573cat > $io_uring_version_h << EOF 574/* SPDX-License-Identifier: MIT */ 575#ifndef LIBURING_VERSION_H 576#define LIBURING_VERSION_H 577 578#define IO_URING_VERSION_MAJOR $VERSION_MAJOR 579#define IO_URING_VERSION_MINOR $VERSION_MINOR 580 581#endif 582EOF 583 584# generate compat.h 585compat_h="src/include/liburing/compat.h" 586cat > $compat_h << EOF 587/* SPDX-License-Identifier: MIT */ 588#ifndef LIBURING_COMPAT_H 589#define LIBURING_COMPAT_H 590 591EOF 592 593if test "$__kernel_rwf_t" != "yes"; then 594cat >> $compat_h << EOF 595typedef int __kernel_rwf_t; 596 597EOF 598fi 599if test "$__kernel_timespec" != "yes"; then 600cat >> $compat_h << EOF 601#include <stdint.h> 602 603struct __kernel_timespec { 604 int64_t tv_sec; 605 long long tv_nsec; 606}; 607 608/* <linux/time_types.h> is not available, so it can't be included */ 609#define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 1 610 611EOF 612else 613cat >> $compat_h << EOF 614#include <linux/time_types.h> 615/* <linux/time_types.h> is included above and not needed again */ 616#define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 1 617 618EOF 619fi 620if test "$open_how" != "yes"; then 621cat >> $compat_h << EOF 622#include <inttypes.h> 623 624struct open_how { 625 uint64_t flags; 626 uint64_t mode; 627 uint64_t resolve; 628}; 629 630EOF 631else cat >> $compat_h << EOF 632#include <linux/openat2.h> 633 634EOF 635fi 636if [ "$glibc_statx" = "no" ] && [ "$statx" = "yes" ]; then 637cat >> $compat_h << EOF 638#include <sys/stat.h> 639 640EOF 641fi 642if test "$futexv" != "yes"; then 643cat >> $compat_h << EOF 644#include <inttypes.h> 645 646#define FUTEX_32 2 647#define FUTEX_WAITV_MAX 128 648 649struct futex_waitv { 650 uint64_t val; 651 uint64_t uaddr; 652 uint32_t flags; 653 uint32_t __reserved; 654}; 655 656EOF 657fi 658 659if test "$has_idtype_t" != "yes"; then 660cat >> $compat_h << EOF 661typedef enum 662{ 663 P_ALL, /* Wait for any child. */ 664 P_PID, /* Wait for specified process. */ 665 P_PGID /* Wait for members of process group. */ 666} idtype_t; 667EOF 668fi 669 670if test "$discard_cmd" != "yes"; then 671cat >> $compat_h << EOF 672 673#include <linux/ioctl.h> 674 675#ifndef BLOCK_URING_CMD_DISCARD 676#define BLOCK_URING_CMD_DISCARD _IO(0x12, 0) 677#endif 678 679EOF 680else cat >> $compat_h << EOF 681#include <linux/blkdev.h> 682 683EOF 684fi 685 686cat >> $compat_h << EOF 687#endif 688EOF 689