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="$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 --nolibc) liburing_nolibc="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 --nolibc build liburing without libc 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 <[email protected]> 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 -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 compiler -Wstringop-overflow 207stringop_overflow="no" 208cat > $TMPC << EOF 209#include <linux/fs.h> 210int main(int argc, char **argv) 211{ 212 return 0; 213} 214EOF 215if compile_prog "-Werror -Wstringop-overflow=0" "" "stringop_overflow"; then 216 stringop_overflow="yes" 217fi 218print_config "stringop_overflow" "$stringop_overflow" 219 220########################################## 221# check for compiler -Warryr-bounds 222array_bounds="no" 223cat > $TMPC << EOF 224#include <linux/fs.h> 225int main(int argc, char **argv) 226{ 227 return 0; 228} 229EOF 230if compile_prog "-Werror -Warray-bounds=0" "" "array_bounds"; then 231 array_bounds="yes" 232fi 233print_config "array_bounds" "$array_bounds" 234 235 236########################################## 237# check for __kernel_rwf_t 238__kernel_rwf_t="no" 239cat > $TMPC << EOF 240#include <linux/fs.h> 241int main(int argc, char **argv) 242{ 243 __kernel_rwf_t x; 244 x = 0; 245 return x; 246} 247EOF 248if compile_prog "" "" "__kernel_rwf_t"; then 249 __kernel_rwf_t="yes" 250fi 251print_config "__kernel_rwf_t" "$__kernel_rwf_t" 252 253########################################## 254# check for __kernel_timespec 255__kernel_timespec="no" 256cat > $TMPC << EOF 257#include <linux/time.h> 258#include <linux/time_types.h> 259int main(int argc, char **argv) 260{ 261 struct __kernel_timespec ts; 262 ts.tv_sec = 0; 263 ts.tv_nsec = 1; 264 return 0; 265} 266EOF 267if compile_prog "" "" "__kernel_timespec"; then 268 __kernel_timespec="yes" 269fi 270print_config "__kernel_timespec" "$__kernel_timespec" 271 272########################################## 273# check for open_how 274open_how="no" 275cat > $TMPC << EOF 276#include <sys/types.h> 277#include <fcntl.h> 278#include <string.h> 279#include <linux/openat2.h> 280int main(int argc, char **argv) 281{ 282 struct open_how how; 283 how.flags = 0; 284 how.mode = 0; 285 how.resolve = 0; 286 return 0; 287} 288EOF 289if compile_prog "" "" "open_how"; then 290 open_how="yes" 291fi 292print_config "open_how" "$open_how" 293 294########################################## 295# check for statx 296statx="no" 297cat > $TMPC << EOF 298#include <sys/types.h> 299#include <sys/stat.h> 300#include <unistd.h> 301#include <fcntl.h> 302#include <string.h> 303int main(int argc, char **argv) 304{ 305 struct statx x; 306 307 return memset(&x, 0, sizeof(x)) != NULL; 308} 309EOF 310if compile_prog "" "" "statx"; then 311 statx="yes" 312fi 313print_config "statx" "$statx" 314 315########################################## 316# check for glibc statx 317glibc_statx="no" 318cat > $TMPC << EOF 319#include <sys/types.h> 320#include <unistd.h> 321#include <fcntl.h> 322#include <string.h> 323#include <sys/stat.h> 324int main(int argc, char **argv) 325{ 326 struct statx x; 327 328 return memset(&x, 0, sizeof(x)) != NULL; 329} 330EOF 331if compile_prog "" "" "glibc_statx"; then 332 glibc_statx="yes" 333fi 334print_config "glibc_statx" "$glibc_statx" 335 336########################################## 337# check for C++ 338has_cxx="no" 339cat > $TMPCXX << EOF 340#include <iostream> 341int main(int argc, char **argv) 342{ 343 std::cout << "Test"; 344 return 0; 345} 346EOF 347if compile_prog_cxx "" "" "C++"; then 348 has_cxx="yes" 349fi 350print_config "C++" "$has_cxx" 351 352########################################## 353# check for ucontext support 354has_ucontext="no" 355cat > $TMPC << EOF 356#include <ucontext.h> 357int main(int argc, char **argv) 358{ 359 ucontext_t ctx; 360 getcontext(&ctx); 361 makecontext(&ctx, 0, 0); 362 return 0; 363} 364EOF 365if compile_prog "" "" "has_ucontext"; then 366 has_ucontext="yes" 367fi 368print_config "has_ucontext" "$has_ucontext" 369 370########################################## 371# check for memfd_create(2) 372has_memfd_create="no" 373cat > $TMPC << EOF 374#include <sys/mman.h> 375int main(int argc, char **argv) 376{ 377 int memfd = memfd_create("test", 0); 378 return 0; 379} 380EOF 381if compile_prog "-Werror=implicit-function-declaration" "" "has_memfd_create"; then 382 has_memfd_create="yes" 383fi 384print_config "has_memfd_create" "$has_memfd_create" 385 386 387############################################################################# 388if test "$liburing_nolibc" = "yes"; then 389 output_sym "CONFIG_NOLIBC" 390else 391 liburing_nolibc="no" 392fi 393print_config "liburing_nolibc" "$liburing_nolibc" 394 395if test "$__kernel_rwf_t" = "yes"; then 396 output_sym "CONFIG_HAVE_KERNEL_RWF_T" 397fi 398if test "$__kernel_timespec" = "yes"; then 399 output_sym "CONFIG_HAVE_KERNEL_TIMESPEC" 400fi 401if test "$open_how" = "yes"; then 402 output_sym "CONFIG_HAVE_OPEN_HOW" 403fi 404if test "$statx" = "yes"; then 405 output_sym "CONFIG_HAVE_STATX" 406fi 407if test "$glibc_statx" = "yes"; then 408 output_sym "CONFIG_HAVE_GLIBC_STATX" 409fi 410if test "$has_cxx" = "yes"; then 411 output_sym "CONFIG_HAVE_CXX" 412fi 413if test "$has_ucontext" = "yes"; then 414 output_sym "CONFIG_HAVE_UCONTEXT" 415fi 416if test "$stringop_overflow" = "yes"; then 417 output_sym "CONFIG_HAVE_STRINGOP_OVERFLOW" 418fi 419if test "$array_bounds" = "yes"; then 420 output_sym "CONFIG_HAVE_ARRAY_BOUNDS" 421fi 422if test "$has_memfd_create" = "yes"; then 423 output_sym "CONFIG_HAVE_MEMFD_CREATE" 424fi 425 426echo "CC=$cc" >> $config_host_mak 427print_config "CC" "$cc" 428echo "CXX=$cxx" >> $config_host_mak 429print_config "CXX" "$cxx" 430 431# generate compat.h 432compat_h="src/include/liburing/compat.h" 433cat > $compat_h << EOF 434/* SPDX-License-Identifier: MIT */ 435#ifndef LIBURING_COMPAT_H 436#define LIBURING_COMPAT_H 437 438EOF 439 440if test "$__kernel_rwf_t" != "yes"; then 441cat >> $compat_h << EOF 442typedef int __kernel_rwf_t; 443 444EOF 445fi 446if test "$__kernel_timespec" != "yes"; then 447cat >> $compat_h << EOF 448#include <stdint.h> 449 450struct __kernel_timespec { 451 int64_t tv_sec; 452 long long tv_nsec; 453}; 454 455EOF 456else 457cat >> $compat_h << EOF 458#include <linux/time_types.h> 459 460EOF 461fi 462if test "$open_how" != "yes"; then 463cat >> $compat_h << EOF 464#include <inttypes.h> 465 466struct open_how { 467 uint64_t flags; 468 uint64_t mode; 469 uint64_t resolve; 470}; 471 472EOF 473else cat >> $compat_h << EOF 474#include <linux/openat2.h> 475 476EOF 477fi 478if [ "$glibc_statx" = "no" ] && [ "$statx" = "yes" ]; then 479cat >> $compat_h << EOF 480#include <sys/stat.h> 481 482EOF 483fi 484 485cat >> $compat_h << EOF 486#endif 487EOF 488