[PATCH] Generalize -fuse-ld= to support absolute path or arbitrary ld.linker
Fangrui Song via gcc-patches
gcc-patches@gcc.gnu.org
Thu Feb 13 17:59:00 GMT 2020
On 2020-02-09, Fangrui Song wrote:
> PR driver/93645
> * common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
> * opts.c (common_handle_option): Handle OPT_fuse_ld_.
> * gcc.c (driver_handle_option): Likewise.
> * collect2.c (main): Likewise.
>---
> gcc/ChangeLog | 8 ++++++
> gcc/collect2.c | 67 ++++++++++++++++++++++++---------------------
> gcc/common.opt | 14 ++--------
> gcc/doc/invoke.texi | 15 +++-------
> gcc/gcc.c | 14 ++++------
> gcc/opts.c | 4 +--
> 6 files changed, 57 insertions(+), 65 deletions(-)
>
>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>index feb2d066d0b..6bcec12d841 100644
>--- a/gcc/ChangeLog
>+++ b/gcc/ChangeLog
>@@ -1,3 +1,11 @@
>+2020-02-09 Fangrui Song <maskray@google.com>
>+
>+ PR driver/93645
>+ * common.opt (-fuse-ld=): Delete -fuse-ld=[bfd|gold|lld]. Add -fuse-ld=.
>+ * opts.c (common_handle_option): Handle OPT_fuse_ld_.
>+ * gcc.c (driver_handle_option): Likewise.
>+ * collect2.c (main): Likewise.
>+
> 2020-02-09 Uroš Bizjak <ubizjak@gmail.com>
>
> * recog.c: Move pass_split_before_sched2 code in front of
>diff --git a/gcc/collect2.c b/gcc/collect2.c
>index 502d629141c..a3ef525a93b 100644
>--- a/gcc/collect2.c
>+++ b/gcc/collect2.c
>@@ -859,18 +859,12 @@ main (int argc, char **argv)
> {
> USE_DEFAULT_LD,
> USE_PLUGIN_LD,
>- USE_GOLD_LD,
>- USE_BFD_LD,
>- USE_LLD_LD,
>- USE_LD_MAX
>+ USE_LD
> } selected_linker = USE_DEFAULT_LD;
>- static const char *const ld_suffixes[USE_LD_MAX] =
>+ static const char *const ld_suffixes[USE_LD] =
> {
> "ld",
>- PLUGIN_LD_SUFFIX,
>- "ld.gold",
>- "ld.bfd",
>- "ld.lld"
>+ PLUGIN_LD_SUFFIX
> };
> static const char *const real_ld_suffix = "real-ld";
> static const char *const collect_ld_suffix = "collect-ld";
>@@ -882,7 +876,7 @@ main (int argc, char **argv)
> static const char *const strip_suffix = "strip";
> static const char *const gstrip_suffix = "gstrip";
>
>- const char *full_ld_suffixes[USE_LD_MAX];
>+ const char *full_ld_suffixes[USE_LD];
> #ifdef CROSS_DIRECTORY_STRUCTURE
> /* If we look for a program in the compiler directories, we just use
> the short name, since these directories are already system-specific.
>@@ -924,6 +918,7 @@ main (int argc, char **argv)
> const char **ld1;
> bool use_plugin = false;
> bool use_collect_ld = false;
>+ const char *use_ld = NULL;
>
> /* The kinds of symbols we will have to consider when scanning the
> outcome of a first pass link. This is ALL to start with, then might
>@@ -948,7 +943,7 @@ main (int argc, char **argv)
> #endif
> int i;
>
>- for (i = 0; i < USE_LD_MAX; i++)
>+ for (i = 0; i < USE_LD; i++)
> full_ld_suffixes[i]
> #ifdef CROSS_DIRECTORY_STRUCTURE
> = concat (target_machine, "-", ld_suffixes[i], NULL);
>@@ -1041,12 +1036,11 @@ main (int argc, char **argv)
> if (selected_linker == USE_DEFAULT_LD)
> selected_linker = USE_PLUGIN_LD;
> }
>- else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
>- selected_linker = USE_BFD_LD;
>- else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
>- selected_linker = USE_GOLD_LD;
>- else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
>- selected_linker = USE_LLD_LD;
>+ else if (!strncmp (argv[i], "-fuse-ld=", 9))
>+ {
>+ use_ld = argv[i] + 9;
>+ selected_linker = USE_LD;
>+ }
> else if (strncmp (argv[i], "-o", 2) == 0)
> {
> /* Parse the output filename if it's given so that we can make
>@@ -1152,8 +1146,7 @@ main (int argc, char **argv)
> /* Maybe we know the right file to use (if not cross). */
> ld_file_name = 0;
> #ifdef DEFAULT_LINKER
>- if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
>- selected_linker == USE_LLD_LD)
>+ if (!ld_file_name && selected_linker == USE_LD)
> {
> char *linker_name;
> # ifdef HOST_EXECUTABLE_SUFFIX
>@@ -1168,15 +1161,13 @@ main (int argc, char **argv)
> if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
> {
> default_linker[len] = '\0';
>- linker_name = concat (default_linker,
>- &ld_suffixes[selected_linker][2],
>+ linker_name = concat (default_linker, ".", use_ld,
> HOST_EXECUTABLE_SUFFIX, NULL);
> }
> }
> if (linker_name == NULL)
> # endif
>- linker_name = concat (DEFAULT_LINKER,
>- &ld_suffixes[selected_linker][2],
>+ linker_name = concat (DEFAULT_LINKER, ".", use_ld,
> NULL);
> if (access (linker_name, X_OK) == 0)
> ld_file_name = linker_name;
>@@ -1197,14 +1188,28 @@ main (int argc, char **argv)
> ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
> use_collect_ld = ld_file_name != 0;
> }
>- /* Search the compiler directories for `ld'. We have protection against
>- recursive calls in find_a_file. */
>- if (ld_file_name == 0)
>- ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
>- /* Search the ordinary system bin directories
>- for `ld' (if native linking) or `TARGET-ld' (if cross). */
>- if (ld_file_name == 0)
>- ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
>+ if (selected_linker != USE_LD) {
>+ /* Search the compiler directories for `ld'. We have protection against
>+ recursive calls in find_a_file. */
>+ if (!ld_file_name)
>+ ld_file_name = find_a_file(&cpath, ld_suffixes[selected_linker], X_OK);
>+ /* Search the ordinary system bin directories
>+ for `ld' (if native linking) or `TARGET-ld' (if cross). */
>+ if (!ld_file_name)
>+ ld_file_name = find_a_file(&path, full_ld_suffixes[selected_linker], X_OK);
>+ } else if (IS_ABSOLUTE_PATH(use_ld) && access(use_ld, X_OK) == 0) {
>+ ld_file_name = use_ld;
>+ } else {
>+ const char *linker_name = concat("ld.", use_ld, NULL);
>+ if (!ld_file_name)
>+ ld_file_name = find_a_file(&cpath, linker_name, X_OK);
>+ if (!ld_file_name) {
>+#ifdef CROSS_DIRECTORY_STRUCTURE
>+ linker_name = concat(target_machine, "-", linker_name, NULL);
>+#endif
>+ ld_file_name = find_a_file(&path, linker_name, X_OK);
>+ }
>+ }
>
> #ifdef REAL_NM_FILE_NAME
> nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
>diff --git a/gcc/common.opt b/gcc/common.opt
>index 5692cd04374..a76ed6434bb 100644
>--- a/gcc/common.opt
>+++ b/gcc/common.opt
>@@ -2859,17 +2859,9 @@ funwind-tables
> Common Report Var(flag_unwind_tables) Optimization
> Just generate unwind tables for exception handling.
>
>-fuse-ld=bfd
>-Common Driver Negative(fuse-ld=gold)
>-Use the bfd linker instead of the default linker.
>-
>-fuse-ld=gold
>-Common Driver Negative(fuse-ld=bfd)
>-Use the gold linker instead of the default linker.
>-
>-fuse-ld=lld
>-Common Driver Negative(fuse-ld=lld)
>-Use the lld LLVM linker instead of the default linker.
>+fuse-ld=
>+Common Driver Joined
>+-fuse-ld=[bfd|gold|lld|<absolute path>] Use the specified linker.
>
> fuse-linker-plugin
> Common Undocumented Var(flag_use_linker_plugin)
>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>index 35b341e759f..c2dd410c88f 100644
>--- a/gcc/doc/invoke.texi
>+++ b/gcc/doc/invoke.texi
>@@ -14128,17 +14128,10 @@ uses @samp{nolto-rel}. To maintain whole program optimization, it is
> recommended to link such objects into static library instead. Alternatively it
> is possible to use H.J. Lu's binutils with support for mixed objects.
>
>-@item -fuse-ld=bfd
>-@opindex fuse-ld=bfd
>-Use the @command{bfd} linker instead of the default linker.
>-
>-@item -fuse-ld=gold
>-@opindex fuse-ld=gold
>-Use the @command{gold} linker instead of the default linker.
>-
>-@item -fuse-ld=lld
>-@opindex fuse-ld=lld
>-Use the LLVM @command{lld} linker instead of the default linker.
>+@item -fuse-ld=@var{linker}
>+@opindex fuse-ld=linker
>+If @var{linker} is an absolute path, use it instead of the default linker;
>+otherwise use @command{ld.@var{linker}}.
>
> @cindex Libraries
> @item -l@var{library}
>diff --git a/gcc/gcc.c b/gcc/gcc.c
>index effc384f3ef..f9a6f10502d 100644
>--- a/gcc/gcc.c
>+++ b/gcc/gcc.c
>@@ -3989,12 +3989,8 @@ driver_handle_option (struct gcc_options *opts,
> do_save = false;
> break;
>
>- case OPT_fuse_ld_bfd:
>- use_ld = ".bfd";
>- break;
>-
>- case OPT_fuse_ld_gold:
>- use_ld = ".gold";
>+ case OPT_fuse_ld_:
>+ use_ld = arg;
> break;
>
> case OPT_fcompare_debug_second:
>@@ -7903,20 +7899,20 @@ driver::maybe_print_and_exit () const
> if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
> {
> default_linker[len] = '\0';
>- ld = concat (default_linker, use_ld,
>+ ld = concat (default_linker, ".", use_ld,
> HOST_EXECUTABLE_SUFFIX, NULL);
> }
> }
> if (ld == NULL)
> # endif
>- ld = concat (DEFAULT_LINKER, use_ld, NULL);
>+ ld = concat (DEFAULT_LINKER, ".", use_ld, NULL);
> if (access (ld, X_OK) == 0)
> {
> printf ("%s\n", ld);
> return (0);
> }
> #endif
>- print_prog_name = concat (print_prog_name, use_ld, NULL);
>+ print_prog_name = concat (print_prog_name, ".", use_ld, NULL);
> }
> char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
> printf ("%s\n", (newname ? newname : print_prog_name));
>diff --git a/gcc/opts.c b/gcc/opts.c
>index 7affeb41a96..f50d365d517 100644
>--- a/gcc/opts.c
>+++ b/gcc/opts.c
>@@ -2763,9 +2763,7 @@ common_handle_option (struct gcc_options *opts,
> dc->max_errors = value;
> break;
>
>- case OPT_fuse_ld_bfd:
>- case OPT_fuse_ld_gold:
>- case OPT_fuse_ld_lld:
>+ case OPT_fuse_ld_:
> case OPT_fuse_linker_plugin:
> /* No-op. Used by the driver and passed to us because it starts with f.*/
> break;
>--
>2.25.0
Friendly ping:)
More information about the Gcc-patches
mailing list