Patchwork Mark linker Makefile rules for job server build

login
register
mail settings
Submitter Andi Kleen
Date Oct. 4, 2010, 1:11 p.m.
Message ID <1286197899-24667-1-git-send-email-andi@firstfloor.org>
Download mbox | patch
Permalink /patch/66646/
State New
Headers show

Comments

Andi Kleen - Oct. 4, 2010, 1:11 p.m.
From: Andi Kleen <ak@linux.intel.com>

-fwhopr=jobserver requires telling GNU make that the linker (= lto)
rules support job server, so that the necessary jobserver
information is passed through.

Add + to all the executable targets that run LTO for this purpose.

This improves build performance with a -fwhopr=jobserver
bootstrap (or BUILD_CONFIG=bootstrap-lto) significantly.

I didn't change Ada because that apparently doesn't support LTO.

Passes bootstrap and test suite. Ok to commit?

gcc/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Makefile.in (xgcc, cpp, cc1, collect2, lto-wrapper, gcov,
        gcov-dump, cc1-dummy, genprog, build/gcov-iov):
        Add + to build rule.

gcc/cp/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (g++, cc1plus): Add + to build rule.

gcc/fortran/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (gfortran, f951): Add + to build rule.

gcc/java/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (xgcj, jc1, jcf-dump, jvgenmain):
        Add + to build rule.

gcc/lto/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (lto1): Add + to build rule.

gcc/objc/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (cc1obj-dummy, cc1obj): Add + to build rule.

gcc/objcp/

2010-10-04  Andi Kleen <ak@linux.intel.com>

	* Make-lang.in (cc1objplus-dummy, cc1objplus): Add + to build rule.

More plus fixes
---
 gcc/Makefile.in          |   20 ++++++++++----------
 gcc/cp/Make-lang.in      |    4 ++--
 gcc/fortran/Make-lang.in |    4 ++--
 gcc/java/Make-lang.in    |    8 ++++----
 gcc/lto/Make-lang.in     |    2 +-
 gcc/objc/Make-lang.in    |    4 ++--
 gcc/objcp/Make-lang.in   |    4 ++--
 7 files changed, 23 insertions(+), 23 deletions(-)
Paolo Bonzini - Oct. 4, 2010, 3:17 p.m.
On 10/04/2010 03:11 PM, Andi Kleen wrote:
> From: Andi Kleen<ak@linux.intel.com>
>
> -fwhopr=jobserver requires telling GNU make that the linker (= lto)
> rules support job server, so that the necessary jobserver
> information is passed through.
>
> Add + to all the executable targets that run LTO for this purpose.
>
> This improves build performance with a -fwhopr=jobserver
> bootstrap (or BUILD_CONFIG=bootstrap-lto) significantly.
>
> I didn't change Ada because that apparently doesn't support LTO.
>
> Passes bootstrap and test suite. Ok to commit?

Ok, but maybe we want to document this in the user manual too?

Paolo
Andi Kleen - Oct. 4, 2010, 5:05 p.m.
> 
> Ok, but maybe we want to document this in the user manual too?

Thanks.

It already is documented in invoke.texi:

The parent Makefile will need a @samp{+} prepended to the command recipe
for this to work. This will likely only work if @env{MAKE} is 
GNU make.

-Andi
Ralf Wildenhues - Oct. 4, 2010, 5:42 p.m.
Hello,

* Andi Kleen wrote on Mon, Oct 04, 2010 at 03:11:39PM CEST:
> -fwhopr=jobserver requires telling GNU make that the linker (= lto)
> rules support job server, so that the necessary jobserver
> information is passed through.
> 
> Add + to all the executable targets that run LTO for this purpose.

FWIW, this will break 'make -n'.  I sent a feature request for GNU make:
<http://thread.gmane.org/gmane.comp.gnu.make.bugs/5015>

With GNU make-specific code, we could probably work around it.  I'm
thinking of something along these lines:

jobserv := $(shell dry=no; for f in $(MAKEFLAGS); do \
                case $$f in \
                  (*=*|--*);; \
                  (*n*) dry=yes;; \
                esac; \
              done; \
              test "$$dry" = no && echo +)

cc1: ...
        $(jobserv)$(LINK) ...


but the open parens in the case patterns are probably not portable
enough to all shells.

Although you may argue that 'make -n' is at least mildly broken in GCC
anyway.

FWIW, the '+' feature is not GNU make-specific, only the $(MAKE) string
detection is.

> This improves build performance with a -fwhopr=jobserver
> bootstrap (or BUILD_CONFIG=bootstrap-lto) significantly.

Yep.

Cheers,
Ralf
Andi Kleen - Oct. 4, 2010, 5:46 p.m.
On Mon, Oct 04, 2010 at 07:42:46PM +0200, Ralf Wildenhues wrote:
> Hello,
> 
> * Andi Kleen wrote on Mon, Oct 04, 2010 at 03:11:39PM CEST:
> > -fwhopr=jobserver requires telling GNU make that the linker (= lto)
> > rules support job server, so that the necessary jobserver
> > information is passed through.
> > 
> > Add + to all the executable targets that run LTO for this purpose.
> 
> FWIW, this will break 'make -n'.  I sent a feature request for GNU make:

Thanks, I didn't know that. 

I agree that having a command line option for make would be best.
I'm not sure why make tries so hard to not always pass jobserver
anyways. 

> Although you may argue that 'make -n' is at least mildly broken in GCC
> anyway.

I'm not even sure what it is good for?

> FWIW, the '+' feature is not GNU make-specific, only the $(MAKE) string
> detection is.

jobserver is GNU make specific I believe.

-Andi
Ralf Wildenhues - Oct. 4, 2010, 5:53 p.m.
* Andi Kleen wrote on Mon, Oct 04, 2010 at 07:46:45PM CEST:
> I agree that having a command line option for make would be best.
> I'm not sure why make tries so hard to not always pass jobserver
> anyways. 

Because you can easily mess up the jobserver's state when you use the
fd's but don't follow the protocol; it might also hang if you keep a
cookie or maybe even if you keep an fd open, haven't checked.

> On Mon, Oct 04, 2010 at 07:42:46PM +0200, Ralf Wildenhues wrote:
> > Although you may argue that 'make -n' is at least mildly broken in GCC
> > anyway.
> 
> I'm not even sure what it is good for?

To see what would happen.  It may not be desirable in GCC, but generally
it can be quite helpful.  Of course GNU make functions aren't shown, so
in order to debug GNU make-heavy makefiles it helps more to use remake.

> > FWIW, the '+' feature is not GNU make-specific, only the $(MAKE) string
> > detection is.
> 
> jobserver is GNU make specific I believe.

Yes (although IIRC some BSDs have been working on one too), sorry for
being unprecise.  Executing even in dry-run is not GNU make-specific.

Cheers,
Ralf
Andi Kleen - Oct. 4, 2010, 8:37 p.m.
On 10/4/2010 7:53 PM, Ralf Wildenhues wrote:
> * Andi Kleen wrote on Mon, Oct 04, 2010 at 07:46:45PM CEST:
>> I agree that having a command line option for make would be best.
>> I'm not sure why make tries so hard to not always pass jobserver
>> anyways.
> Because you can easily mess up the jobserver's state when you use the
> fd's but don't follow the protocol; it might also hang if you keep a
> cookie or maybe even if you keep an fd open, haven't checked.

Hmm maybe the solution would be to implement a more robust protocol
and then enable it unconditionally.

-Andi
Ralf Wildenhues - Oct. 5, 2010, 4:02 a.m.
* Andi Kleen wrote on Mon, Oct 04, 2010 at 10:37:46PM CEST:
>  On 10/4/2010 7:53 PM, Ralf Wildenhues wrote:
> >* Andi Kleen wrote on Mon, Oct 04, 2010 at 07:46:45PM CEST:
> >>I agree that having a command line option for make would be best.
> >>I'm not sure why make tries so hard to not always pass jobserver
> >>anyways.
> >Because you can easily mess up the jobserver's state when you use the
> >fd's but don't follow the protocol; it might also hang if you keep a
> >cookie or maybe even if you keep an fd open, haven't checked.
> 
> Hmm maybe the solution would be to implement a more robust protocol
> and then enable it unconditionally.

FWIW, I don't think the protocol is particularly non-robust.  It's just
that missing cookies are going to lead to problems, and closing file
descriptors not intended for arbitrary child processes is good defensive
programming in general.  However, this really should be discussed with
the GNU make maintainer.

Cheers,
Ralf
Alexandre Oliva - Oct. 5, 2010, 6:21 a.m.
On Oct  4, 2010, Ralf Wildenhues <Ralf.Wildenhues@gmx.de> wrote:

> Hello,
> * Andi Kleen wrote on Mon, Oct 04, 2010 at 03:11:39PM CEST:
>> -fwhopr=jobserver requires telling GNU make that the linker (= lto)
>> rules support job server, so that the necessary jobserver
>> information is passed through.
>> 
>> Add + to all the executable targets that run LTO for this purpose.

> FWIW, this will break 'make -n'.

Would a “# $(MAKE)” comment at the end of the link command break it too?
IIRC such comments will also cause make to pass jobserver info down.
Paolo Bonzini - Oct. 5, 2010, 10:41 a.m.
On 10/04/2010 07:42 PM, Ralf Wildenhues wrote:
> Hello,
>
> * Andi Kleen wrote on Mon, Oct 04, 2010 at 03:11:39PM CEST:
>> -fwhopr=jobserver requires telling GNU make that the linker (= lto)
>> rules support job server, so that the necessary jobserver
>> information is passed through.
>>
>> Add + to all the executable targets that run LTO for this purpose.
>
> FWIW, this will break 'make -n'.  I sent a feature request for GNU make:
> <http://thread.gmane.org/gmane.comp.gnu.make.bugs/5015>
>
> With GNU make-specific code, we could probably work around it.  I'm
> thinking of something along these lines:
>
> jobserv := $(shell dry=no; for f in $(MAKEFLAGS); do \
>                  case $$f in \
>                    (*=*|--*);; \

Any reason to check for *=*?  Even -W or -I do not appear there.  I 
always thought this would do:

ifeq (n,$(findstring n, $(filter-out --%, $(MAKEFLAGS))))
$(warning dry-run)
else
$(warning not dry-run)
endif

(BTW, adding --no-print-directory to $(MAKEFLAGS) broke GNU make's own 
example of using findstring to test MAKEFLAGS...).

Paolo
Ralf Wildenhues - Oct. 5, 2010, 5:03 p.m.
* Alexandre Oliva wrote on Tue, Oct 05, 2010 at 08:21:25AM CEST:
> On Oct  4, 2010, Ralf Wildenhues wrote:
> > * Andi Kleen wrote on Mon, Oct 04, 2010 at 03:11:39PM CEST:
> >> Add + to all the executable targets that run LTO for this purpose.
> 
> > FWIW, this will break 'make -n'.
> 
> Would a “# $(MAKE)” comment at the end of the link command break it too?

Yep.

> IIRC such comments will also cause make to pass jobserver info down.

Yep.

Cheers,
Ralf
Ralf Wildenhues - Oct. 5, 2010, 5:55 p.m.
* Paolo Bonzini wrote on Tue, Oct 05, 2010 at 12:41:24PM CEST:
> On 10/04/2010 07:42 PM, Ralf Wildenhues wrote:
> >jobserv := $(shell dry=no; for f in $(MAKEFLAGS); do \
> >                 case $$f in \
> >                   (*=*|--*);; \
> 
> Any reason to check for *=*?

Variable assignments:

$ cat Makefile
a: ; @echo $(MAKEFLAGS) # $(MAKE)
$ make -n foo=bar
n -- foo=bar

(The above came from the Automake code which is intended for portable
make.)

> Even -W or -I do not appear there.

That's because they are not meant to be passed on to recursive makes.
Some long options go there though.

> I always thought this would do:
> 
> ifeq (n,$(findstring n, $(filter-out --%, $(MAKEFLAGS))))
> $(warning dry-run)
> else
> $(warning not dry-run)
> endif

That's really interesting, because there seems to be something special
going on:

$ cat Makefile
a: ; @echo $(findstring n, $(filter-out --%, $(MAKEFLAGS)))
$ make foo=barn
n

Yet your code above seems to get it right.

> (BTW, adding --no-print-directory to $(MAKEFLAGS) broke GNU make's
> own example of using findstring to test MAKEFLAGS...).

Yes that should be fixed.

Cheers,
Ralf

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a402976..0421368 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1809,7 +1809,7 @@  libbackend.a: $(OBJS)
 # and CC is `gcc'.  It is renamed to `gcc' when it is installed.
 xgcc$(exeext): $(GCC_OBJS) gccspec.o version.o intl.o prefix.o \
    version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
 	  gccspec.o intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 # cpp is to cpp0 as gcc is to cc1.
@@ -1817,7 +1817,7 @@  xgcc$(exeext): $(GCC_OBJS) gccspec.o version.o intl.o prefix.o \
 # instead of gccspec.o.
 cpp$(exeext): $(GCC_OBJS) cppspec.o version.o intl.o prefix.o \
    version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
 	  cppspec.o intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 # Dump a specs file to make -B./ read these specs over installed ones.
@@ -1834,7 +1834,7 @@  gcc-cross$(exeext): xgcc$(exeext)
 dummy-checksum.o : dummy-checksum.c $(CONFIG_H) $(SYSTEM_H)
 
 cc1-dummy$(exeext): $(C_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
 	  dummy-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
 cc1-checksum.c : cc1-dummy$(exeext) build/genchecksum$(build_exeext)
@@ -1843,7 +1843,7 @@  cc1-checksum.c : cc1-dummy$(exeext) build/genchecksum$(build_exeext)
 cc1-checksum.o : cc1-checksum.c $(CONFIG_H) $(SYSTEM_H)
 
 cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
 	  cc1-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
 #
@@ -2055,7 +2055,7 @@  COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o intl.o version.o
 COLLECT2_LIBS = @COLLECT2_LIBS@
 collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 # Don't try modifying collect2 (aka ld) in place--it might be linking this.
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o T$@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o T$@ \
 		$(COLLECT2_OBJS) $(LIBS) $(COLLECT2_LIBS)
 	mv -f T$@ $@
 
@@ -2072,7 +2072,7 @@  tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h
     $(OBSTACK_H) collect2.h intl.h
 
 lto-wrapper$(exeext): lto-wrapper.o intl.o $(LIBDEPS)
-	$(COMPILER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ lto-wrapper.o intl.o $(LIBS)
+	+$(COMPILER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ lto-wrapper.o intl.o $(LIBS)
 	mv -f T$@ $@
 
 lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h \
@@ -3934,7 +3934,7 @@  build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o
 
 # Rule for the generator programs:
 $(genprog:%=build/gen%$(build_exeext)): build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS)
-	$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
+	+$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
 	    $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
 
 # Generated source files for gengtype.
@@ -3978,7 +3978,7 @@  build/gcov-iov.o: gcov-iov.c $(BCONFIG_H) coretypes.h $(GTM_H) \
   $(SYSTEM_H) coretypes.h $(TM_H)
 
 build/gcov-iov$(build_exeext): build/gcov-iov.o
-	$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) \
+	+$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) \
 		build/gcov-iov.o -o $@
 
 gcov-iov.h: s-iov
@@ -3995,10 +3995,10 @@  gcov-dump.o: gcov-dump.c gcov-io.c $(GCOV_IO_H) $(SYSTEM_H) coretypes.h \
 
 GCOV_OBJS = gcov.o intl.o version.o errors.o
 gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
 GCOV_DUMP_OBJS = gcov-dump.o version.o errors.o
 gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
 		$(LIBS) -o $@
 #
 # Build the include directories.  The stamp files are stmp-* rather than
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 35736ca..4be40b5 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -62,7 +62,7 @@  g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \
 # Create the compiler driver for g++.
 GXX_OBJS = $(GCC_OBJS) g++spec.o intl.o prefix.o version.o
 g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 	  $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
 
 # Create a version of the g++ driver which calls the cross-compiler.
@@ -101,7 +101,7 @@  cc1plus-checksum.c : cc1plus-dummy$(exeext) build/genchecksum$(build_exeext)
 cc1plus-checksum.o : cc1plus-checksum.c $(CONFIG_H) $(SYSTEM_H)
 
 cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 	      $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
 # Special build rules.
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index 8f72d32..f3a7f8f 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -86,7 +86,7 @@  gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) \
 # Create the compiler driver gfortran.
 GFORTRAN_D_OBJS = $(GCC_OBJS) gfortranspec.o version.o prefix.o intl.o
 gfortran$(exeext): $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 	  $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
 
 # Create a version of the gfortran driver which calls the cross-compiler.
@@ -97,7 +97,7 @@  gfortran-cross$(exeext): gfortran$(exeext)
 # The compiler itself is called f951.
 f951$(exeext): $(F95_OBJS) \
 		$(BACKEND) $(LIBDEPS) attribs.o
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(F95_OBJS) $(BACKEND) $(LIBS) attribs.o $(BACKENDLIBS)
 
 gt-fortran-trans.h    : s-gtype; @true
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 0c91c37..d0d17cb 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -65,7 +65,7 @@  jvspec.o: $(srcdir)/java/jvspec.c $(SYSTEM_H) coretypes.h $(TM_H) \
 # Create the compiler driver for $(XGCJ).
 $(XGCJ)$(exeext): $(GCC_OBJS) jvspec.o java/jcf-path.o version.o \
 	   prefix.o intl.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
 	  jvspec.o java/jcf-path.o prefix.o intl.o \
 	  version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
@@ -100,17 +100,17 @@  jvspec.o-warn = -Wno-error
 
 jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o
 	rm -f $@
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(JAVA_OBJS) $(BACKEND) $(ZLIB) $(LIBICONV) $(LIBS) attribs.o $(BACKENDLIBS)
 
 jcf-dump$(exeext): $(JCFDUMP_OBJS) $(LIBDEPS)
 	rm -f $@
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JCFDUMP_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JCFDUMP_OBJS) \
 		$(CPPLIBS) $(ZLIB) $(LDEXP_LIB) $(LIBS)
 
 jvgenmain$(exeext): $(JVGENMAIN_OBJS) $(LIBDEPS)
 	rm -f $@
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JVGENMAIN_OBJS) \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JVGENMAIN_OBJS) \
 		$(LIBS)
 
 #
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index a770368..9391405 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -72,7 +72,7 @@  lto.stagefeedback:
 lto-warn = $(STRICT_WARN)
 
 $(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS) $(LTO_USE_LIBELF)
 
 # Dependencies
diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
index 67644bb..08189ef 100644
--- a/gcc/objc/Make-lang.in
+++ b/gcc/objc/Make-lang.in
@@ -52,7 +52,7 @@  OBJC_OBJS = objc/objc-lang.o objc/objc-act.o
 objc_OBJS = $(OBJC_OBJS) cc1obj-checksum.o
 
 cc1obj-dummy$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 	      $(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o \
 	      $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
@@ -62,7 +62,7 @@  cc1obj-checksum.c : cc1obj-dummy$(exeext) build/genchecksum$(build_exeext)
 cc1obj-checksum.o : cc1obj-checksum.c $(CONFIG_H) $(SYSTEM_H)
 
 cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 	      $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o \
 	      $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in
index 0849a89..f9adeac 100644
--- a/gcc/objcp/Make-lang.in
+++ b/gcc/objcp/Make-lang.in
@@ -56,7 +56,7 @@  obj-c++_OBJS = $(OBJCXX_OBJS) cc1objplus-checksum.o
 
 cc1objplus-dummy$(exeext): $(OBJCXX_OBJS) dummy-checksum.o $(BACKEND) \
 		$(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(OBJCXX_OBJS) dummy-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
 cc1objplus-checksum.c : cc1objplus-dummy$(exeext) build/genchecksum$(build_exeext)
@@ -65,7 +65,7 @@  cc1objplus-checksum.c : cc1objplus-dummy$(exeext) build/genchecksum$(build_exeex
 cc1objplus-checksum.o : cc1objplus-checksum.c $(CONFIG_H) $(SYSTEM_H)
 
 cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
 # Objective C++ language specific files.