[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