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 |
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. */ >
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 --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. */