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