Parallel./ configure

0
9


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 (makeso 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.

Source

LEAVE A REPLY

Please enter your comment!
Please enter your name here