• 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  *)
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