diff mbox series

Don't call linker when creating pre-compiled header just because you saw a linker option

Message ID 1510685958.4087.4.camel@cavium.com
State New
Headers show
Series Don't call linker when creating pre-compiled header just because you saw a linker option | expand

Commit Message

Steve Ellcey Nov. 14, 2017, 6:59 p.m. UTC
I am building GCC (and binutils) with --with-sysroot and I build glibc in
that sysroot too.  I want to test GCC using the glibc libraries I just
built, but by default GCC uses the dynamic linker that is in /lib and that
is loading the "normal" libraries from /lib or /lib64 at runtime and not
the ones from my sysroot.  To address this I ran the GCC testsuite with:

make check RUNTESTFLAGS="CFLAGS_FOR_TARGET='-Wl,--dynamic-linker=/mylocation/lib/ld-linux-aarch64.so.1 -Wl,-rpath=/mylocation/lib64'"

But when I do this, I noticed that a number of pch tests fail.  What I found
is that when I run the pch testsuite, it executes:

/home/sellcey/tot/obj/gcc/gcc/xgcc -B/home/sellcey/tot/obj/gcc/gcc/ ./common-1.h -fno-diagnostics-show-caret -fdiagnostics-color=never -O0 -g -Wl,--dynamic-linker=/mylocation/lib/ld-linux-aarch64.so.1 -Wl,-rpath=/mylocation/lib64 -o common-1.h.gch

And this causes the linker to run and try to create an executable instead of 
creating a pre-compiled header.  If I run the same command without the
-Wl flags then GCC creates the pre-compiled header that I need for testing.

I tracked this down to driver::maybe_run_linker where it sees the linker
flags and increments num_linker_inputs, this causes the routine to call
the linker.  I would like to have this function ignore linker options
and only count linker input files.  This way the linker is only called
when there is an actual file to link.

I tested this with the GCC testsuite and got no regressions, OK to checkin?


2017-11-14  Steve Ellcey  <sellcey@cavium.com>

	* gcc.c (driver::maybe_run_linker): Ignore linker options
	when checking for linker inputs.

Comments

Richard Biener Nov. 14, 2017, 7:04 p.m. UTC | #1
On November 14, 2017 7:59:18 PM GMT+01:00, Steve Ellcey <sellcey@cavium.com> wrote:
>I am building GCC (and binutils) with --with-sysroot and I build glibc
>in
>that sysroot too.  I want to test GCC using the glibc libraries I just
>built, but by default GCC uses the dynamic linker that is in /lib and
>that
>is loading the "normal" libraries from /lib or /lib64 at runtime and
>not
>the ones from my sysroot.  To address this I ran the GCC testsuite
>with:
>
>make check
>RUNTESTFLAGS="CFLAGS_FOR_TARGET='-Wl,--dynamic-linker=/mylocation/lib/ld-linux-aarch64.so.1
>-Wl,-rpath=/mylocation/lib64'"
>
>But when I do this, I noticed that a number of pch tests fail.  What I
>found
>is that when I run the pch testsuite, it executes:
>
>/home/sellcey/tot/obj/gcc/gcc/xgcc -B/home/sellcey/tot/obj/gcc/gcc/
>./common-1.h -fno-diagnostics-show-caret -fdiagnostics-color=never -O0
>-g -Wl,--dynamic-linker=/mylocation/lib/ld-linux-aarch64.so.1
>-Wl,-rpath=/mylocation/lib64 -o common-1.h.gch
>
>And this causes the linker to run and try to create an executable
>instead of 
>creating a pre-compiled header.  If I run the same command without the
>-Wl flags then GCC creates the pre-compiled header that I need for
>testing.
>
>I tracked this down to driver::maybe_run_linker where it sees the
>linker
>flags and increments num_linker_inputs, this causes the routine to call
>the linker.  I would like to have this function ignore linker options
>and only count linker input files.  This way the linker is only called
>when there is an actual file to link.
>
>I tested this with the GCC testsuite and got no regressions, OK to
>checkin?

I think the intent is to link even for just - lfoo while it makes sense to ignore -L/path - Wl,... Certainly counts as possible input. 

It seems you even break - lfoo. 

Richard. 

>
>2017-11-14  Steve Ellcey  <sellcey@cavium.com>
>
>	* gcc.c (driver::maybe_run_linker): Ignore linker options
>	when checking for linker inputs.
>
>
>diff --git a/gcc/gcc.c b/gcc/gcc.c
>index 43e6d59..61c7561 100644
>--- a/gcc/gcc.c
>+++ b/gcc/gcc.c
>@@ -8289,11 +8289,14 @@ driver::maybe_run_linker (const char *argv0)
>const
>   int linker_was_run = 0;
>   int num_linker_inputs;

>-  /* Determine if there are any linker input files.  */
>+  /* Determine if there are any linker input files, but ignore
>+     linker options.  If we have options but no input files we
>+     do not want to call the linker.  */
>   num_linker_inputs = 0;
>   for (i = 0; (int) i < n_infiles; i++)
>-    if (explicit_link_files[i] || outfiles[i] != NULL)
>-      num_linker_inputs++;
>+    if ((explicit_link_files[i] || outfiles[i] != NULL)
>+        && (outfiles[i] == NULL || outfiles[i][0] != '-'))
>+        num_linker_inputs++;

>   /* Run ld to link all the compiler output files.  */
>
Steve Ellcey Nov. 14, 2017, 10:51 p.m. UTC | #2
On Tue, 2017-11-14 at 20:04 +0100, Richard Biener wrote:

> I think the intent is to link even for just - lfoo while it makes
> sense to ignore -L/path - Wl,... Certainly counts as possible input. 
> 
> It seems you even break - lfoo. 
> 
> Richard. 

Good point.  I guess I need to take a different approach to determining
if I am creating a PCH or an executable.  Here is a new patch that also
passes the testsuite with no regressions.  Originally in this patch I
was setting create_pch_flag whenever I saw a '@-cheader' compiler being
called but that broke on things like 'gcc foo.h main.c' so now I only
skip the link phase when creating pch's is the only thing being done.

Steve Ellcey
sellcey@cavium.com



2017-11-14  Steve Ellcey  <sellcey@cavium.com>

	* gcc.c (create_pch_flag): New variable.
	(driver::prepare_infiles): Set create_pch_flag
	when we are only creating precompiled headers.
	(driver::maybe_run_linker): Do not link if
	create_pch_flag is set.
	(driver::finalize): Reset create_pch_flag.


diff --git a/gcc/gcc.c b/gcc/gcc.c
index 43e6d59..9df32e3 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -208,6 +208,9 @@ int is_cpp_driver;
 /* Flag set to nonzero if an @file argument has been supplied to gcc.  */
 static bool at_file_supplied;
 
+/* Flag set to nonzero if we are generating a precompiled header.  */
+static bool create_pch_flag;
+
 /* Definition of string containing the arguments given to configure.  */
 #include "configargs.h"
 
@@ -8074,6 +8077,8 @@ driver::prepare_infiles ()
 {
   size_t i;
   int lang_n_infiles = 0;
+  bool found_pch_input_file = false;
+  bool found_non_pch_input_file = false;
 
   if (n_infiles == added_libraries)
     fatal_error (input_location, "no input files");
@@ -8102,8 +8107,16 @@ driver::prepare_infiles ()
 						   strlen (name),
 						   infiles[i].language);
 
-      if (compiler && !(compiler->combinable))
-	combine_inputs = false;
+      if (compiler)
+	{
+	  if (!(compiler->combinable))
+	    combine_inputs = false;
+
+	  if (strcmp(compiler->suffix, "@c-header") == 0)
+	    found_pch_input_file = true;
+	  else
+	    found_non_pch_input_file = true;
+	}
 
       if (lang_n_infiles > 0 && compiler != input_file_compiler
 	  && infiles[i].language && infiles[i].language[0] != '*')
@@ -8129,6 +8142,9 @@ driver::prepare_infiles ()
     fatal_error (input_location,
 		 "cannot specify -o with -c, -S or -E with multiple files");
 
+  if (found_pch_input_file && !found_non_pch_input_file)
+    create_pch_flag = true;
+
   /* No early exit needed from main; we can continue.  */
   return false;
 }
@@ -8289,6 +8305,10 @@ driver::maybe_run_linker (const char *argv0) const
   int linker_was_run = 0;
   int num_linker_inputs;
 
+  /* If we are creating a precompiled header, do not run the linker.  */
+  if (create_pch_flag)
+    return;
+
   /* Determine if there are any linker input files.  */
   num_linker_inputs = 0;
   for (i = 0; (int) i < n_infiles; i++)
@@ -10059,6 +10079,7 @@ driver::finalize ()
 
   is_cpp_driver = 0;
   at_file_supplied = 0;
+  create_pch_flag = 0;
   print_help_list = 0;
   print_version = 0;
   verbose_only_flag = 0;
diff mbox series

Patch

diff --git a/gcc/gcc.c b/gcc/gcc.c
index 43e6d59..61c7561 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -8289,11 +8289,14 @@  driver::maybe_run_linker (const char *argv0) const
   int linker_was_run = 0;
   int num_linker_inputs;
 
-  /* Determine if there are any linker input files.  */
+  /* Determine if there are any linker input files, but ignore
+     linker options.  If we have options but no input files we
+     do not want to call the linker.  */
   num_linker_inputs = 0;
   for (i = 0; (int) i < n_infiles; i++)
-    if (explicit_link_files[i] || outfiles[i] != NULL)
-      num_linker_inputs++;
+    if ((explicit_link_files[i] || outfiles[i] != NULL)
+        && (outfiles[i] == NULL || outfiles[i][0] != '-'))
+        num_linker_inputs++;
 
   /* Run ld to link all the compiler output files.  */