• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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