Dear Recipient,bug#45756 that you reported has been fixed. A patch is attacked for your convenience. Thank you for contributing.
I have decided to follow the advice in the discussion thread and gate this functionality behind an explicit ./configure flag. I believe that this is the cleanest way to introduce it without breaking unrelated things. Please let me know if this is the solution that oyu had in mind. Thanks.
-------- Forwarded Message --------Subject: [automake-commit] 02/02: build: add opt-in compiler jobserver support (bug#45756)
Date: Mon, 19 Oct 2026 07:39:44 -0400 From: Kamila Szewczyk <[email protected]> Reply-To: [email protected] To: [email protected] iczelia pushed a commit to branch master in repository automake. View the commit online: https://git.savannah.gnu.org/gitweb/?p=automake.git;a=commitdiff;h=88ef2eb74d39fcab1065f231f3446fa2d420278d commit 88ef2eb74d39fcab1065f231f3446fa2d420278d Author: Kamila Szewczyk <[email protected]> AuthorDate: Mon Oct 19 13:39:28 2026 +0200 build: add opt-in compiler jobserver support (bug#45756)* m4/jobserver.m4 (_AM_JOBSERVER): Add --enable-jobserver and define AM_JOBSERVER. Require GNU make when enabled.
* m4/init.m4 (AM_INIT_AUTOMAKE): Require _AM_JOBSERVER.
* m4/local.mk: Distribute the new macro.
* bin/automake.in (handle_languages): Prefix object compilation
recipes, accounting for depcomp continuation lines.
* lib/am/program.am: Prefix program link commands.
* lib/am/ltlibrary.am: Prefix Libtool library link commands.
* t/jobserver.sh: Test descriptor inheritance, dependency tracking,
Libtool, silent rules, and non-executing make modes.
* t/list-of-tests.mk: Register it.
* doc/automake.texi (Linking): Document the option.
* NEWS: Mention the feature.
---
NEWS | 5 ++
bin/automake.in | 11 +++++
doc/automake.texi | 22 +++++++++
lib/am/ltlibrary.am | 2 +-
lib/am/program.am | 2 +-
m4/init.m4 | 1 +
m4/jobserver.m4 | 29 ++++++++++++
m4/local.mk | 1 +
t/jobserver.sh | 129
++++++++++++++++++++++++++++++++++++++++++++++++++++
t/list-of-tests.mk | 1 +
10 files changed, 201 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 2a7cb9c97..094b08e79 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@ New in 1.20 (????-??-??):
* New features added
+ - New configure option --enable-jobserver lets compilers and linkers
+ inherit GNU make's pipe jobserver, for example for GCC's
+ -flto=jobserver. Dry-run, question, and touch modes still do not
+ run these commands. (bug#45756)
+
- New option delete-on-error. It emits the .DELETE_ON_ERROR special
target in the generated Makefile.in, instructing make to delete
the target when its recipe fails after having modified it. A failed
diff --git a/bin/automake.in b/bin/automake.in
index 5dc901f47..8ae981a30 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1393,6 +1393,17 @@ sub handle_languages ()
? $verbose : verbose_nodep_flag ($lang->ccer || 'GEN');
my $silent = silent_flag ();
+ if ($rule_file eq 'depend2')
+ {
+ $verbose = '$(AM_JOBSERVER)' . $verbose;
+ # With depcomp, the compiler continues a recipe whose first
+ # line already has the prefix; do not insert another '+'.
+ $verbose_nodep = ($AMDEP eq 'FALSE') ? $verbose
+ : '$(AM_JOBSERVER' . subst ('am__nodep') . ')'
+ . $verbose_nodep;
+ define_variable ('AM_JOBSERVER_no', '', INTERNAL);
+ }
+
my %transform = ('EXT' => $ext,
'PFX' => $pfx,
'FPFX' => $fpfx,
diff --git a/doc/automake.texi b/doc/automake.texi
index 4036f6f5c..072d76409 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -5088,6 +5088,28 @@ third-party libraries. If you follow this rule,
the default value of
omit the other ones.
+@cindex Jobserver, compiler and linker access
+@opindex --enable-jobserver
+@opindex --disable-jobserver
+@vindex AM_JOBSERVER
+To let compilers and linkers share GNU make's parallel job limit, users
+can configure a package with @option{--enable-jobserver}, then build it
+with @samp{make -j@var{N}}. This is useful, for example, with GCC's
+@option{-flto=jobserver}. The option requires GNU make and is disabled
+by default; @option{--disable-jobserver} explicitly disables it.
+
+When enabled, Automake prefixes object compilation and program and
+Libtool library linking recipes with @samp{+}, allowing them to inherit
+the file descriptors of a pipe-based jobserver. The prefix is omitted
+when @command{make} is run with @option{-n}, @option{-q}, or @option{-t},
+so these modes do not execute the compiler or linker. This also works
+with silent rules and dependency tracking. It does not enable link-time
+optimization itself, nor does it change user-written recipes.
+
+The recipe prefix is supplied by @code{AM_JOBSERVER}. After configuring
+with this option, use the same GNU make implementation for the build;
+set @code{MAKE} when running @command{configure} if necessary.
+
@node Conditional Sources
@subsection Conditional compilation of sources
diff --git a/lib/am/ltlibrary.am b/lib/am/ltlibrary.am
index b67db5c26..33846d6b5 100644
--- a/lib/am/ltlibrary.am
+++ b/lib/am/ltlibrary.am
@@ -15,4 +15,4 @@
## along with this program. If not, see <https://www.gnu.org/licenses/>.
%LTLIBRARY%: $(%XLTLIBRARY%_OBJECTS) $(%XLTLIBRARY%_DEPENDENCIES)
$(EXTRA_%XLTLIBRARY%_DEPENDENCIES) %DIRSTAMP%
- %VERBOSE%$(%XLINK%) %RPATH% $(%XLTLIBRARY%_OBJECTS)
$(%XLTLIBRARY%_LIBADD) $(LIBS)
+ $(AM_JOBSERVER)%VERBOSE%$(%XLINK%) %RPATH% $(%XLTLIBRARY%_OBJECTS)
$(%XLTLIBRARY%_LIBADD) $(LIBS)
diff --git a/lib/am/program.am b/lib/am/program.am
index b05795303..1254cc680 100644
--- a/lib/am/program.am
+++ b/lib/am/program.am
@@ -21,4 +21,4 @@
## Or maybe not... sadly, incremental linkers are rarer than losing
## systems.
@rm -f %PROGRAM%%EXEEXT%
- %VERBOSE%$(%XLINK%) $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_LDADD) $(LIBS)
+ $(AM_JOBSERVER)%VERBOSE%$(%XLINK%) $(%XPROGRAM%_OBJECTS)
$(%XPROGRAM%_LDADD) $(LIBS)
diff --git a/m4/init.m4 b/m4/init.m4 index 61e911811..afd43b70a 100644 --- a/m4/init.m4 +++ b/m4/init.m4 @@ -136,6 +136,7 @@ fi AC_SUBST([CSCOPE]) AC_REQUIRE([_AM_SILENT_RULES])dnl +AC_REQUIRE([_AM_JOBSERVER])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. diff --git a/m4/jobserver.m4 b/m4/jobserver.m4 new file mode 100644 index 000000000..582301657 --- /dev/null +++ b/m4/jobserver.m4 @@ -0,0 +1,29 @@ +# Enable compiler access to GNU make's jobserver. -*- Autoconf -*- +# Copyright (C) 2026 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_JOBSERVER +# ------------- +AC_DEFUN([_AM_JOBSERVER], +[AC_ARG_ENABLE([jobserver], + [AS_HELP_STRING([--enable-jobserver], + [let compilers and linkers use the GNU make jobserver])], + [], [enable_jobserver=no]) +AM_JOBSERVER= +AS_CASE([$enable_jobserver], + [yes], [+ AS_IF([${MAKE-make} --version 2>/dev/null | grep 'GNU Make' >/dev/null],
+ [], [AC_MSG_ERROR([--enable-jobserver requires GNU make])]) + dnl MAKEFLAGS begins with the single-letter flags, without a dash. + dnl Prefix a dash so firstword does not pick up a later option or + dnl variable assignment when there are no single-letter flags. + dnl Do not mark commands recursive under -n, -q, or -t.+ AM_JOBSERVER='$(if $(findstring n,$(firstword -$(MAKEFLAGS)))$(findstring q,$(firstword -$(MAKEFLAGS)))$(findstring t,$(firstword -$(MAKEFLAGS))),,+)'
+ ], + [no], [], + [AC_MSG_ERROR([bad value '$enable_jobserver' for --enable-jobserver])]) +AC_SUBST([AM_JOBSERVER]) +]) diff --git a/m4/local.mk b/m4/local.mk index 6b76fd2b9..60327d00d 100644 --- a/m4/local.mk +++ b/m4/local.mk @@ -35,6 +35,7 @@ dist_automake_ac_DATA = \ %D%/gcj.m4 \ %D%/init.m4 \ %D%/install-sh.m4 \ + %D%/jobserver.m4 \ %D%/lead-dot.m4 \ %D%/lex.m4 \ %D%/lispdir.m4 \ diff --git a/t/jobserver.sh b/t/jobserver.sh new file mode 100644 index 000000000..1c29fb02d --- /dev/null +++ b/t/jobserver.sh @@ -0,0 +1,129 @@ +#! /bin/sh +# Copyright (C) 2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# Compilers and linkers can inherit the pipe jobserver without running +# under make -n, -q, or -t (bug#45756). + +required='cc GNUmake libtoolize' +. test-init.sh + +cat >> configure.ac <<'END' +AC_PROG_CC +AM_PROG_AR +LT_INIT +AC_OUTPUT +END + +cat > Makefile.am <<'END' +bin_PROGRAMS = foo bar +foo_SOURCES = foo.c +bar_SOURCES = foo.c +bar_CFLAGS = $(AM_CFLAGS) +noinst_LTLIBRARIES = libfoo.la +libfoo_la_SOURCES = foo.c +libfoo_la_CFLAGS = $(AM_CFLAGS) +END + +echo 'int main (void) { return 0; }' > foo.c + +# Check the descriptors themselves, independently of compiler LTO support. +cat > check-jobserver.c <<'END' +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +int main (void) +{ + const char *flags = getenv ("MAKEFLAGS"); + const char *p; + int r, w; + if (!flags) return 1; + p = strstr (flags, "--jobserver-auth="); + if (!p) p = strstr (flags, "--jobserver-fds="); + if (!p || sscanf (strchr (p, '=') + 1, "%d,%d", &r, &w) != 2) + return 1; + return fcntl (r, F_GETFD) < 0 || fcntl (w, F_GETFD) < 0; +} +END +$CC -o check-jobserver check-jobserver.c + +cat > cc-wrapper <<'END' +#!/bin/sh +./check-jobserver || exit 99 +echo invoked >> compiler.log +exec "$@" +END + +cat > lt-wrapper <<'END' +#!/bin/sh +./check-jobserver || exit 99 +echo invoked >> libtool.log +exec "$@" +END + +libtoolize +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +# GNU make 4.4 defaults to a FIFO, which does not need inherited fds. +# Force the pipe jobserver there; older versions already use pipes. +run_make -O -- --help +jobserver_style= +if grep 'jobserver-style' stdout; then + jobserver_style=--jobserver-style=pipe +fi + +for deps in none fast slow; do + case $deps in + none) ./configure --enable-jobserver --disable-dependency-tracking;; + fast) ./configure --enable-jobserver --enable-dependency-tracking;; + slow) ./configure --enable-jobserver --enable-dependency-tracking \ + am_cv_CC_dependencies_compiler_type=gcc;; + esac + for verbosity in 0 1; do + rm -f compiler.log libtool.log+ run_make -M -j2 $jobserver_style V=$verbosity CC="$SHELL ./cc-wrapper $CC" \
+ LIBTOOL="$SHELL ./lt-wrapper $SHELL ./libtool" + test $(wc -l < compiler.log) -ge 5 + test $(wc -l < libtool.log) -eq 4 + run_make clean + + for mode in -n -q -t -kn -kq -kt; do + rm -f compiler.log libtool.log + run_make -M -e IGNORE -j2 $jobserver_style $mode V=$verbosity \ + CC="$SHELL ./cc-wrapper $CC" \ + LIBTOOL="$SHELL ./lt-wrapper $SHELL ./libtool" + case $mode in + *q) test "$am_make_rc" -eq 1;; + *) test "$am_make_rc" -eq 0;; + esac + test ! -e libtool.log + test ! -e compiler.log + run_make clean + done + done +done + +for option in '' --disable-jobserver; do + ./configure $option + # Default configuration leaves compiler recipes non-recursive. + run_make -M -e FAIL -j2 $jobserver_style CC="$SHELL ./cc-wrapper $CC" +done + +./configure --enable-jobserver=invalid && exit 1 + +: diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk index 243818342..05775fc1a 100644 --- a/t/list-of-tests.mk +++ b/t/list-of-tests.mk @@ -603,6 +603,7 @@ t/javadir-undefined.sh \ t/javaflags.sh \ t/javaprim.sh \ t/javasubst.sh \ +t/jobserver.sh \ t/ldadd.sh \ t/ldflags.sh \ t/lex-args.sh \
OpenPGP_0xC868F0B6DE38409D.asc
Description: OpenPGP public key
OpenPGP_signature.asc
Description: OpenPGP digital signature
