]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/gcc-ar.c
* config/i386/i386.md (and<mode>3): Generate zero-extends for
[thirdparty/gcc.git] / gcc / gcc-ar.c
index fc7e4a2a2ec3977bf8b03a1671e0e1e0ae058dc9..7182d36319d06e6ae2601d7136e5f634941ae8b3 100644 (file)
@@ -1,5 +1,5 @@
 /* Wrapper for ar/ranlib/nm to pass the LTO plugin.
-   Copyright (C) 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011-2019 Free Software Foundation, Inc.
    Contributed by Andi Kleen.
 
 This file is part of GCC.
@@ -18,79 +18,237 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#include <stdio.h>
 #include "config.h"
 #include "system.h"
 #include "libiberty.h"
+#include "file-find.h"
 
 #ifndef PERSONALITY
 #error "Please set personality"
 #endif
 
+/* The exec prefix as derived at compile-time from --prefix.  */
+
+static const char standard_exec_prefix[] = STANDARD_EXEC_PREFIX;
+
+/* The libexec prefix as derived at compile-time from --prefix.  */
+
 static const char standard_libexec_prefix[] = STANDARD_LIBEXEC_PREFIX;
+
+/* The bindir prefix as derived at compile-time from --prefix.  */
+
 static const char standard_bin_prefix[] = STANDARD_BINDIR_PREFIX;
 
+/* A relative path to be used in finding the location of tools
+   relative to this program.  */
+
+static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
+
+/* The exec prefix as relocated from the location of this program.  */
+
+static const char *self_exec_prefix;
+
+/* The libexec prefix as relocated from the location of this program.  */
+
+static const char *self_libexec_prefix;
+
+/* The tools prefix as relocated from the location of this program.  */
+
+static const char *self_tooldir_prefix;
+
+/* The name of the machine that is being targeted.  */
+
+static const char *const target_machine = DEFAULT_TARGET_MACHINE;
+
+/* The target version.  */
+
+static const char *const target_version = DEFAULT_TARGET_VERSION;
+
+/* The collection of target specific path prefixes.  */
+
+static struct path_prefix target_path;
+
+/* The collection path prefixes.  */
+
+static struct path_prefix path;
+
+/* The directory separator.  */
+
 static const char dir_separator[] = { DIR_SEPARATOR, 0 };
 
+static void
+setup_prefixes (const char *exec_path)
+{
+  const char *self;
+
+  self = getenv ("GCC_EXEC_PREFIX");
+  if (!self)
+    self = exec_path;
+  else
+    self = concat (self, "gcc-" PERSONALITY, NULL);
+
+  /* Relocate the exec prefix.  */
+  self_exec_prefix = make_relative_prefix (self,
+                                          standard_bin_prefix,
+                                          standard_exec_prefix);
+  if (self_exec_prefix == NULL)
+    self_exec_prefix = standard_exec_prefix;
+
+  /* Relocate libexec prefix.  */
+  self_libexec_prefix = make_relative_prefix (self,
+                                             standard_bin_prefix,
+                                             standard_libexec_prefix);
+  if (self_libexec_prefix == NULL)
+    self_libexec_prefix = standard_libexec_prefix;
+
+
+  /* Build the relative path to the target-specific tool directory.  */
+  self_tooldir_prefix = concat (tooldir_base_prefix, target_machine,
+                               dir_separator, NULL);
+  self_tooldir_prefix = concat (self_exec_prefix, target_machine, 
+                               dir_separator, target_version, dir_separator,
+                               self_tooldir_prefix, NULL);
+
+  /* Add the target-specific tool bin prefix.  */
+  prefix_from_string (concat (self_tooldir_prefix, "bin", NULL), &target_path);
+
+  /* Add the target-specific libexec prefix.  */
+  self_libexec_prefix = concat (self_libexec_prefix, target_machine, 
+                               dir_separator, target_version,
+                               dir_separator, NULL);
+  prefix_from_string (self_libexec_prefix, &target_path);
+
+  /* Add path as a last resort.  */
+  prefix_from_env ("PATH", &path);
+}
+
 int 
-main(int ac, char **av)
+main (int ac, char **av)
 {
-  const char *nprefix;
   const char *exe_name;
+#if HAVE_LTO_PLUGIN > 0
   char *plugin;
+#endif
   int k, status, err;
   const char *err_msg;
   const char **nargv;
   bool is_ar = !strcmp (PERSONALITY, "ar");
+  int exit_code = FATAL_EXIT_CODE;
+  int i;
 
-  exe_name = PERSONALITY;
-#ifdef CROSS_DIRECTORY_STRUCTURE
-  exe_name = concat (target_machine, "-", exe_name, NULL);
-#endif
+  setup_prefixes (av[0]);
+
+  /* Not using getopt for now.  */
+  for (i = 0; i < ac; i++)
+      if (!strncmp (av[i], "-B", 2))
+       {
+         const char *arg = av[i] + 2;
+         const char *end;
+         size_t len;
+
+         memmove (av + i, av + i + 1, sizeof (char *) * ((ac + 1) - i));
+         ac--;
+         if (*arg == 0)
+           {
+             arg = av[i];
+             if (!arg)
+               {
+                 fprintf (stderr, "Usage: gcc-ar [-B prefix] ar arguments ...\n");
+                 exit (EXIT_FAILURE);
+               }
+             memmove (av + i, av + i + 1, sizeof (char *) * ((ac + 1) - i));
+             ac--;
+             i++;
+           }
+         /* else it's a joined argument  */
+
+         len = strlen (arg);
+         if (len > 0)
+           len--;
+         end = arg + len;
 
-  /* Find plugin */
-  /* XXX implement more magic from gcc.c? */
-  nprefix = getenv ("GCC_EXEC_PREFIX");
-  if (!nprefix)
-    nprefix = standard_libexec_prefix;
-
-  nprefix = make_relative_prefix (av[0], 
-                                 standard_bin_prefix, 
-                                 nprefix);
-  plugin = concat (nprefix,
-                  dir_separator,
-                   DEFAULT_TARGET_MACHINE, 
-                  dir_separator,
-                  DEFAULT_TARGET_VERSION,
-                  dir_separator,
-                  LTOPLUGINSONAME,
-                  NULL);
-  if (access (plugin, X_OK))
+         /* Always add a dir separator for the prefix list.  */
+         if (end > arg && !IS_DIR_SEPARATOR (*end))
+           {
+             static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
+             arg = concat (arg, dir_separator_str, NULL);
+           }
+
+         add_prefix_begin (&path, arg);
+         add_prefix_begin (&target_path, arg);
+         break;
+       }
+
+#if HAVE_LTO_PLUGIN > 0
+  /* Find the GCC LTO plugin */
+  plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK);
+  if (!plugin)
     {
-      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
+      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
       exit (1);
     }
+#endif
 
-  /* Create new command line with plugin */
+  /* Find the wrapped binutils program.  */
+  exe_name = find_a_file (&target_path, PERSONALITY, X_OK);
+  if (!exe_name)
+    {
+      const char *real_exe_name = PERSONALITY;
+#ifdef CROSS_DIRECTORY_STRUCTURE
+      real_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
+#endif
+      exe_name = find_a_file (&path, real_exe_name, X_OK);
+      if (!exe_name)
+       {
+         fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
+                  real_exe_name);
+         exit (1);
+       }
+    }
+
+  /* Create new command line with plugin - if we have one, otherwise just
+     copy the command through.  */
   nargv = XCNEWVEC (const char *, ac + 4);
   nargv[0] = exe_name;
+#if HAVE_LTO_PLUGIN > 0
   nargv[1] = "--plugin";
   nargv[2] = plugin;
   if (is_ar && av[1] && av[1][0] != '-')
-    av[1] = concat("-", av[1], NULL);
+    av[1] = concat ("-", av[1], NULL);
   for (k = 1; k < ac; k++)
     nargv[2 + k] = av[k];
   nargv[2 + k] = NULL;
+#else
+  if (is_ar && av[1] && av[1][0] != '-')
+    av[1] = concat ("-", av[1], NULL);
+  for (k = 1; k < ac; k++)
+    nargv[k] = av[k];
+  nargv[k] = NULL;
+#endif
 
   /* Run utility */
   /* ??? the const is misplaced in pex_one's argv? */
   err_msg = pex_one (PEX_LAST|PEX_SEARCH, 
                     exe_name, 
                     CONST_CAST2 (char * const *, const char **, nargv),
-                    concat("gcc-", exe_name, NULL), 
+                    concat ("gcc-", exe_name, NULL),
                     NULL,NULL,  &status, &err);
   if (err_msg) 
-    fprintf(stderr, "Error running %s: %s\n", exe_name, err_msg);
+    fprintf (stderr, "Error running %s: %s\n", exe_name, err_msg);
+  else if (status)
+    {
+      if (WIFSIGNALED (status))
+       {
+         int sig = WTERMSIG (status);
+         fprintf (stderr, "%s terminated with signal %d [%s]%s\n",
+                  exe_name, sig, strsignal (sig),
+                  WCOREDUMP (status) ? ", core dumped" : "");
+       }
+      else if (WIFEXITED (status))
+       exit_code = WEXITSTATUS (status);
+    }
+  else
+    exit_code = SUCCESS_EXIT_CODE;
 
-  return err;
+  return exit_code;
 }