Message ID | 20200519192144.5fxm3v4k22ml7njm@google.com |
---|---|
State | New |
Headers | show |
Series | Add -fuse-ld= to specify an arbitrary executable as the linker | expand |
Hello. > diff --git a/gcc/collect2.c b/gcc/collect2.c > index f8a5ce45994..e04892cb91f 100644 > --- a/gcc/collect2.c > +++ b/gcc/collect2.c > @@ -782,15 +782,16 @@ main (int argc, char **argv) > USE_GOLD_LD, > USE_BFD_LD, > USE_LLD_LD, > + USE_LD, I wouldn't add a new constant. > USE_LD_MAX > } 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" > + "ld.lld", Not needed change. > }; > static const char *const real_ld_suffix = "real-ld"; > static const char *const collect_ld_suffix = "collect-ld"; > @@ -802,7 +803,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. > @@ -844,6 +845,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 > @@ -868,7 +870,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); > @@ -967,6 +969,11 @@ main (int argc, char **argv) > 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; Here you can selected_linker = USE_LD_MAX. > + } > else if (strncmp (argv[i], "-o", 2) == 0) > { > /* Parse the output filename if it's given so that we can make > @@ -1119,12 +1126,16 @@ main (int argc, char **argv) > } > /* 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); Here you can check either for selected_linker == USE_LD_MAX or for use_ld != NULL. > + if (selected_linker == USE_LD) { > + ld_file_name = find_a_file (&cpath, use_ld, X_OK); > + } else { Bad coding style (braces should be at a separate line) and you don't need the {} here. > + 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); > + } > > #ifdef REAL_NM_FILE_NAME > nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK); > @@ -1296,8 +1307,7 @@ main (int argc, char **argv) > "configuration"); > #endif > } > - else if (!use_collect_ld > - && strncmp (arg, "-fuse-ld=", 9) == 0) > + else if (strncmp (arg, "-fuse-ld=", 9) == 0) Why did you change this logic here? Note that it also affects e.g. -fuse-ld=gold here. Martin > { > /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */ > ld1--; > diff --git a/gcc/common.opt b/gcc/common.opt > index 4464049fc1f..6408d042d8c 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -2908,6 +2908,10 @@ fuse-ld=lld > Common Driver Negative(fuse-ld=lld) > Use the lld LLVM linker instead of the default linker. > > +fuse-ld= > +Common Driver Joined > +Use the specified executable instead of the default linker. > + > fuse-linker-plugin > Common Undocumented Var(flag_use_linker_plugin) > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index 7217e27151d..30a2fc4fa53 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -14304,6 +14304,10 @@ Use the @command{gold} linker instead of the default linker. > @opindex fuse-ld=lld > Use the LLVM @command{lld} linker instead of the default linker. > > +@item -fuse-ld=@var{linker} > +@opindex fuse-ld=linker > +Use the specified executable named @var{linker} instead of the default linker. > + > @cindex Libraries > @item -l@var{library} > @itemx -l @var{library} > diff --git a/gcc/opts.c b/gcc/opts.c > index ec3ca0720f9..522a196ab0f 100644 > --- a/gcc/opts.c > +++ b/gcc/opts.c > @@ -2785,6 +2785,7 @@ common_handle_option (struct gcc_options *opts, > 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; #ifdef REAL_NM_FILE_NAME nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK); @@ -1296,8 +1307,7 @@ main (int argc, char **argv) "configuration"); #endif } - else if (!use_collect_ld - && strncmp (arg, "-fuse-ld=", 9) == 0) + else if (strncmp (arg, "-fuse-ld=", 9) == 0) { /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */ ld1--; diff --git a/gcc/common.opt b/gcc/common.opt index 4464049fc1f..6408d042d8c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2908,6 +2908,10 @@ fuse-ld=lld Common Driver Negative(fuse-ld=lld) Use the lld LLVM linker instead of the default linker. +fuse-ld= +Common Driver Joined +Use the specified executable instead of the default linker. + fuse-linker-plugin Common Undocumented Var(flag_use_linker_plugin) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7217e27151d..30a2fc4fa53 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14304,6 +14304,10 @@ Use the @command{gold} linker instead of the default linker. @opindex fuse-ld=lld Use the LLVM @command{lld} linker instead of the default linker. +@item -fuse-ld=@var{linker} +@opindex fuse-ld=linker +Use the specified executable named @var{linker} instead of the default linker. + @cindex Libraries @item -l@var{library} @itemx -l @var{library} diff --git a/gcc/opts.c b/gcc/opts.c index ec3ca0720f9..522a196ab0f 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2785,6 +2785,7 @@ common_handle_option (struct gcc_options *opts, 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;
From 72049b927b6cee8c3acb2d56b2a403d9f0946807 Mon Sep 17 00:00:00 2001 From: Fangrui Song <maskray@google.com> Date: Tue, 19 May 2020 12:21:26 -0700 Subject: [PATCH] Add -fuse-ld= to specify an arbitrary executable as the linker The value can be either an absolute path or a relative path. Unlike -fuse-ld={bfd,gold,lld}, -fuse-ld= does not add a prefix `ld.` PR driver/93645 * common.opt (-fuse-ld=): Add -fuse-ld=. * opts.c (common_handle_option): Handle OPT_fuse_ld_. * gcc.c (driver_handle_option): Likewise. * collect2.c (main): Likewise. * doc/invoke.texi: Document -fuse-ld=. --- gcc/ChangeLog | 9 +++++++++ gcc/collect2.c | 34 ++++++++++++++++++++++------------ gcc/common.opt | 4 ++++ gcc/doc/invoke.texi | 4 ++++ gcc/opts.c | 1 + 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 703b6349516..19506bf0884 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2020-05-19 Fangrui Song <maskray@google.com> + + PR driver/93645 + * common.opt (-fuse-ld=): Add -fuse-ld=. + * opts.c (common_handle_option): Handle OPT_fuse_ld_. + * gcc.c (driver_handle_option): Likewise. + * collect2.c (main): Likewise. + * doc/invoke.texi: Document -fuse-ld=. + 2020-05-19 Jozef Lawrynowicz <jozef.l@mittosystems.com> * doc/sourcebuild.texi: Document new short_eq_int, ptr_eq_short, diff --git a/gcc/collect2.c b/gcc/collect2.c index f8a5ce45994..e04892cb91f 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -782,15 +782,16 @@ main (int argc, char **argv) USE_GOLD_LD, USE_BFD_LD, USE_LLD_LD, + USE_LD, USE_LD_MAX } 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" + "ld.lld", }; static const char *const real_ld_suffix = "real-ld"; static const char *const collect_ld_suffix = "collect-ld"; @@ -802,7 +803,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. @@ -844,6 +845,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 @@ -868,7 +870,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); @@ -967,6 +969,11 @@ main (int argc, char **argv) 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 @@ -1119,12 +1126,16 @@ main (int argc, char **argv) } /* 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) { + ld_file_name = find_a_file (&cpath, use_ld, X_OK); + } else { + 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); + } #ifdef REAL_NM_FILE_NAME nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK); @@ -1296,8 +1307,7 @@ main (int argc, char **argv) "configuration"); #endif } - else if (!use_collect_ld - && strncmp (arg, "-fuse-ld=", 9) == 0) + else if (strncmp (arg, "-fuse-ld=", 9) == 0) { /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */ ld1--; diff --git a/gcc/common.opt b/gcc/common.opt index 4464049fc1f..6408d042d8c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2908,6 +2908,10 @@ fuse-ld=lld Common Driver Negative(fuse-ld=lld) Use the lld LLVM linker instead of the default linker. +fuse-ld= +Common Driver Joined +Use the specified executable instead of the default linker. + fuse-linker-plugin Common Undocumented Var(flag_use_linker_plugin) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7217e27151d..30a2fc4fa53 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14304,6 +14304,10 @@ Use the @command{gold} linker instead of the default linker. @opindex fuse-ld=lld Use the LLVM @command{lld} linker instead of the default linker. +@item -fuse-ld=@var{linker} +@opindex fuse-ld=linker +Use the specified executable named @var{linker} instead of the default linker. + @cindex Libraries @item -l@var{library} @itemx -l @var{library} diff --git a/gcc/opts.c b/gcc/opts.c index ec3ca0720f9..522a196ab0f 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2785,6 +2785,7 @@ common_handle_option (struct gcc_options *opts, 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.26.2.761.g0e0b3e54be-goog