Tavian Barnes
GitHub
I’m sorry, however in the year 2025, this is outrageous:
$ time ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether sleep supports fractional seconds... yes
checking filesystem timestamp resolution... 0.01
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking xargs -n works... yes
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for leaf optimisation... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether gcc accepts -g... yes
checking for gcc option to enable C11 features... none needed
checking whether gcc understands -c and -o together... yes
checking whether the compiler is clang... no
checking for compiler option needed when checking for declarations... none
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for wchar.h... yes
checking for minix/config.h... no
checking for stdbool.h... yes
checking for byteswap.h... yes
checking for uchar.h... yes
checking for sys/param.h... yes
checking for sys/socket.h... yes
checking for dirent.h... yes
checking for endian.h... yes
checking for sys/endian.h... no
checking for error.h... yes
checking for fnmatch.h... yes
checking for stdio_ext.h... yes
checking for sys/vfs.h... yes
checking for netdb.h... yes
checking for getopt.h... yes
checking for sys/time.h... yes
checking for threads.h... yes
checking for limits.h... yes
checking for crtdefs.h... no
checking for wctype.h... yes
checking for langinfo.h... yes
checking for xlocale.h... no
checking for math.h... yes
checking for sys/mman.h... yes
checking for sys/statvfs.h... yes
checking for pthread.h... yes
checking for malloc.h... yes
checking for selinux/selinux.h... no
checking for stdckdint.h... yes
checking for sys/uio.h... yes
checking for sys/utsname.h... yes
checking for sys/wait.h... yes
checking for features.h... yes
checking for arpa/inet.h... yes
checking for netinet/in.h... yes
checking for semaphore.h... yes
checking for priv.h... no
checking for sys/select.h... yes
checking for sys/ioctl.h... yes
checking for sys/random.h... yes
checking for sys/un.h... yes
checking whether it is safe to define __EXTENSIONS__... yes
checking whether _XOPEN_SOURCE should be defined... no
checking for egrep -e... (cached) /usr/bin/grep -E
checking for Minix Amsterdam compiler... no
checking for ar... ar
checking for ranlib... ranlib
checking for gcc option to support large files... none needed
checking for gcc option to support timestamps after 2038... none needed
checking whether ln -s works... yes
checking whether make sets $(MAKE)... (cached) yes
checking for gcc option to support large files... (cached) none needed
checking for gcc option to support timestamps after 2038... (cached) none needed
checking for lstat... yes
checking for btowc... yes
checking for mbrtowc... yes
checking for mbsinit... yes
checking for canonicalize_file_name... yes
checking for realpath... yes
checking for _set_invalid_parameter_handler... no
checking for fchdir... yes
checking for fdopendir... yes
checking for fcntl... yes
checking for symlink... yes
checking for fnmatch... yes
checking for mbsrtowcs... yes
checking for fpurge... no
checking for fstatat... yes
checking for openat... yes
checking for fstatfs... yes
checking for getdtablesize... yes
checking for getexecname... no
checking for gettimeofday... yes
checking for isblank... yes
checking for iswcntrl... yes
checking for mbslen... no
checking for isascii... yes
checking for mprotect... yes
checking for strftime_z... no
checking for __xpg_strerror_r... yes
checking for pipe... yes
checking for qsort_r... yes
checking for readlink... yes
checking for iswctype... yes
checking for setenv... yes
checking for snprintf... yes
checking for strndup... yes
checking for strtoumax... yes
checking for localtime_r... yes
checking for unlinkat... yes
checking for vasnprintf... no
checking for wcrtomb... yes
checking for wcwidth... yes
checking for geteuid... yes
checking for pselect... yes
checking for pthread_sigmask... yes
checking for secure_getenv... yes
checking for getuid... yes
checking for getgid... yes
checking for getegid... yes
checking for sleep... yes
checking for shutdown... yes
checking for usleep... yes
checking for wctob... yes
checking for vprintf... yes
checking for size_t... yes
checking for working alloca.h... yes
checking for alloca... yes
checking whether the preprocessor supports include_next... yes
checking whether source code line length is unlimited... yes
checking for wint_t... yes
checking whether wint_t is large enough... yes
checking whether
uses 'inline' correctly... yes
checking for nl_langinfo and CODESET... yes
checking for a traditional french locale... none
checking whether char8_t is correctly defined... yes
checking whether char16_t is correctly defined... yes
checking whether char32_t is correctly defined... yes
checking for bit size of wchar_t... 32
checking for mbstate_t... yes
checking for a traditional japanese locale... none
checking for an english Unicode locale... en_US.UTF-8
checking for a transitional chinese locale... none
checking whether mbrtowc handles incomplete characters... yes
checking whether mbrtowc works as well as mbtowc... guessing yes
checking for gcc options needed to detect all undeclared functions... none needed
checking whether mbrtoc32 is declared... yes
checking for mbrtoc32... yes
checking whether mbrtoc32 works as well as mbrtowc... guessing yes
checking whether c32rtomb is declared... yes
checking for c32rtomb... yes
checking whether c32rtomb works as well as wcrtomb... guessing yes
checking whether malloc is ptrdiff_t safe... yes
checking whether malloc, realloc, calloc set errno on failure... yes
checking whether lstat correctly handles trailing slash... yes
checking whether // is distinct from /... no
checking whether realpath works... yes
checking for C/C++ restrict keyword... __restrict__
checking whether byte ordering is bigendian... no
checking if endian.h defines stdint types... no
checking if endian.h defines functions and macros... yes
checking if environ is properly declared... yes
checking for complete errno.h... yes
checking for error... yes
checking whether error_at_line is declared... yes
checking for error_at_line... yes
checking for working error function... yes
checking whether strerror_r is declared... yes
checking whether strerror_r returns char *... yes
checking for uid_t... yes
checking for gid_t... yes
checking type of array argument to getgroups... gid_t
checking whether ctype.h defines __header_inline... no
checking whether fchdir is declared... yes
checking for working fcntl.h... yes
checking for pid_t... yes
checking for mode_t... yes
checking for promoted mode_t type... mode_t
checking whether strmode is declared... no
checking whether fopen recognizes a trailing slash... yes
checking whether fflush works on input streams... no
checking whether stdin defaults to large file offsets... yes
checking for off64_t... yes
checking whether fseeko is declared... yes
checking for fseeko... yes
checking whether fflush works on input streams... (cached) no
checking whether stat file-mode macros are broken... no
checking for nlink_t... yes
checking whether ftello is declared... yes
checking whether ungetc works on arbitrary bytes... yes
checking for ftello... yes
checking whether ftello works... yes
checking for O_CLOEXEC... yes
checking whether getcwd (NULL, 0) allocates memory for result... yes
checking for getcwd with POSIX signature... yes
checking whether getcwd is declared... yes
checking whether alarm is declared... yes
checking whether getdelim is declared... yes
checking whether getdtablesize is declared... yes
checking whether getline is declared... yes
checking for getopt.h... (cached) yes
checking for getopt_long_only... yes
checking whether getopt is POSIX compatible... yes
checking for working GNU getopt function... yes
checking for working GNU getopt_long function... yes
checking for glibc-compatible sys/cdefs.h... yes
checking whether timespec_get is declared... yes
checking for timespec_get... yes
checking for struct timeval... yes
checking for wide-enough struct timeval.tv_sec member... yes
checking for pthread.h... (cached) yes
checking for pthread_kill in -lpthread... yes
checking whether POSIX threads API is available... yes
checking whether setlocale (LC_ALL, NULL) is multithread-safe... yes
checking whether setlocale (category, NULL) is multithread-safe... yes
checking for inline... inline
checking whether limits.h has WORD_BIT, BOOL_WIDTH etc.... yes
checking whether limits.h has SSIZE_MAX... yes
checking whether the compiler produces multi-arch binaries... no
checking whether stdint.h conforms to C99... yes
checking whether stdint.h works without ISO C predefines... yes
checking whether stdint.h has UINTMAX_WIDTH etc.... yes
checking whether INT32_MAX < INTMAX_MAX... yes
checking whether INT64_MAX == LONG_MAX... yes
checking whether UINT32_MAX < UINTMAX_MAX... yes
checking whether UINT64_MAX == ULONG_MAX... yes
checking where to find the exponent in a 'long double'... word 2 bit 0
checking whether long double and double are the same... no
checking where to find the exponent in a 'double'... word 1 bit 20
checking where to find the exponent in a 'float'... word 0 bit 23
checking whether iswcntrl works... yes
checking for towlower... yes
checking for wctype_t... yes
checking for wctrans_t... yes
checking whether wctype supports the "blank" and "punct" character classes... yes
checking whether langinfo.h defines CODESET... yes
checking whether langinfo.h defines T_FMT_AMPM... yes
checking whether langinfo.h defines ALTMON_1... yes
checking whether langinfo.h defines ERA... yes
checking whether langinfo.h defines YESEXPR... yes
checking for good max_align_t... yes
checking whether NULL can be used in arbitrary expressions... yes
checking for unreachable... no
checking whether nullptr_t needs ... no
checking for clean definition of __STDC_VERSION_STDDEF_H__... yes
checking whether locale.h defines locale_t... yes
checking whether locale.h conforms to POSIX:2001... yes
checking whether struct lconv is properly defined... yes
checking for LC_MESSAGES... yes
checking for uselocale... yes
checking whether uselocale works... yes
checking for fake locale system (OpenBSD)... no
checking for Solaris 11.4 locale system... no
checking for getlocalename_l... no
checking whether imported symbols can be declared weak... yes
checking for multithread API to use... posix
checking for a sed that does not truncate output... /usr/bin/sed
checking whether malloc (0) returns nonnull... yes
checking whether NAN macro works... yes
checking whether HUGE_VAL works... yes
checking for mmap... yes
checking for MAP_ANONYMOUS... yes
checking whether memchr works... yes
checking whether memrchr is declared... yes
checking whether defines MIN and MAX... no
checking whether defines MIN and MAX... yes
checking whether time_t is signed... yes
checking for working mktime... yes
checking whether trunc is declared... yes
checking for struct tm.tm_gmtoff... yes
checking for struct tm.tm_zone... yes
checking for compound literals... yes
checking whether strerror(0) succeeds... yes
checking for strerror_r... yes
checking for strerror_r with POSIX signature... no
checking whether __xpg_strerror_r works... yes
checking for pthread_t... yes
checking for pthread_spinlock_t... yes
checking for pthread_spin_init... yes
checking whether realloc should abort upon undefined behaviour... no
checking for ssize_t... yes
checking for sched.h... yes
checking for struct sched_param... yes
checking for library containing setfilecon... no
checking whether setenv is declared... yes
checking whether _putenv is declared... no
checking for search.h... yes
checking for tsearch... yes
checking whether snprintf returns a byte count as in C99... yes
checking whether printf supports POSIX/XSI format strings with positions... yes
checking whether snprintf is declared... yes
checking for library containing setsockopt... none needed
checking whether fcloseall is declared... yes
checking whether getw is declared... yes
checking whether putw is declared... yes
checking which flavor of printf attribute matches inttypes macros... system
checking whether ecvt is declared... yes
checking whether fcvt is declared... yes
checking whether gcvt is declared... yes
checking whether MB_CUR_MAX is correct... yes
checking for strcasestr... yes
checking whether strcasestr works... yes
checking whether strdup is declared... yes
checking whether strndup is declared... yes
checking whether strnlen is declared... yes
checking whether strstr works... yes
checking whether strtoumax is declared... yes
checking whether is self-contained... yes
checking for shutdown... (cached) yes
checking whether defines the SHUT_* macros... yes
checking for struct sockaddr_storage... yes
checking for sa_family_t... yes
checking for struct sockaddr_storage.ss_family... yes
checking for struct utsname... yes
checking for struct timespec in ./configure 13.80s user 12.72s system 69% cpu 38.018 total
$ time make -j48
make all-recursive
make[1]: Entering directory '/home/tavianator/code/gnu/findutils'
Making all in gl
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/gl'
Making all in lib
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/gl/lib'
GEN alloca.h
GEN ctype.h
GEN endian.h
GEN dirent.h
GEN fcntl.h
GEN error.h
GEN float.h
GEN malloc/dynarray-skeleton.gl.h
GEN malloc/scratch_buffer.gl.h
GEN malloc/dynarray.gl.h
GEN inttypes.h
GEN langinfo.h
GEN limits.h
GEN locale.h
GEN math.h
GEN pthread.h
GEN sched.h
GEN selinux/selinux.h
GEN selinux/context.h
GEN selinux/label.h
GEN stddef.h
GEN stdio.h
GEN stdlib.h
GEN string.h
GEN strings.h
GEN sys/socket.h
GEN sys/stat.h
GEN sys/time.h
GEN sys/types.h
GEN sys/uio.h
GEN sys/utsname.h
GEN sys/wait.h
GEN time.h
GEN uchar.h
GEN unicase.h
GEN unictype.h
GEN uninorm.h
GEN unistd.h
GEN unistr.h
GEN unitypes.h
GEN uniwidth.h
GEN wchar.h
GEN wctype.h
make all-recursive
make[4]: Entering directory '/home/tavianator/code/gnu/findutils/gl/lib'
make[5]: Entering directory '/home/tavianator/code/gnu/findutils/gl/lib'
CC libgnulib_a-allocator.o
CC libgnulib_a-areadlinkat.o
CC libgnulib_a-areadlink.o
CC libgnulib_a-argmatch.o
CC libgnulib_a-argv-iter.o
CC libgnulib_a-basename-lgpl.o
CC libgnulib_a-openat-proc.o
CC libgnulib_a-bitrotate.o
CC libgnulib_a-btoc32.o
CC libgnulib_a-btowc.o
CC libgnulib_a-c-ctype.o
CC libgnulib_a-c-strcasecmp.o
CC libgnulib_a-c-strncasecmp.o
CC libgnulib_a-c-strcasestr.o
CC libgnulib_a-c-strstr.o
CC libgnulib_a-c32_apply_type_test.o
CC libgnulib_a-c32_get_type_test.o
CC libgnulib_a-c32isalnum.o
CC libgnulib_a-c32isalpha.o
CC libgnulib_a-c32isblank.o
CC libgnulib_a-c32iscntrl.o
CC libgnulib_a-c32isdigit.o
CC libgnulib_a-c32isgraph.o
CC libgnulib_a-c32islower.o
CC libgnulib_a-c32isprint.o
CC libgnulib_a-c32ispunct.o
CC libgnulib_a-c32isspace.o
CC libgnulib_a-c32isupper.o
CC libgnulib_a-c32isxdigit.o
CC libgnulib_a-c32tolower.o
CC libgnulib_a-c32width.o
CC libgnulib_a-canonicalize.o
CC libgnulib_a-careadlinkat.o
CC libgnulib_a-chdir-long.o
CC libgnulib_a-cloexec.o
CC libgnulib_a-close-stream.o
CC libgnulib_a-closein.o
CC libgnulib_a-closeout.o
CC libgnulib_a-cycle-check.o
CC libgnulib_a-opendir-safer.o
CC libgnulib_a-dirname.o
CC libgnulib_a-basename.o
CC libgnulib_a-dirname-lgpl.o
CC libgnulib_a-stripslash.o
CC libgnulib_a-endian.o
CC libgnulib_a-exitfail.o
CC libgnulib_a-fcntl.o
CC libgnulib_a-creat-safer.o
CC libgnulib_a-open-safer.o
CC libgnulib_a-fd-hook.o
CC libgnulib_a-fflush.o
CC libgnulib_a-file-set.o
CC libgnulib_a-filemode.o
CC libgnulib_a-filenamecat-lgpl.o
CC libgnulib_a-float.o
CC libgnulib_a-fopen-safer.o
CC libgnulib_a-fpurge.o
CC libgnulib_a-freadahead.o
CC libgnulib_a-freading.o
CC libgnulib_a-fseek.o
CC libgnulib_a-fseeko.o
CC libgnulib_a-fts.o
CC libgnulib_a-getprogname.o
CC libgnulib_a-gettime.o
CC malloc/libgnulib_a-dynarray_at_failure.o
CC malloc/libgnulib_a-dynarray_emplace_enlarge.o
CC malloc/libgnulib_a-dynarray_finalize.o
CC malloc/libgnulib_a-dynarray_resize.o
CC malloc/libgnulib_a-dynarray_resize_clear.o
CC malloc/libgnulib_a-scratch_buffer_grow.o
CC malloc/libgnulib_a-scratch_buffer_grow_preserve.o
CC malloc/libgnulib_a-scratch_buffer_set_array_size.o
CC libgnulib_a-hard-locale.o
CC libgnulib_a-hash.o
CC libgnulib_a-hash-pjw.o
CC libgnulib_a-hash-triple-simple.o
CC libgnulib_a-human.o
CC libgnulib_a-i-ring.o
CC libgnulib_a-ialloc.o
CC libgnulib_a-idcache.o
CC libgnulib_a-localcharset.o
CC glthread/libgnulib_a-lock.o
CC libgnulib_a-malloca.o
CC libgnulib_a-math.o
CC libgnulib_a-mbchar.o
CC libgnulib_a-mbrtoc32.o
CC libgnulib_a-mbrtowc.o
CC libgnulib_a-mbscasestr.o
CC libgnulib_a-mbslen.o
CC libgnulib_a-mbsrtoc32s.o
CC libgnulib_a-mbsrtowcs.o
CC libgnulib_a-mbsstr.o
CC libgnulib_a-mbswidth.o
CC libgnulib_a-mbszero.o
CC libgnulib_a-mbuiter.o
CC libgnulib_a-mbuiterf.o
CC libgnulib_a-modechange.o
CC libgnulib_a-mountlist.o
CC libgnulib_a-nstrftime.o
CC glthread/libgnulib_a-once.o
CC libgnulib_a-openat-die.o
CC libgnulib_a-openat-safer.o
CC libgnulib_a-opendirat.o
CC libgnulib_a-parse-datetime.o
CC libgnulib_a-progname.o
CC libgnulib_a-quotearg.o
CC libgnulib_a-realloc.o
CC libgnulib_a-reallocarray.o
CC libgnulib_a-safe-read.o
CC libgnulib_a-same-inode.o
CC libgnulib_a-save-cwd.o
CC libgnulib_a-savedir.o
CC libgnulib_a-selinux-at.o
CC libgnulib_a-se-context.o
CC libgnulib_a-se-label.o
CC libgnulib_a-se-selinux.o
CC libgnulib_a-setlocale_null.o
CC libgnulib_a-setlocale_null-unlocked.o
CC libgnulib_a-sockets.o
CC libgnulib_a-stat-time.o
CC libgnulib_a-stdlib.o
CC libgnulib_a-strnlen1.o
CC libgnulib_a-sys_socket.o
CC glthread/libgnulib_a-threadlib.o
CC libgnulib_a-time_rz.o
CC libgnulib_a-timespec.o
CC unicase/libgnulib_a-tolower.o
CC unictype/libgnulib_a-ctype_alnum.o
CC unictype/libgnulib_a-ctype_alpha.o
CC unictype/libgnulib_a-ctype_blank.o
CC unictype/libgnulib_a-ctype_cntrl.o
CC unictype/libgnulib_a-ctype_digit.o
CC unictype/libgnulib_a-ctype_graph.o
CC unictype/libgnulib_a-ctype_lower.o
CC unictype/libgnulib_a-ctype_print.o
CC unictype/libgnulib_a-ctype_punct.o
CC unictype/libgnulib_a-ctype_space.o
CC unictype/libgnulib_a-ctype_upper.o
CC unictype/libgnulib_a-ctype_xdigit.o
CC libgnulib_a-unistd.o
CC libgnulib_a-dup-safer.o
CC libgnulib_a-fd-safer.o
CC libgnulib_a-pipe-safer.o
CC unistr/libgnulib_a-u32-chr.o
CC unistr/libgnulib_a-u32-cpy.o
CC unistr/libgnulib_a-u32-pcpy.o
CC unistr/libgnulib_a-u32-strcat.o
CC unistr/libgnulib_a-u32-strlen.o
CC uniwidth/libgnulib_a-width.o
CC libgnulib_a-version-etc.o
CC libgnulib_a-version-etc-fsf.o
CC libgnulib_a-wctype-h.o
CC libgnulib_a-vsnzprintf.o
CC libgnulib_a-xmalloc.o
CC libgnulib_a-xalloc-die.o
CC libgnulib_a-xgetcwd.o
CC libgnulib_a-xsize.o
CC libgnulib_a-xstrtod.o
CC libgnulib_a-xstrtol.o
CC libgnulib_a-xstrtoul.o
CC libgnulib_a-xstrtol-error.o
CC libgnulib_a-xstrtoumax.o
CC libgnulib_a-yesno.o
CC fopen.o
CC asnprintf.o
CC mbsrtoc32s-state.o
CC mbsrtowcs-state.o
CC mktime.o
CC printf-args.o
CC printf-parse.o
CC strerror_r.o
CC vasnprintf.o
AR libgnulib.a
make[5]: Leaving directory '/home/tavianator/code/gnu/findutils/gl/lib'
make[4]: Leaving directory '/home/tavianator/code/gnu/findutils/gl/lib'
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/gl/lib'
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/gl'
make[3]: Nothing to be done for 'all-am'.
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/gl'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/gl'
Making all in build-aux
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/build-aux'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/build-aux'
Making all in lib
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/lib'
CC buildcmd.o
CC dircallback.o
CC extendbuf.o
CC fdleak.o
CC listfile.o
CC findutils-version.o
CC printquoted.o
CC qmark.o
CC safe-atoi.o
CC splitstring.o
CC regextype.o
CC bugreports.o
AR libfind.a
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/lib'
Making all in find
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/find'
Making all in .
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/find'
CC ftsfind.o
CC finddata.o
CC fstype.o
CC parser.o
CC pred.o
CC exec.o
CC tree.o
CC util.o
CC sharefile.o
CC print.o
CC getlimits.o
AR libfindtools.a
CCLD find
CCLD getlimits
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/find'
Making all in testsuite
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/find/testsuite'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/find/testsuite'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/find'
Making all in xargs
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/xargs'
Making all in .
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/xargs'
CC xargs.o
CCLD xargs
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/xargs'
Making all in testsuite
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/xargs/testsuite'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/xargs/testsuite'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/xargs'
Making all in locate
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/locate'
echo '@set LOCATE_DB /usr/local/var/locatedb' > dblocation.texi.tmp
if test -f dblocation.texi && cmp dblocation.texi.tmp dblocation.texi >/dev/null ; then
rm dblocation.texi.tmp ;
else
mv dblocation.texi.tmp dblocation.texi ;
fi
make all-recursive
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/locate'
Making all in .
make[4]: Entering directory '/home/tavianator/code/gnu/findutils/locate'
rm -f updatedb
CC locate.o
CC frcode.o
find=`echo find|sed 's,x,x,'`;
frcode=`echo frcode|sed 's,x,x,'`;
copyright=`sed -n '/^# Copyright /{s/^..//;p;q;}' ./updatedb.sh
grep .` || exit 1;
sed
-e "s,@""bindir""@,/usr/local/bin,"
-e "s,@""libexecdir""@,/usr/local/libexec,"
-e "s,@""LOCATE_DB""@,/usr/local/var/locatedb,"
-e "s,@""VERSION""@,4.10.0.51-1ef8-dirty,"
-e "s,@""PACKAGE_NAME""@,GNU findutils,"
-e "s,@""PACKAGE_BUGREPORT""@,bug-findutils@gnu.org,"
-e "s,@""PACKAGE_BUGREPORT_URL""@,https://savannah.gnu.org/bugs/?group=findutils,"
-e "s,@""PACKAGE_URL""@,https://www.gnu.org/software/findutils/,"
-e "s,@""find""@,${find},"
-e "s,@""frcode""@,${frcode},"
-e "s,@""SORT""@,/usr/bin/sort,"
-e "s,@""SORT_SUPPORTS_Z""@,true,"
-e "s/@""COPYRIGHT""@/${copyright}/"
./updatedb.sh > updatedb
CC word_io.o
chmod +x updatedb
CCLD frcode
CCLD locate
make[4]: Leaving directory '/home/tavianator/code/gnu/findutils/locate'
Making all in testsuite
make[4]: Entering directory '/home/tavianator/code/gnu/findutils/locate/testsuite'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/home/tavianator/code/gnu/findutils/locate/testsuite'
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/locate'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/locate'
Making all in doc
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/doc'
ln -s ../locate/dblocation.texi dblocation.texi
make all-am
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/doc'
make[3]: Nothing to be done for 'all-am'.
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/doc'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/doc'
Making all in po
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/po'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/po'
Making all in m4
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/m4'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/m4'
Making all in gnulib-tests
make[2]: Entering directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
GEN arpa/inet.h
GEN sys/ioctl.h
GEN signal.h
## ---------------------------------------------------- ##
GEN sys/select.h
GEN sys/random.h
## ------------------- Gnulib tests ------------------- ##
## You can ignore compiler warnings in this directory. ##
## ---------------------------------------------------- ##
make all-recursive
make[3]: Entering directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
Making all in .
make[4]: Entering directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
CC locale.o
CC arpa_inet.o
CC c32tob.o
CC binary-io.o
CC concat-filename.o
CC dtotimespec.o
CC fd-safer-flag.o
CC imaxtostr.o
CC dup-safer-flag.o
CC inttostr.o
CC offtostr.o
CC umaxtostr.o
CC uinttostr.o
CC ioctl.o
CC localename.o
CC localename-unsafe.o
CC localename-table.o
CC nanosleep.o
CC priv-set.o
CC pthread-rwlock.o
CC tempname.o
CC glthread/thread.o
CC time.o
CC timespec-add.o
CC timespec-sub.o
CC tmpdir.o
CC unistr/u32-set.o
CC unlinkdir.o
CC xconcat-filename.o
CC test-localcharset.o
AR libtests.a
CCLD current-locale
CCLD test-localcharset
make[4]: Leaving directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
make[3]: Leaving directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils/gnulib-tests'
make[2]: Entering directory '/home/tavianator/code/gnu/findutils'
make[2]: Leaving directory '/home/tavianator/code/gnu/findutils'
make[1]: Leaving directory '/home/tavianator/code/gnu/findutils'
make -j48 12.05s user 4.70s system 593% cpu 2.822 total
I paid great cash for my 24 CPU cores, however ./configure
can just handle to utilize 69% of among them. As an outcome, this random task takes about 13.5 × longer to set up the develop than it does to in fact do the construct.
The function of a ./configure
script is generally to run the compiler a lot of times and check which runs been successful. In this method it can evaluate whether specific headers, functions, struct fields, and so on exist, which lets individuals compose portable software application. This is an embarrassingly parallel issue, however Autoconf can’t parallelize itand neither can CMake neither can Mesonand so on, and so on.
The issue is that many develop setups scripts basically appear like this:
CFLAGS="-g"
if $CC $CFLAGS -Wall empty.c; then
CFLAGS="$CFLAGS -Wall"
fi
...
: >config.h
if $CC $CFLAGS have_statx.c; then
echo "#define HAVE_STATX 1" >>config.h
else
echo "#define HAVE_STATX 0" >>config.h
fi
...
This is composed in a naturally consecutive method, however in concept a lot of these tests might be run in parallel. We currently have an efficient tool for parallelizing lots of commands (make
so let’s utilize it. We’ll have a setup makefile that creates our Makefile
and config.h
:
configure.mk
# The default goal generates both outputs, and merges the logs together
config: Makefile config.h
cat Makefile.log config.h.log >$@.log
rm Makefile.log config.h.log
To begin with, we’ll conserve the preliminary worths of variables like CC
and CFLAGS
into the Makefile
:
configure.mk
# Default values, if unspecified
CC ?= cc
CPPFLAGS ?= -D_GNU_SOURCE
CFLAGS ?= -g
LDFLAGS ?=
# Export these through the environment to avoid stripping backslashes
export _CC=${CC}
export _CPPFLAGS=${CPPFLAGS}
export _CFLAGS=${CFLAGS}
export _LDFLAGS=${LDFLAGS}
Makefile:
printf 'CC := %sn' "$$_CC" >$@
printf 'CPPFLAGS := %sn' "$$_CPPFLAGS" >>$@
printf 'CFLAGS := %sn' "$$_CFLAGS" >>$@
printf 'LDFLAGS := %sn' "$$_LDFLAGS" >>$@
Utilizing export
like this prevents removing the required backslashes from invocations like
$ ./configure CPPFLAGS='-DMACRO="string"'
Now let’s examine which flags our compiler supports. We’ll utilize this assistant script:
flags.sh
#!/bin/sh
set -eu
VAR="$1"
FLAGS="$2"
shift 2
if "$@" $FLAGS; then
printf '%s += %sn' "$VAR" "$FLAGS"
fi
When we run
$ ./flags.sh CFLAGS -Wall cc empty.c
it will print
CFLAGS += -Wall
if cc empty.c -Wall
is successful (and absolutely nothing otherwise). We can utilize this to create some makefile pieces that allow just the supported flags.
configure.mk
ALL_FLAGS = ${CPPFLAGS} ${CFLAGS} ${LDFLAGS}
# Run the compiler with the given flags, sending
#
# - stdout to foo.mk (e.g. CFLAGS += -flag)
# - stderr to foo.mk.log (e.g. error: unrecognized command-line option ‘-flag’)
# - the compiled binary to foo.mk.out
# - but then we delete it immediately
TRY_CC = ${CC} ${ALL_FLAGS} empty.c -o $@.out >$@ 2>$@.log && rm -f $@.out $@.d
deps.mk:
./flags.sh CPPFLAGS "-MP -MD" ${TRY_CC}
Wall.mk:
./flags.sh CFLAGS -Wall ${TRY_CC}
pthread.mk:
./flags.sh CFLAGS -pthread ${TRY_CC}
bind-now.mk:
./flags.sh LDFLAGS -Wl,-z,now ${TRY_CC}
Each of these targets creates a small makefile piece that’s accountable for a single flag. Notably, every one can run individually, in parallel. Once they’re done, we can combine them all into the primary Makefile
and tidy up the cruft:
configure.mk
FLAGS :=
deps.mk
Wall.mk
pthread.mk
bind-now.mk
Makefile: ${FLAGS}
printf 'CC := %sn' "$$_CC" >$@
...
cat ${FLAGS} >>$@
cat ${FLAGS:%=%.log} >$@.log
rm ${FLAGS} ${FLAGS:%=%.log}
The tail end to contribute to the Makefile
is the part that in fact develops our application. We can compose a basic makefile like this:
main.mk
OBJS := main.o
app: ${OBJS}
${CC} ${CFLAGS} ${LDFLAGS} ${OBJS} -o $@
${OBJS}:
${CC} ${CPPFLAGS} ${CFLAGS} -c ${@:.o=.c} -o $@
-include ${OBJS:.o=.d}
And add it to the Makefile
The flags:
configure.mk
Makefile: ${FLAGS}
...
cat main.mk >>$@
We likewise wish to create a config.h
file, which specifies macros that inform us whether specific libraries/headers/functions/ struct fields/etc. exist. We can do this by test-compiling some basic C programs. As an example, these programs look for the different methods to discover a file’s production timestamp:
#include
#include
int main(void) {
struct statx stx;
return statx(AT_FDCWD, ".", 0, STATX_BTIME, &stx);
}
#include
int main(void) {
struct stat sb = {0};
return sb.st_birthtim.tv_sec;
}
#include
int main(void) {
struct stat sb = {0};
return sb.st_birthtimespec.tv_sec;
}
#include
int main(void) {
struct stat sb = {0};
return sb.__st_birthtim.tv_sec;
}
This assistant script:
define.sh
#!/bin/sh
set -eu
MACRO=$1
shift
if "$@"; then
printf '#define %s 1n' "$MACRO"
else
printf '#define %s 0n' "$MACRO"
fi
will output things like
#define HAVE_STATX 1
or
#define HAVE_ST_BIRTHTIM 0
depending upon whether the develop prospers. We can utilize it in a makefile like this:
configure.mk
# Use a recursive make to pick up our auto-detected *FLAGS from above
config.h: Makefile
+${MAKE} -f header.mk $@
# Get the final *FLAGS values from the Makefile
include Makefile
# We first generate a lot of small headers, before merging them into one big one
HEADERS :=
have_statx.h
have_st_birthtim.h
have_st_birthtimespec.h
have___st_birthtim.h
# Strip .h and capitalize the macro name
MACRO = $$(printf '%s' ${@:.h=} | tr 'a-z' 'A-Z')
ALL_FLAGS = ${CPPFLAGS} ${CFLAGS} ${LDFLAGS}
${HEADERS}:
./define.sh ${MACRO} ${CC} ${ALL_FLAGS} ${@:.h=.c} -o $@.out >$@ 2>$@.log
rm -f $@.out $@.d
And to join them entirely (in addition to a header guard):
config.h: ${HEADERS}
printf '#ifndef CONFIG_Hn' >$@
printf '#define CONFIG_Hn' >>$@
cat ${HEADERS} >>$@
printf '#endifn' >>$@
cat ${HEADERS:%=%.log} >$@.log
rm ${HEADERS} ${HEADERS:%=%.log}
The last action is to cover configure.mk
in a shell script, so individuals can run ./configure
like they’re utilized to:
configure
#!/bin/sh
set -eu
# Guess a good number for make -j
jobs() {
{
nproc
|| sysctl -n hw.ncpu
|| getconf _NPROCESSORS_ONLN
|| echo 1
} 2>/dev/null
}
# Default to MAKE=make
MAKE="${MAKE-make}"
# Set MAKEFLAGS to -j$(jobs) if it's unset
export MAKEFLAGS="${MAKEFLAGS--j$(jobs)}"
$MAKE -r -f configure.mk "$@"
I create a basic proof-of-concept GitHub repository which contains the complete variation of all these files if you wish to copy-paste. The demonstration app prints submit production times, if it can find out how to on your platform.
I’ve likewise been utilizing a comparable develop system in bfs for a while, if you wish to see a bigger example. The efficiency advantage is considerable:
$ time ./configure
[ GEN] gen/vars.mk
[ CC ] build/empty.c ✔
[ CC ] flags/Wundef-prefix.c ✘
[ CC ] flags/Wshadow.c ✔
[ CC ] flags/Wimplicit.c ✔
[ CC ] flags/Wsign-compare.c ✔
[ CC ] flags/Wmissing-var-decls.c ✔
[ CC ] flags/Wimplicit-fallthrough.c ✔
[ CC ] flags/Wmissing-decls.c ✔
[ CC ] flags/Wformat.c ✔
[ CC ] flags/Wstrict-prototypes.c ✔
[ CC ] flags/deps.c ✔
[ CC ] flags/pthread.c ✔
[ CC ] flags/bind-now.c ✔
[ GEN] gen/flags.mk
[ CC ] with/libacl.c ✔
[ CC ] with/libcap.c ✔
[ CC ] with/oniguruma.c ✔
[ CC ] with/liburing.c ✔
[ CC ] with/libselinux.c ✘
[ GEN] gen/pkgs.mk
[ CC ] has/--st-birthtim.c ✘
[ CC ] has/acl-is-trivial-np.c ✘
[ CC ] has/builtin-riscv-pause.c ✘
[ CC ] has/extattr-get-file.c ✘
[ CC ] has/extattr-get-link.c ✘
[ CC ] has/acl-trivial.c ✘
[ CC ] has/getdents.c ✘
[ CC ] has/extattr-list-file.c ✘
[ CC ] has/fdclosedir.c ✘
[ CC ] has/extattr-list-link.c ✘
[ CC ] has/getmntent-2.c ✘
[ CC ] has/posix-getdents.c ✘
[ CC ] has/getprogname.c ✘
[ CC ] has/getmntinfo.c ✘
[ CC ] has/string-to-flags.c ✘
[ CC ] has/pragma-nounroll.c ✘
[ CC ] has/st-birthtimespec.c ✘
[ CC ] has/st-acmtimespec.c ✘
[ CC ] has/pthread-set-name-np.c ✘
[ CC ] has/st-birthtim.c ✘
[ CC ] has/posix-spawn-addfchdir.c ✘
[ CC ] has/tcgetwinsize.c ✘
[ CC ] has/strerror-r-posix.c ✘
[ CC ] has/st-flags.c ✘
[ CC ] has/strtofflags.c ✘
[ CC ] has/tcsetwinsize.c ✘
[ CC ] has/acl-get-file.c ✔
[ CC ] has/_Fork.c ✔
[ CC ] has/confstr.c ✔
[ CC ] has/dprintf.c ✔
[ CC ] has/acl-get-entry.c ✔
[ CC ] has/acl-get-tag-type.c ✔
[ CC ] has/getdents64.c ✔
[ CC ] has/getprogname-gnu.c ✔
[ CC ] has/getdents64-syscall.c ✔
[ CC ] has/getmntent-1.c ✔
[ CC ] has/pipe2.c ✔
[ CC ] has/st-acmtim.c ✔
[ CC ] has/sched-getaffinity.c ✔
[ CC ] has/strerror-r-gnu.c ✔
[ CC ] has/posix-spawn-addfchdir-np.c ✔
[ CC ] has/pthread-setname-np.c ✔
[ CC ] has/strerror-l.c ✔
[ CC ] has/timegm.c ✔
[ CC ] has/timer-create.c ✔
[ CC ] has/statx-syscall.c ✔
[ CC ] has/statx.c ✔
[ CC ] has/tm-gmtoff.c ✔
[ CC ] has/uselocale.c ✔
[ CC ] has/io-uring-max-workers.c ✔
[ GEN] gen/config.h
[ GEN] gen/config.mk
./configure 1.44s user 1.78s system 802% cpu 0.401 total
tavianator@tachyon $ time make -j48
[ CC ] src/main.c
[ CC ] src/xspawn.c
[ CC ] src/xtime.c
[ CC ] src/xregex.c
[ CC ] src/bar.c
[ CC ] src/bfstd.c
[ CC ] src/bftw.c
[ CC ] src/alloc.c
[ CC ] src/color.c
[ CC ] src/ctx.c
[ CC ] src/diag.c
[ CC ] src/dir.c
[ CC ] src/dstring.c
[ CC ] src/eval.c
[ CC ] src/exec.c
[ CC ] src/ioq.c
[ CC ] src/fsade.c
[ CC ] src/expr.c
[ CC ] src/mtab.c
[ CC ] src/opt.c
[ CC ] src/parse.c
[ CC ] src/printf.c
[ CC ] src/pwcache.c
[ CC ] src/sighook.c
[ CC ] src/thread.c
[ CC ] src/stat.c
[ CC ] src/trie.c
[ CC ] src/typo.c
[ CC ] src/version.c
[ LD ] bin/bfs
make -j48 1.89s user 0.64s system 817% cpu 0.310 total
Obviously, a great deal of the advantage originates from simply doing less setup actions, however the 802% CPU usage is a remarkable enhancement over whatever else I’ve attempted.