public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
@ 2012-10-04 20:46 Meador Inge
  2012-10-10  2:47 ` Meador Inge
  0 siblings, 1 reply; 16+ messages in thread
From: Meador Inge @ 2012-10-04 20:46 UTC (permalink / raw)
  To: gcc-patches

Hi All,

Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
path when invoking the wrapped binutils program.  This goes against the
accepted practice in GCC to find sub-programs relative to where the
GCC binaries are stored and to not make assumptions about the PATH.

This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
by factoring out some utility code for finding files from collect2.c.
These functions are then leveraged to find the binutils programs.
Note that similar code exist in gcc.c.  Perhaps one day everything
can be merged to the file-find files.

Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
arm-none-eabi targets.  OK?

P.S. I am not quite sure what is best for the copyrights and contributed
by comments in the file-find* files I added since that code was just moved.
This patch drops the contributed by and keeps all the copyright dates from
collect2.c.

2012-10-04  Meador Inge  <meadori@codesourcery.com>

	* collect2.c (main): Call find_file_set_debug.
	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
	Factor out into ...
	* file-find.c (New file): ... here and ...
	* file-find.h (New file): ... here.
	* gcc-ar.c (standard_exec_prefix): New variable.
	(standard_libexec_prefix): Ditto.
	(tooldir_base_prefix) Ditto.
	(self_exec_prefix): Ditto.
	(self_libexec_prefix): Ditto.
	(self_tooldir_prefix): Ditto.
	(target_version): Ditto.
	(path): Ditto.
	(target_path): Ditto.
	(setup_prefixes): New function.
	(main): Rework how wrapped programs are found.
	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
	(AR_OBJS): New variable.
	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
	(gcc-nm$(exeext)): Ditto.
	(gcc-ranlib(exeext)): Ditto.
	(COLLECT2_OBJS): Add file-find.o.
	(collect2.o): Add file-find.h prerequisite.
	(file-find.o): New rule.

Index: gcc/gcc-ar.c
===================================================================
--- gcc/gcc-ar.c	(revision 192099)
+++ gcc/gcc-ar.c	(working copy)
@@ -21,21 +21,110 @@
 #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;
-static const char *const target_machine = TARGET_MACHINE;
 
+/* 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)
 {
-  const char *nprefix;
   const char *exe_name;
   char *plugin;
   int k, status, err;
@@ -44,37 +133,35 @@
   bool is_ar = !strcmp (PERSONALITY, "ar");
   int exit_code = FATAL_EXIT_CODE;
 
-  exe_name = PERSONALITY;
-#ifdef CROSS_DIRECTORY_STRUCTURE
-  exe_name = concat (target_machine, "-", exe_name, NULL);
-#endif
+  setup_prefixes (av[0]);
 
-  /* Find plugin */
-  /* XXX implement more magic from gcc.c? */
-  nprefix = getenv ("GCC_EXEC_PREFIX");
-  if (!nprefix)
-    nprefix = av[0];
-  else
-    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
+  /* Find the GCC LTO plugin */
+  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
+  if (!plugin)
+    {
+      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
+      exit (1);
+    }
 
-  nprefix = make_relative_prefix (nprefix,
-				  standard_bin_prefix,
-				  standard_libexec_prefix);
-  if (nprefix == NULL)
-    nprefix = standard_libexec_prefix;
+  /* Find the wrapped binutils program.  */
+  exe_name = find_a_file (&target_path, PERSONALITY);
+  if (!exe_name)
+    {
+#ifdef CROSS_DIRECTORY_STRUCTURE
+      const char *cross_exe_name;
 
-  plugin = concat (nprefix,
-		   dir_separator,
-                   DEFAULT_TARGET_MACHINE, 
-		   dir_separator,
-		   DEFAULT_TARGET_VERSION,
-	           dir_separator,
-		   LTOPLUGINSONAME,
-		   NULL);
-  if (access (plugin, R_OK))
-    {
-      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
+      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
+      exe_name = find_a_file (&path, cross_exe_name);
+      if (!exe_name)
+	{
+	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
+		   cross_exe_name);
+	  exit (1);
+	}
+#else
+      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
       exit (1);
+#endif
     }
 
   /* Create new command line with plugin */
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 192099)
+++ gcc/Makefile.in	(working copy)
@@ -1446,7 +1446,7 @@
 # compiler and containing target-dependent code.
 OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
 	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
-	hash-table.o
+	hash-table.o file-find.o
 
 # This lists all host objects for the front ends.
 ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
@@ -1827,19 +1827,20 @@
 ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
 sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
 
+AR_OBJS = file-find.o
 AR_LIBS = @COLLECT2_LIBS@
 
-gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
+gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
-		$(LIBS) $(AR_LIBS)
+		$(AR_OBJS) $(LIBS) $(AR_LIBS)
 
-gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
+gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
-		$(LIBS) $(AR_LIBS)
+		$(AR_OBJS) $(LIBS) $(AR_LIBS)
 
-gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
+gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
-		$(LIBS) $(AR_LIBS)
+		$(AR_OBJS) $(LIBS) $(AR_LIBS)
 
 CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
 	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
@@ -1867,7 +1868,7 @@
 gcc-nm.c: gcc-ar.c
 	cp $^ $@
 
-COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
+COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
 COLLECT2_LIBS = @COLLECT2_LIBS@
 collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 # Don't try modifying collect2 (aka ld) in place--it might be linking this.
@@ -1879,7 +1880,7 @@
 	@TARGET_SYSTEM_ROOT_DEFINE@
 collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
 	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
-	$(DIAGNOSTIC_H)
+	$(DIAGNOSTIC_H) file-find.h
 
 collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     collect2-aix.h
@@ -3353,6 +3354,7 @@
    $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
    $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
    $(REGS_H) hw-doloop.h
+file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
 $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
    $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
    output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
Index: gcc/file-find.c
===================================================================
--- gcc/file-find.c	(revision 0)
+++ gcc/file-find.c	(revision 0)
@@ -0,0 +1,194 @@
+/* Utility functions for finding files relative to GCC binaries.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+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 "config.h"
+#include "system.h"
+#include "filenames.h"
+#include "file-find.h"
+
+static bool debug = false;
+
+void
+find_file_set_debug(bool debug_state)
+{
+  debug = debug_state;
+}
+
+char *
+find_a_file (struct path_prefix *pprefix, const char *name)
+{
+  char *temp;
+  struct prefix_list *pl;
+  int len = pprefix->max_len + strlen (name) + 1;
+
+  if (debug)
+    fprintf (stderr, "Looking for '%s'\n", name);
+
+#ifdef HOST_EXECUTABLE_SUFFIX
+  len += strlen (HOST_EXECUTABLE_SUFFIX);
+#endif
+
+  temp = XNEWVEC (char, len);
+
+  /* Determine the filename to execute (special case for absolute paths).  */
+
+  if (IS_ABSOLUTE_PATH (name))
+    {
+      if (access (name, X_OK) == 0)
+	{
+	  strcpy (temp, name);
+
+	  if (debug)
+	    fprintf (stderr, "  - found: absolute path\n");
+
+	  return temp;
+	}
+
+#ifdef HOST_EXECUTABLE_SUFFIX
+	/* Some systems have a suffix for executable files.
+	   So try appending that.  */
+      strcpy (temp, name);
+	strcat (temp, HOST_EXECUTABLE_SUFFIX);
+
+	if (access (temp, X_OK) == 0)
+	  return temp;
+#endif
+
+      if (debug)
+	fprintf (stderr, "  - failed to locate using absolute path\n");
+    }
+  else
+    for (pl = pprefix->plist; pl; pl = pl->next)
+      {
+	struct stat st;
+
+	strcpy (temp, pl->prefix);
+	strcat (temp, name);
+
+	if (stat (temp, &st) >= 0
+	    && ! S_ISDIR (st.st_mode)
+	    && access (temp, X_OK) == 0)
+	  return temp;
+
+#ifdef HOST_EXECUTABLE_SUFFIX
+	/* Some systems have a suffix for executable files.
+	   So try appending that.  */
+	strcat (temp, HOST_EXECUTABLE_SUFFIX);
+
+	if (stat (temp, &st) >= 0
+	    && ! S_ISDIR (st.st_mode)
+	    && access (temp, X_OK) == 0)
+	  return temp;
+#endif
+      }
+
+  if (debug && pprefix->plist == NULL)
+    fprintf (stderr, "  - failed: no entries in prefix list\n");
+
+  free (temp);
+  return 0;
+}
+
+/* Add an entry for PREFIX to prefix list PPREFIX.  */
+
+void
+add_prefix (struct path_prefix *pprefix, const char *prefix)
+{
+  struct prefix_list *pl, **prev;
+  int len;
+
+  if (pprefix->plist)
+    {
+      for (pl = pprefix->plist; pl->next; pl = pl->next)
+	;
+      prev = &pl->next;
+    }
+  else
+    prev = &pprefix->plist;
+
+  /* Keep track of the longest prefix.  */
+
+  len = strlen (prefix);
+  if (len > pprefix->max_len)
+    pprefix->max_len = len;
+
+  pl = XNEW (struct prefix_list);
+  pl->prefix = xstrdup (prefix);
+
+  if (*prev)
+    pl->next = *prev;
+  else
+    pl->next = (struct prefix_list *) 0;
+  *prev = pl;
+}
+
+/* Take the value of the environment variable ENV, break it into a path, and
+   add of the entries to PPREFIX.  */
+
+void
+prefix_from_env (const char *env, struct path_prefix *pprefix)
+{
+  const char *p;
+  p = getenv (env);
+
+  if (p)
+    prefix_from_string (p, pprefix);
+}
+
+void
+prefix_from_string (const char *p, struct path_prefix *pprefix)
+{
+  const char *startp, *endp;
+  char *nstore = XNEWVEC (char, strlen (p) + 3);
+
+  if (debug)
+    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
+
+  startp = endp = p;
+  while (1)
+    {
+      if (*endp == PATH_SEPARATOR || *endp == 0)
+	{
+	  strncpy (nstore, startp, endp-startp);
+	  if (endp == startp)
+	    {
+	      strcpy (nstore, "./");
+	    }
+	  else if (! IS_DIR_SEPARATOR (endp[-1]))
+	    {
+	      nstore[endp-startp] = DIR_SEPARATOR;
+	      nstore[endp-startp+1] = 0;
+	    }
+	  else
+	    nstore[endp-startp] = 0;
+
+	  if (debug)
+	    fprintf (stderr, "  - add prefix: %s\n", nstore);
+
+	  add_prefix (pprefix, nstore);
+	  if (*endp == 0)
+	    break;
+	  endp = startp = endp + 1;
+	}
+      else
+	endp++;
+    }
+  free (nstore);
+}
Index: gcc/file-find.h
===================================================================
--- gcc/file-find.h	(revision 0)
+++ gcc/file-find.h	(revision 0)
@@ -0,0 +1,47 @@
+/* Prototypes and data structures used for implementing functions for
+   finding files relative to GCC binaries.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+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/>.  */
+
+#ifndef GCC_FILE_FIND_H
+#define GCC_FILE_FIND_H
+
+/* Structure to hold all the directories in which to search for files to
+   execute.  */
+
+struct prefix_list
+{
+  const char *prefix;         /* String to prepend to the path.  */
+  struct prefix_list *next;   /* Next in linked list.  */
+};
+
+struct path_prefix
+{
+  struct prefix_list *plist;  /* List of prefixes to try */
+  int max_len;                /* Max length of a prefix in PLIST */
+  const char *name;           /* Name of this list (used in config stuff) */
+};
+
+extern void find_file_set_debug (bool);
+extern char *find_a_file (struct path_prefix *, const char *);
+extern void add_prefix (struct path_prefix *, const char *);
+extern void prefix_from_env (const char *, struct path_prefix *);
+extern void prefix_from_string (const char *, struct path_prefix *);
+
+#endif /* GCC_FILE_FIND_H */
Index: gcc/collect2.c
===================================================================
--- gcc/collect2.c	(revision 192099)
+++ gcc/collect2.c	(working copy)
@@ -31,6 +31,7 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "filenames.h"
+#include "file-find.h"
 
 /* TARGET_64BIT may be defined to use driver specific functionality. */
 #undef TARGET_64BIT
@@ -243,22 +244,6 @@
    would leave untouched.  */
 bool may_unlink_output_file = false;
 
-/* Structure to hold all the directories in which to search for files to
-   execute.  */
-
-struct prefix_list
-{
-  const char *prefix;         /* String to prepend to the path.  */
-  struct prefix_list *next;   /* Next in linked list.  */
-};
-
-struct path_prefix
-{
-  struct prefix_list *plist;  /* List of prefixes to try */
-  int max_len;                /* Max length of a prefix in PLIST */
-  const char *name;           /* Name of this list (used in config stuff) */
-};
-
 #ifdef COLLECT_EXPORT_LIST
 /* Lists to keep libraries to be scanned for global constructors/destructors.  */
 static struct head libs;                    /* list of libraries */
@@ -302,10 +287,6 @@
 static symkind is_ctor_dtor (const char *);
 
 static void handler (int);
-static char *find_a_file (struct path_prefix *, const char *);
-static void add_prefix (struct path_prefix *, const char *);
-static void prefix_from_env (const char *, struct path_prefix *);
-static void prefix_from_string (const char *, struct path_prefix *);
 static void do_wait (const char *, struct pex_obj *);
 static void fork_execute (const char *, char **);
 static void maybe_unlink (const char *);
@@ -653,168 +634,6 @@
 
    Return 0 if not found, otherwise return its name, allocated with malloc.  */
 
-static char *
-find_a_file (struct path_prefix *pprefix, const char *name)
-{
-  char *temp;
-  struct prefix_list *pl;
-  int len = pprefix->max_len + strlen (name) + 1;
-
-  if (debug)
-    fprintf (stderr, "Looking for '%s'\n", name);
-
-#ifdef HOST_EXECUTABLE_SUFFIX
-  len += strlen (HOST_EXECUTABLE_SUFFIX);
-#endif
-
-  temp = XNEWVEC (char, len);
-
-  /* Determine the filename to execute (special case for absolute paths).  */
-
-  if (IS_ABSOLUTE_PATH (name))
-    {
-      if (access (name, X_OK) == 0)
-	{
-	  strcpy (temp, name);
-
-	  if (debug)
-	    fprintf (stderr, "  - found: absolute path\n");
-
-	  return temp;
-	}
-
-#ifdef HOST_EXECUTABLE_SUFFIX
-	/* Some systems have a suffix for executable files.
-	   So try appending that.  */
-      strcpy (temp, name);
-	strcat (temp, HOST_EXECUTABLE_SUFFIX);
-
-	if (access (temp, X_OK) == 0)
-	  return temp;
-#endif
-
-      if (debug)
-	fprintf (stderr, "  - failed to locate using absolute path\n");
-    }
-  else
-    for (pl = pprefix->plist; pl; pl = pl->next)
-      {
-	struct stat st;
-
-	strcpy (temp, pl->prefix);
-	strcat (temp, name);
-
-	if (stat (temp, &st) >= 0
-	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
-	  return temp;
-
-#ifdef HOST_EXECUTABLE_SUFFIX
-	/* Some systems have a suffix for executable files.
-	   So try appending that.  */
-	strcat (temp, HOST_EXECUTABLE_SUFFIX);
-
-	if (stat (temp, &st) >= 0
-	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
-	  return temp;
-#endif
-      }
-
-  if (debug && pprefix->plist == NULL)
-    fprintf (stderr, "  - failed: no entries in prefix list\n");
-
-  free (temp);
-  return 0;
-}
-
-/* Add an entry for PREFIX to prefix list PPREFIX.  */
-
-static void
-add_prefix (struct path_prefix *pprefix, const char *prefix)
-{
-  struct prefix_list *pl, **prev;
-  int len;
-
-  if (pprefix->plist)
-    {
-      for (pl = pprefix->plist; pl->next; pl = pl->next)
-	;
-      prev = &pl->next;
-    }
-  else
-    prev = &pprefix->plist;
-
-  /* Keep track of the longest prefix.  */
-
-  len = strlen (prefix);
-  if (len > pprefix->max_len)
-    pprefix->max_len = len;
-
-  pl = XNEW (struct prefix_list);
-  pl->prefix = xstrdup (prefix);
-
-  if (*prev)
-    pl->next = *prev;
-  else
-    pl->next = (struct prefix_list *) 0;
-  *prev = pl;
-}
-\f
-/* Take the value of the environment variable ENV, break it into a path, and
-   add of the entries to PPREFIX.  */
-
-static void
-prefix_from_env (const char *env, struct path_prefix *pprefix)
-{
-  const char *p;
-  p = getenv (env);
-
-  if (p)
-    prefix_from_string (p, pprefix);
-}
-
-static void
-prefix_from_string (const char *p, struct path_prefix *pprefix)
-{
-  const char *startp, *endp;
-  char *nstore = XNEWVEC (char, strlen (p) + 3);
-
-  if (debug)
-    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
-
-  startp = endp = p;
-  while (1)
-    {
-      if (*endp == PATH_SEPARATOR || *endp == 0)
-	{
-	  strncpy (nstore, startp, endp-startp);
-	  if (endp == startp)
-	    {
-	      strcpy (nstore, "./");
-	    }
-	  else if (! IS_DIR_SEPARATOR (endp[-1]))
-	    {
-	      nstore[endp-startp] = DIR_SEPARATOR;
-	      nstore[endp-startp+1] = 0;
-	    }
-	  else
-	    nstore[endp-startp] = 0;
-
-	  if (debug)
-	    fprintf (stderr, "  - add prefix: %s\n", nstore);
-
-	  add_prefix (pprefix, nstore);
-	  if (*endp == 0)
-	    break;
-	  endp = startp = endp + 1;
-	}
-      else
-	endp++;
-    }
-  free (nstore);
-}
-
 #ifdef OBJECT_FORMAT_NONE
 
 /* Add an entry for the object file NAME to object file list LIST.
@@ -1198,6 +1017,7 @@
 #endif
       }
     vflag = debug;
+    find_file_set_debug (debug);
     if (no_partition && lto_mode == LTO_MODE_WHOPR)
       lto_mode = LTO_MODE_LTO;
   }

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-04 20:46 [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self Meador Inge
@ 2012-10-10  2:47 ` Meador Inge
  2012-10-18 15:39   ` Meador Inge
  0 siblings, 1 reply; 16+ messages in thread
From: Meador Inge @ 2012-10-10  2:47 UTC (permalink / raw)
  To: gcc-patches

Ping.

On 10/04/2012 03:45 PM, Meador Inge wrote:
> Hi All,
> 
> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
> path when invoking the wrapped binutils program.  This goes against the
> accepted practice in GCC to find sub-programs relative to where the
> GCC binaries are stored and to not make assumptions about the PATH.
> 
> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
> by factoring out some utility code for finding files from collect2.c.
> These functions are then leveraged to find the binutils programs.
> Note that similar code exist in gcc.c.  Perhaps one day everything
> can be merged to the file-find files.
> 
> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
> arm-none-eabi targets.  OK?
> 
> P.S. I am not quite sure what is best for the copyrights and contributed
> by comments in the file-find* files I added since that code was just moved.
> This patch drops the contributed by and keeps all the copyright dates from
> collect2.c.
> 
> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
> 
> 	* collect2.c (main): Call find_file_set_debug.
> 	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
> 	Factor out into ...
> 	* file-find.c (New file): ... here and ...
> 	* file-find.h (New file): ... here.
> 	* gcc-ar.c (standard_exec_prefix): New variable.
> 	(standard_libexec_prefix): Ditto.
> 	(tooldir_base_prefix) Ditto.
> 	(self_exec_prefix): Ditto.
> 	(self_libexec_prefix): Ditto.
> 	(self_tooldir_prefix): Ditto.
> 	(target_version): Ditto.
> 	(path): Ditto.
> 	(target_path): Ditto.
> 	(setup_prefixes): New function.
> 	(main): Rework how wrapped programs are found.
> 	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
> 	(AR_OBJS): New variable.
> 	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
> 	(gcc-nm$(exeext)): Ditto.
> 	(gcc-ranlib(exeext)): Ditto.
> 	(COLLECT2_OBJS): Add file-find.o.
> 	(collect2.o): Add file-find.h prerequisite.
> 	(file-find.o): New rule.
> 
> Index: gcc/gcc-ar.c
> ===================================================================
> --- gcc/gcc-ar.c	(revision 192099)
> +++ gcc/gcc-ar.c	(working copy)
> @@ -21,21 +21,110 @@
>  #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;
> -static const char *const target_machine = TARGET_MACHINE;
>  
> +/* 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)
>  {
> -  const char *nprefix;
>    const char *exe_name;
>    char *plugin;
>    int k, status, err;
> @@ -44,37 +133,35 @@
>    bool is_ar = !strcmp (PERSONALITY, "ar");
>    int exit_code = FATAL_EXIT_CODE;
>  
> -  exe_name = PERSONALITY;
> -#ifdef CROSS_DIRECTORY_STRUCTURE
> -  exe_name = concat (target_machine, "-", exe_name, NULL);
> -#endif
> +  setup_prefixes (av[0]);
>  
> -  /* Find plugin */
> -  /* XXX implement more magic from gcc.c? */
> -  nprefix = getenv ("GCC_EXEC_PREFIX");
> -  if (!nprefix)
> -    nprefix = av[0];
> -  else
> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
> +  /* Find the GCC LTO plugin */
> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
> +  if (!plugin)
> +    {
> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
> +      exit (1);
> +    }
>  
> -  nprefix = make_relative_prefix (nprefix,
> -				  standard_bin_prefix,
> -				  standard_libexec_prefix);
> -  if (nprefix == NULL)
> -    nprefix = standard_libexec_prefix;
> +  /* Find the wrapped binutils program.  */
> +  exe_name = find_a_file (&target_path, PERSONALITY);
> +  if (!exe_name)
> +    {
> +#ifdef CROSS_DIRECTORY_STRUCTURE
> +      const char *cross_exe_name;
>  
> -  plugin = concat (nprefix,
> -		   dir_separator,
> -                   DEFAULT_TARGET_MACHINE, 
> -		   dir_separator,
> -		   DEFAULT_TARGET_VERSION,
> -	           dir_separator,
> -		   LTOPLUGINSONAME,
> -		   NULL);
> -  if (access (plugin, R_OK))
> -    {
> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
> +      exe_name = find_a_file (&path, cross_exe_name);
> +      if (!exe_name)
> +	{
> +	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
> +		   cross_exe_name);
> +	  exit (1);
> +	}
> +#else
> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>        exit (1);
> +#endif
>      }
>  
>    /* Create new command line with plugin */
> Index: gcc/Makefile.in
> ===================================================================
> --- gcc/Makefile.in	(revision 192099)
> +++ gcc/Makefile.in	(working copy)
> @@ -1446,7 +1446,7 @@
>  # compiler and containing target-dependent code.
>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>  	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
> -	hash-table.o
> +	hash-table.o file-find.o
>  
>  # This lists all host objects for the front ends.
>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
> @@ -1827,19 +1827,20 @@
>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>  
> +AR_OBJS = file-find.o
>  AR_LIBS = @COLLECT2_LIBS@
>  
> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
> -		$(LIBS) $(AR_LIBS)
> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>  
> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
> -		$(LIBS) $(AR_LIBS)
> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>  
> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
> -		$(LIBS) $(AR_LIBS)
> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>  
>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>  	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
> @@ -1867,7 +1868,7 @@
>  gcc-nm.c: gcc-ar.c
>  	cp $^ $@
>  
> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>  COLLECT2_LIBS = @COLLECT2_LIBS@
>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
> @@ -1879,7 +1880,7 @@
>  	@TARGET_SYSTEM_ROOT_DEFINE@
>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>  	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
> -	$(DIAGNOSTIC_H)
> +	$(DIAGNOSTIC_H) file-find.h
>  
>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>      collect2-aix.h
> @@ -3353,6 +3354,7 @@
>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>     $(REGS_H) hw-doloop.h
> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
> Index: gcc/file-find.c
> ===================================================================
> --- gcc/file-find.c	(revision 0)
> +++ gcc/file-find.c	(revision 0)
> @@ -0,0 +1,194 @@
> +/* Utility functions for finding files relative to GCC binaries.
> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +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 "config.h"
> +#include "system.h"
> +#include "filenames.h"
> +#include "file-find.h"
> +
> +static bool debug = false;
> +
> +void
> +find_file_set_debug(bool debug_state)
> +{
> +  debug = debug_state;
> +}
> +
> +char *
> +find_a_file (struct path_prefix *pprefix, const char *name)
> +{
> +  char *temp;
> +  struct prefix_list *pl;
> +  int len = pprefix->max_len + strlen (name) + 1;
> +
> +  if (debug)
> +    fprintf (stderr, "Looking for '%s'\n", name);
> +
> +#ifdef HOST_EXECUTABLE_SUFFIX
> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
> +#endif
> +
> +  temp = XNEWVEC (char, len);
> +
> +  /* Determine the filename to execute (special case for absolute paths).  */
> +
> +  if (IS_ABSOLUTE_PATH (name))
> +    {
> +      if (access (name, X_OK) == 0)
> +	{
> +	  strcpy (temp, name);
> +
> +	  if (debug)
> +	    fprintf (stderr, "  - found: absolute path\n");
> +
> +	  return temp;
> +	}
> +
> +#ifdef HOST_EXECUTABLE_SUFFIX
> +	/* Some systems have a suffix for executable files.
> +	   So try appending that.  */
> +      strcpy (temp, name);
> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
> +
> +	if (access (temp, X_OK) == 0)
> +	  return temp;
> +#endif
> +
> +      if (debug)
> +	fprintf (stderr, "  - failed to locate using absolute path\n");
> +    }
> +  else
> +    for (pl = pprefix->plist; pl; pl = pl->next)
> +      {
> +	struct stat st;
> +
> +	strcpy (temp, pl->prefix);
> +	strcat (temp, name);
> +
> +	if (stat (temp, &st) >= 0
> +	    && ! S_ISDIR (st.st_mode)
> +	    && access (temp, X_OK) == 0)
> +	  return temp;
> +
> +#ifdef HOST_EXECUTABLE_SUFFIX
> +	/* Some systems have a suffix for executable files.
> +	   So try appending that.  */
> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
> +
> +	if (stat (temp, &st) >= 0
> +	    && ! S_ISDIR (st.st_mode)
> +	    && access (temp, X_OK) == 0)
> +	  return temp;
> +#endif
> +      }
> +
> +  if (debug && pprefix->plist == NULL)
> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
> +
> +  free (temp);
> +  return 0;
> +}
> +
> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
> +
> +void
> +add_prefix (struct path_prefix *pprefix, const char *prefix)
> +{
> +  struct prefix_list *pl, **prev;
> +  int len;
> +
> +  if (pprefix->plist)
> +    {
> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
> +	;
> +      prev = &pl->next;
> +    }
> +  else
> +    prev = &pprefix->plist;
> +
> +  /* Keep track of the longest prefix.  */
> +
> +  len = strlen (prefix);
> +  if (len > pprefix->max_len)
> +    pprefix->max_len = len;
> +
> +  pl = XNEW (struct prefix_list);
> +  pl->prefix = xstrdup (prefix);
> +
> +  if (*prev)
> +    pl->next = *prev;
> +  else
> +    pl->next = (struct prefix_list *) 0;
> +  *prev = pl;
> +}
> +
> +/* Take the value of the environment variable ENV, break it into a path, and
> +   add of the entries to PPREFIX.  */
> +
> +void
> +prefix_from_env (const char *env, struct path_prefix *pprefix)
> +{
> +  const char *p;
> +  p = getenv (env);
> +
> +  if (p)
> +    prefix_from_string (p, pprefix);
> +}
> +
> +void
> +prefix_from_string (const char *p, struct path_prefix *pprefix)
> +{
> +  const char *startp, *endp;
> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
> +
> +  if (debug)
> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
> +
> +  startp = endp = p;
> +  while (1)
> +    {
> +      if (*endp == PATH_SEPARATOR || *endp == 0)
> +	{
> +	  strncpy (nstore, startp, endp-startp);
> +	  if (endp == startp)
> +	    {
> +	      strcpy (nstore, "./");
> +	    }
> +	  else if (! IS_DIR_SEPARATOR (endp[-1]))
> +	    {
> +	      nstore[endp-startp] = DIR_SEPARATOR;
> +	      nstore[endp-startp+1] = 0;
> +	    }
> +	  else
> +	    nstore[endp-startp] = 0;
> +
> +	  if (debug)
> +	    fprintf (stderr, "  - add prefix: %s\n", nstore);
> +
> +	  add_prefix (pprefix, nstore);
> +	  if (*endp == 0)
> +	    break;
> +	  endp = startp = endp + 1;
> +	}
> +      else
> +	endp++;
> +    }
> +  free (nstore);
> +}
> Index: gcc/file-find.h
> ===================================================================
> --- gcc/file-find.h	(revision 0)
> +++ gcc/file-find.h	(revision 0)
> @@ -0,0 +1,47 @@
> +/* Prototypes and data structures used for implementing functions for
> +   finding files relative to GCC binaries.
> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +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/>.  */
> +
> +#ifndef GCC_FILE_FIND_H
> +#define GCC_FILE_FIND_H
> +
> +/* Structure to hold all the directories in which to search for files to
> +   execute.  */
> +
> +struct prefix_list
> +{
> +  const char *prefix;         /* String to prepend to the path.  */
> +  struct prefix_list *next;   /* Next in linked list.  */
> +};
> +
> +struct path_prefix
> +{
> +  struct prefix_list *plist;  /* List of prefixes to try */
> +  int max_len;                /* Max length of a prefix in PLIST */
> +  const char *name;           /* Name of this list (used in config stuff) */
> +};
> +
> +extern void find_file_set_debug (bool);
> +extern char *find_a_file (struct path_prefix *, const char *);
> +extern void add_prefix (struct path_prefix *, const char *);
> +extern void prefix_from_env (const char *, struct path_prefix *);
> +extern void prefix_from_string (const char *, struct path_prefix *);
> +
> +#endif /* GCC_FILE_FIND_H */
> Index: gcc/collect2.c
> ===================================================================
> --- gcc/collect2.c	(revision 192099)
> +++ gcc/collect2.c	(working copy)
> @@ -31,6 +31,7 @@
>  #include "coretypes.h"
>  #include "tm.h"
>  #include "filenames.h"
> +#include "file-find.h"
>  
>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>  #undef TARGET_64BIT
> @@ -243,22 +244,6 @@
>     would leave untouched.  */
>  bool may_unlink_output_file = false;
>  
> -/* Structure to hold all the directories in which to search for files to
> -   execute.  */
> -
> -struct prefix_list
> -{
> -  const char *prefix;         /* String to prepend to the path.  */
> -  struct prefix_list *next;   /* Next in linked list.  */
> -};
> -
> -struct path_prefix
> -{
> -  struct prefix_list *plist;  /* List of prefixes to try */
> -  int max_len;                /* Max length of a prefix in PLIST */
> -  const char *name;           /* Name of this list (used in config stuff) */
> -};
> -
>  #ifdef COLLECT_EXPORT_LIST
>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>  static struct head libs;                    /* list of libraries */
> @@ -302,10 +287,6 @@
>  static symkind is_ctor_dtor (const char *);
>  
>  static void handler (int);
> -static char *find_a_file (struct path_prefix *, const char *);
> -static void add_prefix (struct path_prefix *, const char *);
> -static void prefix_from_env (const char *, struct path_prefix *);
> -static void prefix_from_string (const char *, struct path_prefix *);
>  static void do_wait (const char *, struct pex_obj *);
>  static void fork_execute (const char *, char **);
>  static void maybe_unlink (const char *);
> @@ -653,168 +634,6 @@
>  
>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>  
> -static char *
> -find_a_file (struct path_prefix *pprefix, const char *name)
> -{
> -  char *temp;
> -  struct prefix_list *pl;
> -  int len = pprefix->max_len + strlen (name) + 1;
> -
> -  if (debug)
> -    fprintf (stderr, "Looking for '%s'\n", name);
> -
> -#ifdef HOST_EXECUTABLE_SUFFIX
> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
> -#endif
> -
> -  temp = XNEWVEC (char, len);
> -
> -  /* Determine the filename to execute (special case for absolute paths).  */
> -
> -  if (IS_ABSOLUTE_PATH (name))
> -    {
> -      if (access (name, X_OK) == 0)
> -	{
> -	  strcpy (temp, name);
> -
> -	  if (debug)
> -	    fprintf (stderr, "  - found: absolute path\n");
> -
> -	  return temp;
> -	}
> -
> -#ifdef HOST_EXECUTABLE_SUFFIX
> -	/* Some systems have a suffix for executable files.
> -	   So try appending that.  */
> -      strcpy (temp, name);
> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
> -
> -	if (access (temp, X_OK) == 0)
> -	  return temp;
> -#endif
> -
> -      if (debug)
> -	fprintf (stderr, "  - failed to locate using absolute path\n");
> -    }
> -  else
> -    for (pl = pprefix->plist; pl; pl = pl->next)
> -      {
> -	struct stat st;
> -
> -	strcpy (temp, pl->prefix);
> -	strcat (temp, name);
> -
> -	if (stat (temp, &st) >= 0
> -	    && ! S_ISDIR (st.st_mode)
> -	    && access (temp, X_OK) == 0)
> -	  return temp;
> -
> -#ifdef HOST_EXECUTABLE_SUFFIX
> -	/* Some systems have a suffix for executable files.
> -	   So try appending that.  */
> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
> -
> -	if (stat (temp, &st) >= 0
> -	    && ! S_ISDIR (st.st_mode)
> -	    && access (temp, X_OK) == 0)
> -	  return temp;
> -#endif
> -      }
> -
> -  if (debug && pprefix->plist == NULL)
> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
> -
> -  free (temp);
> -  return 0;
> -}
> -
> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
> -
> -static void
> -add_prefix (struct path_prefix *pprefix, const char *prefix)
> -{
> -  struct prefix_list *pl, **prev;
> -  int len;
> -
> -  if (pprefix->plist)
> -    {
> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
> -	;
> -      prev = &pl->next;
> -    }
> -  else
> -    prev = &pprefix->plist;
> -
> -  /* Keep track of the longest prefix.  */
> -
> -  len = strlen (prefix);
> -  if (len > pprefix->max_len)
> -    pprefix->max_len = len;
> -
> -  pl = XNEW (struct prefix_list);
> -  pl->prefix = xstrdup (prefix);
> -
> -  if (*prev)
> -    pl->next = *prev;
> -  else
> -    pl->next = (struct prefix_list *) 0;
> -  *prev = pl;
> -}
> -\f
> -/* Take the value of the environment variable ENV, break it into a path, and
> -   add of the entries to PPREFIX.  */
> -
> -static void
> -prefix_from_env (const char *env, struct path_prefix *pprefix)
> -{
> -  const char *p;
> -  p = getenv (env);
> -
> -  if (p)
> -    prefix_from_string (p, pprefix);
> -}
> -
> -static void
> -prefix_from_string (const char *p, struct path_prefix *pprefix)
> -{
> -  const char *startp, *endp;
> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
> -
> -  if (debug)
> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
> -
> -  startp = endp = p;
> -  while (1)
> -    {
> -      if (*endp == PATH_SEPARATOR || *endp == 0)
> -	{
> -	  strncpy (nstore, startp, endp-startp);
> -	  if (endp == startp)
> -	    {
> -	      strcpy (nstore, "./");
> -	    }
> -	  else if (! IS_DIR_SEPARATOR (endp[-1]))
> -	    {
> -	      nstore[endp-startp] = DIR_SEPARATOR;
> -	      nstore[endp-startp+1] = 0;
> -	    }
> -	  else
> -	    nstore[endp-startp] = 0;
> -
> -	  if (debug)
> -	    fprintf (stderr, "  - add prefix: %s\n", nstore);
> -
> -	  add_prefix (pprefix, nstore);
> -	  if (*endp == 0)
> -	    break;
> -	  endp = startp = endp + 1;
> -	}
> -      else
> -	endp++;
> -    }
> -  free (nstore);
> -}
> -
>  #ifdef OBJECT_FORMAT_NONE
>  
>  /* Add an entry for the object file NAME to object file list LIST.
> @@ -1198,6 +1017,7 @@
>  #endif
>        }
>      vflag = debug;
> +    find_file_set_debug (debug);
>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>        lto_mode = LTO_MODE_LTO;
>    }


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-10  2:47 ` Meador Inge
@ 2012-10-18 15:39   ` Meador Inge
  2012-10-18 19:08     ` Bernhard Reutner-Fischer
                       ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Meador Inge @ 2012-10-18 15:39 UTC (permalink / raw)
  To: gcc-patches

Ping ^ 2.

On 10/09/2012 09:44 PM, Meador Inge wrote:
> Ping.
> 
> On 10/04/2012 03:45 PM, Meador Inge wrote:
>> Hi All,
>>
>> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
>> path when invoking the wrapped binutils program.  This goes against the
>> accepted practice in GCC to find sub-programs relative to where the
>> GCC binaries are stored and to not make assumptions about the PATH.
>>
>> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
>> by factoring out some utility code for finding files from collect2.c.
>> These functions are then leveraged to find the binutils programs.
>> Note that similar code exist in gcc.c.  Perhaps one day everything
>> can be merged to the file-find files.
>>
>> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
>> arm-none-eabi targets.  OK?
>>
>> P.S. I am not quite sure what is best for the copyrights and contributed
>> by comments in the file-find* files I added since that code was just moved.
>> This patch drops the contributed by and keeps all the copyright dates from
>> collect2.c.
>>
>> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
>>
>> 	* collect2.c (main): Call find_file_set_debug.
>> 	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
>> 	Factor out into ...
>> 	* file-find.c (New file): ... here and ...
>> 	* file-find.h (New file): ... here.
>> 	* gcc-ar.c (standard_exec_prefix): New variable.
>> 	(standard_libexec_prefix): Ditto.
>> 	(tooldir_base_prefix) Ditto.
>> 	(self_exec_prefix): Ditto.
>> 	(self_libexec_prefix): Ditto.
>> 	(self_tooldir_prefix): Ditto.
>> 	(target_version): Ditto.
>> 	(path): Ditto.
>> 	(target_path): Ditto.
>> 	(setup_prefixes): New function.
>> 	(main): Rework how wrapped programs are found.
>> 	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
>> 	(AR_OBJS): New variable.
>> 	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
>> 	(gcc-nm$(exeext)): Ditto.
>> 	(gcc-ranlib(exeext)): Ditto.
>> 	(COLLECT2_OBJS): Add file-find.o.
>> 	(collect2.o): Add file-find.h prerequisite.
>> 	(file-find.o): New rule.
>>
>> Index: gcc/gcc-ar.c
>> ===================================================================
>> --- gcc/gcc-ar.c	(revision 192099)
>> +++ gcc/gcc-ar.c	(working copy)
>> @@ -21,21 +21,110 @@
>>  #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;
>> -static const char *const target_machine = TARGET_MACHINE;
>>  
>> +/* 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)
>>  {
>> -  const char *nprefix;
>>    const char *exe_name;
>>    char *plugin;
>>    int k, status, err;
>> @@ -44,37 +133,35 @@
>>    bool is_ar = !strcmp (PERSONALITY, "ar");
>>    int exit_code = FATAL_EXIT_CODE;
>>  
>> -  exe_name = PERSONALITY;
>> -#ifdef CROSS_DIRECTORY_STRUCTURE
>> -  exe_name = concat (target_machine, "-", exe_name, NULL);
>> -#endif
>> +  setup_prefixes (av[0]);
>>  
>> -  /* Find plugin */
>> -  /* XXX implement more magic from gcc.c? */
>> -  nprefix = getenv ("GCC_EXEC_PREFIX");
>> -  if (!nprefix)
>> -    nprefix = av[0];
>> -  else
>> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
>> +  /* Find the GCC LTO plugin */
>> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
>> +  if (!plugin)
>> +    {
>> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
>> +      exit (1);
>> +    }
>>  
>> -  nprefix = make_relative_prefix (nprefix,
>> -				  standard_bin_prefix,
>> -				  standard_libexec_prefix);
>> -  if (nprefix == NULL)
>> -    nprefix = standard_libexec_prefix;
>> +  /* Find the wrapped binutils program.  */
>> +  exe_name = find_a_file (&target_path, PERSONALITY);
>> +  if (!exe_name)
>> +    {
>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>> +      const char *cross_exe_name;
>>  
>> -  plugin = concat (nprefix,
>> -		   dir_separator,
>> -                   DEFAULT_TARGET_MACHINE, 
>> -		   dir_separator,
>> -		   DEFAULT_TARGET_VERSION,
>> -	           dir_separator,
>> -		   LTOPLUGINSONAME,
>> -		   NULL);
>> -  if (access (plugin, R_OK))
>> -    {
>> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
>> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
>> +      exe_name = find_a_file (&path, cross_exe_name);
>> +      if (!exe_name)
>> +	{
>> +	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
>> +		   cross_exe_name);
>> +	  exit (1);
>> +	}
>> +#else
>> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>>        exit (1);
>> +#endif
>>      }
>>  
>>    /* Create new command line with plugin */
>> Index: gcc/Makefile.in
>> ===================================================================
>> --- gcc/Makefile.in	(revision 192099)
>> +++ gcc/Makefile.in	(working copy)
>> @@ -1446,7 +1446,7 @@
>>  # compiler and containing target-dependent code.
>>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>>  	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
>> -	hash-table.o
>> +	hash-table.o file-find.o
>>  
>>  # This lists all host objects for the front ends.
>>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
>> @@ -1827,19 +1827,20 @@
>>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>>  
>> +AR_OBJS = file-find.o
>>  AR_LIBS = @COLLECT2_LIBS@
>>  
>> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
>> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
>> -		$(LIBS) $(AR_LIBS)
>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>  
>> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
>> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
>> -		$(LIBS) $(AR_LIBS)
>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>  
>> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
>> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
>> -		$(LIBS) $(AR_LIBS)
>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>  
>>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>>  	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
>> @@ -1867,7 +1868,7 @@
>>  gcc-nm.c: gcc-ar.c
>>  	cp $^ $@
>>  
>> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
>> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>>  COLLECT2_LIBS = @COLLECT2_LIBS@
>>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
>> @@ -1879,7 +1880,7 @@
>>  	@TARGET_SYSTEM_ROOT_DEFINE@
>>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>>  	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
>> -	$(DIAGNOSTIC_H)
>> +	$(DIAGNOSTIC_H) file-find.h
>>  
>>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>      collect2-aix.h
>> @@ -3353,6 +3354,7 @@
>>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>>     $(REGS_H) hw-doloop.h
>> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
>> Index: gcc/file-find.c
>> ===================================================================
>> --- gcc/file-find.c	(revision 0)
>> +++ gcc/file-find.c	(revision 0)
>> @@ -0,0 +1,194 @@
>> +/* Utility functions for finding files relative to GCC binaries.
>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>> +
>> +This file is part of GCC.
>> +
>> +GCC is free software; you can redistribute it and/or modify it under
>> +the terms of the GNU General Public License as published by the Free
>> +Software Foundation; either version 3, or (at your option) any later
>> +version.
>> +
>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> +for more details.
>> +
>> +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 "config.h"
>> +#include "system.h"
>> +#include "filenames.h"
>> +#include "file-find.h"
>> +
>> +static bool debug = false;
>> +
>> +void
>> +find_file_set_debug(bool debug_state)
>> +{
>> +  debug = debug_state;
>> +}
>> +
>> +char *
>> +find_a_file (struct path_prefix *pprefix, const char *name)
>> +{
>> +  char *temp;
>> +  struct prefix_list *pl;
>> +  int len = pprefix->max_len + strlen (name) + 1;
>> +
>> +  if (debug)
>> +    fprintf (stderr, "Looking for '%s'\n", name);
>> +
>> +#ifdef HOST_EXECUTABLE_SUFFIX
>> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
>> +#endif
>> +
>> +  temp = XNEWVEC (char, len);
>> +
>> +  /* Determine the filename to execute (special case for absolute paths).  */
>> +
>> +  if (IS_ABSOLUTE_PATH (name))
>> +    {
>> +      if (access (name, X_OK) == 0)
>> +	{
>> +	  strcpy (temp, name);
>> +
>> +	  if (debug)
>> +	    fprintf (stderr, "  - found: absolute path\n");
>> +
>> +	  return temp;
>> +	}
>> +
>> +#ifdef HOST_EXECUTABLE_SUFFIX
>> +	/* Some systems have a suffix for executable files.
>> +	   So try appending that.  */
>> +      strcpy (temp, name);
>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>> +
>> +	if (access (temp, X_OK) == 0)
>> +	  return temp;
>> +#endif
>> +
>> +      if (debug)
>> +	fprintf (stderr, "  - failed to locate using absolute path\n");
>> +    }
>> +  else
>> +    for (pl = pprefix->plist; pl; pl = pl->next)
>> +      {
>> +	struct stat st;
>> +
>> +	strcpy (temp, pl->prefix);
>> +	strcat (temp, name);
>> +
>> +	if (stat (temp, &st) >= 0
>> +	    && ! S_ISDIR (st.st_mode)
>> +	    && access (temp, X_OK) == 0)
>> +	  return temp;
>> +
>> +#ifdef HOST_EXECUTABLE_SUFFIX
>> +	/* Some systems have a suffix for executable files.
>> +	   So try appending that.  */
>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>> +
>> +	if (stat (temp, &st) >= 0
>> +	    && ! S_ISDIR (st.st_mode)
>> +	    && access (temp, X_OK) == 0)
>> +	  return temp;
>> +#endif
>> +      }
>> +
>> +  if (debug && pprefix->plist == NULL)
>> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
>> +
>> +  free (temp);
>> +  return 0;
>> +}
>> +
>> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
>> +
>> +void
>> +add_prefix (struct path_prefix *pprefix, const char *prefix)
>> +{
>> +  struct prefix_list *pl, **prev;
>> +  int len;
>> +
>> +  if (pprefix->plist)
>> +    {
>> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
>> +	;
>> +      prev = &pl->next;
>> +    }
>> +  else
>> +    prev = &pprefix->plist;
>> +
>> +  /* Keep track of the longest prefix.  */
>> +
>> +  len = strlen (prefix);
>> +  if (len > pprefix->max_len)
>> +    pprefix->max_len = len;
>> +
>> +  pl = XNEW (struct prefix_list);
>> +  pl->prefix = xstrdup (prefix);
>> +
>> +  if (*prev)
>> +    pl->next = *prev;
>> +  else
>> +    pl->next = (struct prefix_list *) 0;
>> +  *prev = pl;
>> +}
>> +
>> +/* Take the value of the environment variable ENV, break it into a path, and
>> +   add of the entries to PPREFIX.  */
>> +
>> +void
>> +prefix_from_env (const char *env, struct path_prefix *pprefix)
>> +{
>> +  const char *p;
>> +  p = getenv (env);
>> +
>> +  if (p)
>> +    prefix_from_string (p, pprefix);
>> +}
>> +
>> +void
>> +prefix_from_string (const char *p, struct path_prefix *pprefix)
>> +{
>> +  const char *startp, *endp;
>> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
>> +
>> +  if (debug)
>> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>> +
>> +  startp = endp = p;
>> +  while (1)
>> +    {
>> +      if (*endp == PATH_SEPARATOR || *endp == 0)
>> +	{
>> +	  strncpy (nstore, startp, endp-startp);
>> +	  if (endp == startp)
>> +	    {
>> +	      strcpy (nstore, "./");
>> +	    }
>> +	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>> +	    {
>> +	      nstore[endp-startp] = DIR_SEPARATOR;
>> +	      nstore[endp-startp+1] = 0;
>> +	    }
>> +	  else
>> +	    nstore[endp-startp] = 0;
>> +
>> +	  if (debug)
>> +	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>> +
>> +	  add_prefix (pprefix, nstore);
>> +	  if (*endp == 0)
>> +	    break;
>> +	  endp = startp = endp + 1;
>> +	}
>> +      else
>> +	endp++;
>> +    }
>> +  free (nstore);
>> +}
>> Index: gcc/file-find.h
>> ===================================================================
>> --- gcc/file-find.h	(revision 0)
>> +++ gcc/file-find.h	(revision 0)
>> @@ -0,0 +1,47 @@
>> +/* Prototypes and data structures used for implementing functions for
>> +   finding files relative to GCC binaries.
>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>> +
>> +This file is part of GCC.
>> +
>> +GCC is free software; you can redistribute it and/or modify it under
>> +the terms of the GNU General Public License as published by the Free
>> +Software Foundation; either version 3, or (at your option) any later
>> +version.
>> +
>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> +for more details.
>> +
>> +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/>.  */
>> +
>> +#ifndef GCC_FILE_FIND_H
>> +#define GCC_FILE_FIND_H
>> +
>> +/* Structure to hold all the directories in which to search for files to
>> +   execute.  */
>> +
>> +struct prefix_list
>> +{
>> +  const char *prefix;         /* String to prepend to the path.  */
>> +  struct prefix_list *next;   /* Next in linked list.  */
>> +};
>> +
>> +struct path_prefix
>> +{
>> +  struct prefix_list *plist;  /* List of prefixes to try */
>> +  int max_len;                /* Max length of a prefix in PLIST */
>> +  const char *name;           /* Name of this list (used in config stuff) */
>> +};
>> +
>> +extern void find_file_set_debug (bool);
>> +extern char *find_a_file (struct path_prefix *, const char *);
>> +extern void add_prefix (struct path_prefix *, const char *);
>> +extern void prefix_from_env (const char *, struct path_prefix *);
>> +extern void prefix_from_string (const char *, struct path_prefix *);
>> +
>> +#endif /* GCC_FILE_FIND_H */
>> Index: gcc/collect2.c
>> ===================================================================
>> --- gcc/collect2.c	(revision 192099)
>> +++ gcc/collect2.c	(working copy)
>> @@ -31,6 +31,7 @@
>>  #include "coretypes.h"
>>  #include "tm.h"
>>  #include "filenames.h"
>> +#include "file-find.h"
>>  
>>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>>  #undef TARGET_64BIT
>> @@ -243,22 +244,6 @@
>>     would leave untouched.  */
>>  bool may_unlink_output_file = false;
>>  
>> -/* Structure to hold all the directories in which to search for files to
>> -   execute.  */
>> -
>> -struct prefix_list
>> -{
>> -  const char *prefix;         /* String to prepend to the path.  */
>> -  struct prefix_list *next;   /* Next in linked list.  */
>> -};
>> -
>> -struct path_prefix
>> -{
>> -  struct prefix_list *plist;  /* List of prefixes to try */
>> -  int max_len;                /* Max length of a prefix in PLIST */
>> -  const char *name;           /* Name of this list (used in config stuff) */
>> -};
>> -
>>  #ifdef COLLECT_EXPORT_LIST
>>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>>  static struct head libs;                    /* list of libraries */
>> @@ -302,10 +287,6 @@
>>  static symkind is_ctor_dtor (const char *);
>>  
>>  static void handler (int);
>> -static char *find_a_file (struct path_prefix *, const char *);
>> -static void add_prefix (struct path_prefix *, const char *);
>> -static void prefix_from_env (const char *, struct path_prefix *);
>> -static void prefix_from_string (const char *, struct path_prefix *);
>>  static void do_wait (const char *, struct pex_obj *);
>>  static void fork_execute (const char *, char **);
>>  static void maybe_unlink (const char *);
>> @@ -653,168 +634,6 @@
>>  
>>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>>  
>> -static char *
>> -find_a_file (struct path_prefix *pprefix, const char *name)
>> -{
>> -  char *temp;
>> -  struct prefix_list *pl;
>> -  int len = pprefix->max_len + strlen (name) + 1;
>> -
>> -  if (debug)
>> -    fprintf (stderr, "Looking for '%s'\n", name);
>> -
>> -#ifdef HOST_EXECUTABLE_SUFFIX
>> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
>> -#endif
>> -
>> -  temp = XNEWVEC (char, len);
>> -
>> -  /* Determine the filename to execute (special case for absolute paths).  */
>> -
>> -  if (IS_ABSOLUTE_PATH (name))
>> -    {
>> -      if (access (name, X_OK) == 0)
>> -	{
>> -	  strcpy (temp, name);
>> -
>> -	  if (debug)
>> -	    fprintf (stderr, "  - found: absolute path\n");
>> -
>> -	  return temp;
>> -	}
>> -
>> -#ifdef HOST_EXECUTABLE_SUFFIX
>> -	/* Some systems have a suffix for executable files.
>> -	   So try appending that.  */
>> -      strcpy (temp, name);
>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>> -
>> -	if (access (temp, X_OK) == 0)
>> -	  return temp;
>> -#endif
>> -
>> -      if (debug)
>> -	fprintf (stderr, "  - failed to locate using absolute path\n");
>> -    }
>> -  else
>> -    for (pl = pprefix->plist; pl; pl = pl->next)
>> -      {
>> -	struct stat st;
>> -
>> -	strcpy (temp, pl->prefix);
>> -	strcat (temp, name);
>> -
>> -	if (stat (temp, &st) >= 0
>> -	    && ! S_ISDIR (st.st_mode)
>> -	    && access (temp, X_OK) == 0)
>> -	  return temp;
>> -
>> -#ifdef HOST_EXECUTABLE_SUFFIX
>> -	/* Some systems have a suffix for executable files.
>> -	   So try appending that.  */
>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>> -
>> -	if (stat (temp, &st) >= 0
>> -	    && ! S_ISDIR (st.st_mode)
>> -	    && access (temp, X_OK) == 0)
>> -	  return temp;
>> -#endif
>> -      }
>> -
>> -  if (debug && pprefix->plist == NULL)
>> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
>> -
>> -  free (temp);
>> -  return 0;
>> -}
>> -
>> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
>> -
>> -static void
>> -add_prefix (struct path_prefix *pprefix, const char *prefix)
>> -{
>> -  struct prefix_list *pl, **prev;
>> -  int len;
>> -
>> -  if (pprefix->plist)
>> -    {
>> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
>> -	;
>> -      prev = &pl->next;
>> -    }
>> -  else
>> -    prev = &pprefix->plist;
>> -
>> -  /* Keep track of the longest prefix.  */
>> -
>> -  len = strlen (prefix);
>> -  if (len > pprefix->max_len)
>> -    pprefix->max_len = len;
>> -
>> -  pl = XNEW (struct prefix_list);
>> -  pl->prefix = xstrdup (prefix);
>> -
>> -  if (*prev)
>> -    pl->next = *prev;
>> -  else
>> -    pl->next = (struct prefix_list *) 0;
>> -  *prev = pl;
>> -}
>> -\f
>> -/* Take the value of the environment variable ENV, break it into a path, and
>> -   add of the entries to PPREFIX.  */
>> -
>> -static void
>> -prefix_from_env (const char *env, struct path_prefix *pprefix)
>> -{
>> -  const char *p;
>> -  p = getenv (env);
>> -
>> -  if (p)
>> -    prefix_from_string (p, pprefix);
>> -}
>> -
>> -static void
>> -prefix_from_string (const char *p, struct path_prefix *pprefix)
>> -{
>> -  const char *startp, *endp;
>> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
>> -
>> -  if (debug)
>> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>> -
>> -  startp = endp = p;
>> -  while (1)
>> -    {
>> -      if (*endp == PATH_SEPARATOR || *endp == 0)
>> -	{
>> -	  strncpy (nstore, startp, endp-startp);
>> -	  if (endp == startp)
>> -	    {
>> -	      strcpy (nstore, "./");
>> -	    }
>> -	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>> -	    {
>> -	      nstore[endp-startp] = DIR_SEPARATOR;
>> -	      nstore[endp-startp+1] = 0;
>> -	    }
>> -	  else
>> -	    nstore[endp-startp] = 0;
>> -
>> -	  if (debug)
>> -	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>> -
>> -	  add_prefix (pprefix, nstore);
>> -	  if (*endp == 0)
>> -	    break;
>> -	  endp = startp = endp + 1;
>> -	}
>> -      else
>> -	endp++;
>> -    }
>> -  free (nstore);
>> -}
>> -
>>  #ifdef OBJECT_FORMAT_NONE
>>  
>>  /* Add an entry for the object file NAME to object file list LIST.
>> @@ -1198,6 +1017,7 @@
>>  #endif
>>        }
>>      vflag = debug;
>> +    find_file_set_debug (debug);
>>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>>        lto_mode = LTO_MODE_LTO;
>>    }
> 
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-18 15:39   ` Meador Inge
@ 2012-10-18 19:08     ` Bernhard Reutner-Fischer
  2012-10-19 21:55       ` Meador Inge
  2012-10-19 22:26     ` Meador Inge
  2012-10-29 16:10     ` Meador Inge
  2 siblings, 1 reply; 16+ messages in thread
From: Bernhard Reutner-Fischer @ 2012-10-18 19:08 UTC (permalink / raw)
  To: Meador Inge, gcc-patches

On 18 October 2012 17:30:20 Meador Inge <meadori@codesourcery.com> wrote:
> Ping ^ 2

Been a while but wasn't --with-build-sysroot for exactly this?
>
> On 10/09/2012 09:44 PM, Meador Inge wrote:
> > Ping.
> >
> > On 102012 03:45 PM, Meador Inge wrote:
> >> Hi All,
> >>
> >> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
> >> path when invoking the wrapped binutils program.  This goes against the
> >> accepted practice in GCC to find sub-programs relative to where the
> >> GCC binaries are stored and to not make assumptions about the PATH.
> >>
> >> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
> >> by factoring out some utility code for finding files from collect2.c.
> >> These functions are then leveraged to find the binutils programs.
> >> Note that similar code exist in gcc.c.  Perhaps one day everything
> >> can be merged to the file-find files.
> >>
> >> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
> >> arm-none-eabi targets.


Sent with AquaMail for Android
http://www.aqua-mail.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-18 19:08     ` Bernhard Reutner-Fischer
@ 2012-10-19 21:55       ` Meador Inge
  0 siblings, 0 replies; 16+ messages in thread
From: Meador Inge @ 2012-10-19 21:55 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer; +Cc: gcc-patches

On 10/18/2012 01:33 PM, Bernhard Reutner-Fischer wrote:

> On 18 October 2012 17:30:20 Meador Inge <meadori@codesourcery.com> wrote:
>> Ping ^ 2
> 
> Been a while but wasn't --with-build-sysroot for exactly this?

AFAICT, no.  --with-build-sysroot seems to be used for setting a different
sysroot to use for compiling target libraries while GCC is being built [1].
This patch fixes the gcc-{ar,nm,ranlib} programs that are built and deployed
with GCC to not rely on the current PATH when running the binutils programs
they are wrapping.

[1] http://gcc.gnu.org/install/configure.html

-- 
Meador Inge
CodeSourcery / Mentor Embedded

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-18 15:39   ` Meador Inge
  2012-10-18 19:08     ` Bernhard Reutner-Fischer
@ 2012-10-19 22:26     ` Meador Inge
  2012-10-29 16:10     ` Meador Inge
  2 siblings, 0 replies; 16+ messages in thread
From: Meador Inge @ 2012-10-19 22:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther, dnovillo

CC'ing the LTO maintainers.

On 10/18/2012 10:30 AM, Meador Inge wrote:
> Ping ^ 2.
> 
> On 10/09/2012 09:44 PM, Meador Inge wrote:
>> Ping.
>>
>> On 10/04/2012 03:45 PM, Meador Inge wrote:
>>> Hi All,
>>>
>>> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
>>> path when invoking the wrapped binutils program.  This goes against the
>>> accepted practice in GCC to find sub-programs relative to where the
>>> GCC binaries are stored and to not make assumptions about the PATH.
>>>
>>> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
>>> by factoring out some utility code for finding files from collect2.c.
>>> These functions are then leveraged to find the binutils programs.
>>> Note that similar code exist in gcc.c.  Perhaps one day everything
>>> can be merged to the file-find files.
>>>
>>> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
>>> arm-none-eabi targets.  OK?
>>>
>>> P.S. I am not quite sure what is best for the copyrights and contributed
>>> by comments in the file-find* files I added since that code was just moved.
>>> This patch drops the contributed by and keeps all the copyright dates from
>>> collect2.c.
>>>
>>> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
>>>
>>> 	* collect2.c (main): Call find_file_set_debug.
>>> 	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
>>> 	Factor out into ...
>>> 	* file-find.c (New file): ... here and ...
>>> 	* file-find.h (New file): ... here.
>>> 	* gcc-ar.c (standard_exec_prefix): New variable.
>>> 	(standard_libexec_prefix): Ditto.
>>> 	(tooldir_base_prefix) Ditto.
>>> 	(self_exec_prefix): Ditto.
>>> 	(self_libexec_prefix): Ditto.
>>> 	(self_tooldir_prefix): Ditto.
>>> 	(target_version): Ditto.
>>> 	(path): Ditto.
>>> 	(target_path): Ditto.
>>> 	(setup_prefixes): New function.
>>> 	(main): Rework how wrapped programs are found.
>>> 	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
>>> 	(AR_OBJS): New variable.
>>> 	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
>>> 	(gcc-nm$(exeext)): Ditto.
>>> 	(gcc-ranlib(exeext)): Ditto.
>>> 	(COLLECT2_OBJS): Add file-find.o.
>>> 	(collect2.o): Add file-find.h prerequisite.
>>> 	(file-find.o): New rule.
>>>
>>> Index: gcc/gcc-ar.c
>>> ===================================================================
>>> --- gcc/gcc-ar.c	(revision 192099)
>>> +++ gcc/gcc-ar.c	(working copy)
>>> @@ -21,21 +21,110 @@
>>>  #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;
>>> -static const char *const target_machine = TARGET_MACHINE;
>>>  
>>> +/* 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)
>>>  {
>>> -  const char *nprefix;
>>>    const char *exe_name;
>>>    char *plugin;
>>>    int k, status, err;
>>> @@ -44,37 +133,35 @@
>>>    bool is_ar = !strcmp (PERSONALITY, "ar");
>>>    int exit_code = FATAL_EXIT_CODE;
>>>  
>>> -  exe_name = PERSONALITY;
>>> -#ifdef CROSS_DIRECTORY_STRUCTURE
>>> -  exe_name = concat (target_machine, "-", exe_name, NULL);
>>> -#endif
>>> +  setup_prefixes (av[0]);
>>>  
>>> -  /* Find plugin */
>>> -  /* XXX implement more magic from gcc.c? */
>>> -  nprefix = getenv ("GCC_EXEC_PREFIX");
>>> -  if (!nprefix)
>>> -    nprefix = av[0];
>>> -  else
>>> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
>>> +  /* Find the GCC LTO plugin */
>>> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
>>> +  if (!plugin)
>>> +    {
>>> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
>>> +      exit (1);
>>> +    }
>>>  
>>> -  nprefix = make_relative_prefix (nprefix,
>>> -				  standard_bin_prefix,
>>> -				  standard_libexec_prefix);
>>> -  if (nprefix == NULL)
>>> -    nprefix = standard_libexec_prefix;
>>> +  /* Find the wrapped binutils program.  */
>>> +  exe_name = find_a_file (&target_path, PERSONALITY);
>>> +  if (!exe_name)
>>> +    {
>>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>>> +      const char *cross_exe_name;
>>>  
>>> -  plugin = concat (nprefix,
>>> -		   dir_separator,
>>> -                   DEFAULT_TARGET_MACHINE, 
>>> -		   dir_separator,
>>> -		   DEFAULT_TARGET_VERSION,
>>> -	           dir_separator,
>>> -		   LTOPLUGINSONAME,
>>> -		   NULL);
>>> -  if (access (plugin, R_OK))
>>> -    {
>>> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
>>> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
>>> +      exe_name = find_a_file (&path, cross_exe_name);
>>> +      if (!exe_name)
>>> +	{
>>> +	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
>>> +		   cross_exe_name);
>>> +	  exit (1);
>>> +	}
>>> +#else
>>> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>>>        exit (1);
>>> +#endif
>>>      }
>>>  
>>>    /* Create new command line with plugin */
>>> Index: gcc/Makefile.in
>>> ===================================================================
>>> --- gcc/Makefile.in	(revision 192099)
>>> +++ gcc/Makefile.in	(working copy)
>>> @@ -1446,7 +1446,7 @@
>>>  # compiler and containing target-dependent code.
>>>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>>>  	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
>>> -	hash-table.o
>>> +	hash-table.o file-find.o
>>>  
>>>  # This lists all host objects for the front ends.
>>>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
>>> @@ -1827,19 +1827,20 @@
>>>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>>>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>>>  
>>> +AR_OBJS = file-find.o
>>>  AR_LIBS = @COLLECT2_LIBS@
>>>  
>>> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
>>> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
>>> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
>>> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>>>  	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
>>> @@ -1867,7 +1868,7 @@
>>>  gcc-nm.c: gcc-ar.c
>>>  	cp $^ $@
>>>  
>>> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
>>> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>>>  COLLECT2_LIBS = @COLLECT2_LIBS@
>>>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>>>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
>>> @@ -1879,7 +1880,7 @@
>>>  	@TARGET_SYSTEM_ROOT_DEFINE@
>>>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>>>  	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
>>> -	$(DIAGNOSTIC_H)
>>> +	$(DIAGNOSTIC_H) file-find.h
>>>  
>>>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>>      collect2-aix.h
>>> @@ -3353,6 +3354,7 @@
>>>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>>>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>>>     $(REGS_H) hw-doloop.h
>>> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>>>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>>>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>>>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
>>> Index: gcc/file-find.c
>>> ===================================================================
>>> --- gcc/file-find.c	(revision 0)
>>> +++ gcc/file-find.c	(revision 0)
>>> @@ -0,0 +1,194 @@
>>> +/* Utility functions for finding files relative to GCC binaries.
>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>> +
>>> +This file is part of GCC.
>>> +
>>> +GCC is free software; you can redistribute it and/or modify it under
>>> +the terms of the GNU General Public License as published by the Free
>>> +Software Foundation; either version 3, or (at your option) any later
>>> +version.
>>> +
>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>> +for more details.
>>> +
>>> +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 "config.h"
>>> +#include "system.h"
>>> +#include "filenames.h"
>>> +#include "file-find.h"
>>> +
>>> +static bool debug = false;
>>> +
>>> +void
>>> +find_file_set_debug(bool debug_state)
>>> +{
>>> +  debug = debug_state;
>>> +}
>>> +
>>> +char *
>>> +find_a_file (struct path_prefix *pprefix, const char *name)
>>> +{
>>> +  char *temp;
>>> +  struct prefix_list *pl;
>>> +  int len = pprefix->max_len + strlen (name) + 1;
>>> +
>>> +  if (debug)
>>> +    fprintf (stderr, "Looking for '%s'\n", name);
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>> +#endif
>>> +
>>> +  temp = XNEWVEC (char, len);
>>> +
>>> +  /* Determine the filename to execute (special case for absolute paths).  */
>>> +
>>> +  if (IS_ABSOLUTE_PATH (name))
>>> +    {
>>> +      if (access (name, X_OK) == 0)
>>> +	{
>>> +	  strcpy (temp, name);
>>> +
>>> +	  if (debug)
>>> +	    fprintf (stderr, "  - found: absolute path\n");
>>> +
>>> +	  return temp;
>>> +	}
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +	/* Some systems have a suffix for executable files.
>>> +	   So try appending that.  */
>>> +      strcpy (temp, name);
>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> +
>>> +	if (access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +#endif
>>> +
>>> +      if (debug)
>>> +	fprintf (stderr, "  - failed to locate using absolute path\n");
>>> +    }
>>> +  else
>>> +    for (pl = pprefix->plist; pl; pl = pl->next)
>>> +      {
>>> +	struct stat st;
>>> +
>>> +	strcpy (temp, pl->prefix);
>>> +	strcat (temp, name);
>>> +
>>> +	if (stat (temp, &st) >= 0
>>> +	    && ! S_ISDIR (st.st_mode)
>>> +	    && access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +	/* Some systems have a suffix for executable files.
>>> +	   So try appending that.  */
>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> +
>>> +	if (stat (temp, &st) >= 0
>>> +	    && ! S_ISDIR (st.st_mode)
>>> +	    && access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +#endif
>>> +      }
>>> +
>>> +  if (debug && pprefix->plist == NULL)
>>> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>> +
>>> +  free (temp);
>>> +  return 0;
>>> +}
>>> +
>>> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>> +
>>> +void
>>> +add_prefix (struct path_prefix *pprefix, const char *prefix)
>>> +{
>>> +  struct prefix_list *pl, **prev;
>>> +  int len;
>>> +
>>> +  if (pprefix->plist)
>>> +    {
>>> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>> +	;
>>> +      prev = &pl->next;
>>> +    }
>>> +  else
>>> +    prev = &pprefix->plist;
>>> +
>>> +  /* Keep track of the longest prefix.  */
>>> +
>>> +  len = strlen (prefix);
>>> +  if (len > pprefix->max_len)
>>> +    pprefix->max_len = len;
>>> +
>>> +  pl = XNEW (struct prefix_list);
>>> +  pl->prefix = xstrdup (prefix);
>>> +
>>> +  if (*prev)
>>> +    pl->next = *prev;
>>> +  else
>>> +    pl->next = (struct prefix_list *) 0;
>>> +  *prev = pl;
>>> +}
>>> +
>>> +/* Take the value of the environment variable ENV, break it into a path, and
>>> +   add of the entries to PPREFIX.  */
>>> +
>>> +void
>>> +prefix_from_env (const char *env, struct path_prefix *pprefix)
>>> +{
>>> +  const char *p;
>>> +  p = getenv (env);
>>> +
>>> +  if (p)
>>> +    prefix_from_string (p, pprefix);
>>> +}
>>> +
>>> +void
>>> +prefix_from_string (const char *p, struct path_prefix *pprefix)
>>> +{
>>> +  const char *startp, *endp;
>>> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>> +
>>> +  if (debug)
>>> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>> +
>>> +  startp = endp = p;
>>> +  while (1)
>>> +    {
>>> +      if (*endp == PATH_SEPARATOR || *endp == 0)
>>> +	{
>>> +	  strncpy (nstore, startp, endp-startp);
>>> +	  if (endp == startp)
>>> +	    {
>>> +	      strcpy (nstore, "./");
>>> +	    }
>>> +	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>> +	    {
>>> +	      nstore[endp-startp] = DIR_SEPARATOR;
>>> +	      nstore[endp-startp+1] = 0;
>>> +	    }
>>> +	  else
>>> +	    nstore[endp-startp] = 0;
>>> +
>>> +	  if (debug)
>>> +	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>> +
>>> +	  add_prefix (pprefix, nstore);
>>> +	  if (*endp == 0)
>>> +	    break;
>>> +	  endp = startp = endp + 1;
>>> +	}
>>> +      else
>>> +	endp++;
>>> +    }
>>> +  free (nstore);
>>> +}
>>> Index: gcc/file-find.h
>>> ===================================================================
>>> --- gcc/file-find.h	(revision 0)
>>> +++ gcc/file-find.h	(revision 0)
>>> @@ -0,0 +1,47 @@
>>> +/* Prototypes and data structures used for implementing functions for
>>> +   finding files relative to GCC binaries.
>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>> +
>>> +This file is part of GCC.
>>> +
>>> +GCC is free software; you can redistribute it and/or modify it under
>>> +the terms of the GNU General Public License as published by the Free
>>> +Software Foundation; either version 3, or (at your option) any later
>>> +version.
>>> +
>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>> +for more details.
>>> +
>>> +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/>.  */
>>> +
>>> +#ifndef GCC_FILE_FIND_H
>>> +#define GCC_FILE_FIND_H
>>> +
>>> +/* Structure to hold all the directories in which to search for files to
>>> +   execute.  */
>>> +
>>> +struct prefix_list
>>> +{
>>> +  const char *prefix;         /* String to prepend to the path.  */
>>> +  struct prefix_list *next;   /* Next in linked list.  */
>>> +};
>>> +
>>> +struct path_prefix
>>> +{
>>> +  struct prefix_list *plist;  /* List of prefixes to try */
>>> +  int max_len;                /* Max length of a prefix in PLIST */
>>> +  const char *name;           /* Name of this list (used in config stuff) */
>>> +};
>>> +
>>> +extern void find_file_set_debug (bool);
>>> +extern char *find_a_file (struct path_prefix *, const char *);
>>> +extern void add_prefix (struct path_prefix *, const char *);
>>> +extern void prefix_from_env (const char *, struct path_prefix *);
>>> +extern void prefix_from_string (const char *, struct path_prefix *);
>>> +
>>> +#endif /* GCC_FILE_FIND_H */
>>> Index: gcc/collect2.c
>>> ===================================================================
>>> --- gcc/collect2.c	(revision 192099)
>>> +++ gcc/collect2.c	(working copy)
>>> @@ -31,6 +31,7 @@
>>>  #include "coretypes.h"
>>>  #include "tm.h"
>>>  #include "filenames.h"
>>> +#include "file-find.h"
>>>  
>>>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>>>  #undef TARGET_64BIT
>>> @@ -243,22 +244,6 @@
>>>     would leave untouched.  */
>>>  bool may_unlink_output_file = false;
>>>  
>>> -/* Structure to hold all the directories in which to search for files to
>>> -   execute.  */
>>> -
>>> -struct prefix_list
>>> -{
>>> -  const char *prefix;         /* String to prepend to the path.  */
>>> -  struct prefix_list *next;   /* Next in linked list.  */
>>> -};
>>> -
>>> -struct path_prefix
>>> -{
>>> -  struct prefix_list *plist;  /* List of prefixes to try */
>>> -  int max_len;                /* Max length of a prefix in PLIST */
>>> -  const char *name;           /* Name of this list (used in config stuff) */
>>> -};
>>> -
>>>  #ifdef COLLECT_EXPORT_LIST
>>>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>>>  static struct head libs;                    /* list of libraries */
>>> @@ -302,10 +287,6 @@
>>>  static symkind is_ctor_dtor (const char *);
>>>  
>>>  static void handler (int);
>>> -static char *find_a_file (struct path_prefix *, const char *);
>>> -static void add_prefix (struct path_prefix *, const char *);
>>> -static void prefix_from_env (const char *, struct path_prefix *);
>>> -static void prefix_from_string (const char *, struct path_prefix *);
>>>  static void do_wait (const char *, struct pex_obj *);
>>>  static void fork_execute (const char *, char **);
>>>  static void maybe_unlink (const char *);
>>> @@ -653,168 +634,6 @@
>>>  
>>>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>>>  
>>> -static char *
>>> -find_a_file (struct path_prefix *pprefix, const char *name)
>>> -{
>>> -  char *temp;
>>> -  struct prefix_list *pl;
>>> -  int len = pprefix->max_len + strlen (name) + 1;
>>> -
>>> -  if (debug)
>>> -    fprintf (stderr, "Looking for '%s'\n", name);
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>> -#endif
>>> -
>>> -  temp = XNEWVEC (char, len);
>>> -
>>> -  /* Determine the filename to execute (special case for absolute paths).  */
>>> -
>>> -  if (IS_ABSOLUTE_PATH (name))
>>> -    {
>>> -      if (access (name, X_OK) == 0)
>>> -	{
>>> -	  strcpy (temp, name);
>>> -
>>> -	  if (debug)
>>> -	    fprintf (stderr, "  - found: absolute path\n");
>>> -
>>> -	  return temp;
>>> -	}
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -	/* Some systems have a suffix for executable files.
>>> -	   So try appending that.  */
>>> -      strcpy (temp, name);
>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> -
>>> -	if (access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -#endif
>>> -
>>> -      if (debug)
>>> -	fprintf (stderr, "  - failed to locate using absolute path\n");
>>> -    }
>>> -  else
>>> -    for (pl = pprefix->plist; pl; pl = pl->next)
>>> -      {
>>> -	struct stat st;
>>> -
>>> -	strcpy (temp, pl->prefix);
>>> -	strcat (temp, name);
>>> -
>>> -	if (stat (temp, &st) >= 0
>>> -	    && ! S_ISDIR (st.st_mode)
>>> -	    && access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -	/* Some systems have a suffix for executable files.
>>> -	   So try appending that.  */
>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> -
>>> -	if (stat (temp, &st) >= 0
>>> -	    && ! S_ISDIR (st.st_mode)
>>> -	    && access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -#endif
>>> -      }
>>> -
>>> -  if (debug && pprefix->plist == NULL)
>>> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>> -
>>> -  free (temp);
>>> -  return 0;
>>> -}
>>> -
>>> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>> -
>>> -static void
>>> -add_prefix (struct path_prefix *pprefix, const char *prefix)
>>> -{
>>> -  struct prefix_list *pl, **prev;
>>> -  int len;
>>> -
>>> -  if (pprefix->plist)
>>> -    {
>>> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>> -	;
>>> -      prev = &pl->next;
>>> -    }
>>> -  else
>>> -    prev = &pprefix->plist;
>>> -
>>> -  /* Keep track of the longest prefix.  */
>>> -
>>> -  len = strlen (prefix);
>>> -  if (len > pprefix->max_len)
>>> -    pprefix->max_len = len;
>>> -
>>> -  pl = XNEW (struct prefix_list);
>>> -  pl->prefix = xstrdup (prefix);
>>> -
>>> -  if (*prev)
>>> -    pl->next = *prev;
>>> -  else
>>> -    pl->next = (struct prefix_list *) 0;
>>> -  *prev = pl;
>>> -}
>>> -\f
>>> -/* Take the value of the environment variable ENV, break it into a path, and
>>> -   add of the entries to PPREFIX.  */
>>> -
>>> -static void
>>> -prefix_from_env (const char *env, struct path_prefix *pprefix)
>>> -{
>>> -  const char *p;
>>> -  p = getenv (env);
>>> -
>>> -  if (p)
>>> -    prefix_from_string (p, pprefix);
>>> -}
>>> -
>>> -static void
>>> -prefix_from_string (const char *p, struct path_prefix *pprefix)
>>> -{
>>> -  const char *startp, *endp;
>>> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>> -
>>> -  if (debug)
>>> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>> -
>>> -  startp = endp = p;
>>> -  while (1)
>>> -    {
>>> -      if (*endp == PATH_SEPARATOR || *endp == 0)
>>> -	{
>>> -	  strncpy (nstore, startp, endp-startp);
>>> -	  if (endp == startp)
>>> -	    {
>>> -	      strcpy (nstore, "./");
>>> -	    }
>>> -	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>> -	    {
>>> -	      nstore[endp-startp] = DIR_SEPARATOR;
>>> -	      nstore[endp-startp+1] = 0;
>>> -	    }
>>> -	  else
>>> -	    nstore[endp-startp] = 0;
>>> -
>>> -	  if (debug)
>>> -	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>> -
>>> -	  add_prefix (pprefix, nstore);
>>> -	  if (*endp == 0)
>>> -	    break;
>>> -	  endp = startp = endp + 1;
>>> -	}
>>> -      else
>>> -	endp++;
>>> -    }
>>> -  free (nstore);
>>> -}
>>> -
>>>  #ifdef OBJECT_FORMAT_NONE
>>>  
>>>  /* Add an entry for the object file NAME to object file list LIST.
>>> @@ -1198,6 +1017,7 @@
>>>  #endif
>>>        }
>>>      vflag = debug;
>>> +    find_file_set_debug (debug);
>>>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>>>        lto_mode = LTO_MODE_LTO;
>>>    }
>>
>>
> 
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-18 15:39   ` Meador Inge
  2012-10-18 19:08     ` Bernhard Reutner-Fischer
  2012-10-19 22:26     ` Meador Inge
@ 2012-10-29 16:10     ` Meador Inge
  2012-11-07 21:51       ` Meador Inge
  2 siblings, 1 reply; 16+ messages in thread
From: Meador Inge @ 2012-10-29 16:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.guenther, dnovillo

Ping ^ 3.

On 10/18/2012 10:30 AM, Meador Inge wrote:
> Ping ^ 2.
> 
> On 10/09/2012 09:44 PM, Meador Inge wrote:
>> Ping.
>>
>> On 10/04/2012 03:45 PM, Meador Inge wrote:
>>> Hi All,
>>>
>>> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
>>> path when invoking the wrapped binutils program.  This goes against the
>>> accepted practice in GCC to find sub-programs relative to where the
>>> GCC binaries are stored and to not make assumptions about the PATH.
>>>
>>> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
>>> by factoring out some utility code for finding files from collect2.c.
>>> These functions are then leveraged to find the binutils programs.
>>> Note that similar code exist in gcc.c.  Perhaps one day everything
>>> can be merged to the file-find files.
>>>
>>> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
>>> arm-none-eabi targets.  OK?
>>>
>>> P.S. I am not quite sure what is best for the copyrights and contributed
>>> by comments in the file-find* files I added since that code was just moved.
>>> This patch drops the contributed by and keeps all the copyright dates from
>>> collect2.c.
>>>
>>> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
>>>
>>> 	* collect2.c (main): Call find_file_set_debug.
>>> 	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
>>> 	Factor out into ...
>>> 	* file-find.c (New file): ... here and ...
>>> 	* file-find.h (New file): ... here.
>>> 	* gcc-ar.c (standard_exec_prefix): New variable.
>>> 	(standard_libexec_prefix): Ditto.
>>> 	(tooldir_base_prefix) Ditto.
>>> 	(self_exec_prefix): Ditto.
>>> 	(self_libexec_prefix): Ditto.
>>> 	(self_tooldir_prefix): Ditto.
>>> 	(target_version): Ditto.
>>> 	(path): Ditto.
>>> 	(target_path): Ditto.
>>> 	(setup_prefixes): New function.
>>> 	(main): Rework how wrapped programs are found.
>>> 	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
>>> 	(AR_OBJS): New variable.
>>> 	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
>>> 	(gcc-nm$(exeext)): Ditto.
>>> 	(gcc-ranlib(exeext)): Ditto.
>>> 	(COLLECT2_OBJS): Add file-find.o.
>>> 	(collect2.o): Add file-find.h prerequisite.
>>> 	(file-find.o): New rule.
>>>
>>> Index: gcc/gcc-ar.c
>>> ===================================================================
>>> --- gcc/gcc-ar.c	(revision 192099)
>>> +++ gcc/gcc-ar.c	(working copy)
>>> @@ -21,21 +21,110 @@
>>>  #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;
>>> -static const char *const target_machine = TARGET_MACHINE;
>>>  
>>> +/* 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)
>>>  {
>>> -  const char *nprefix;
>>>    const char *exe_name;
>>>    char *plugin;
>>>    int k, status, err;
>>> @@ -44,37 +133,35 @@
>>>    bool is_ar = !strcmp (PERSONALITY, "ar");
>>>    int exit_code = FATAL_EXIT_CODE;
>>>  
>>> -  exe_name = PERSONALITY;
>>> -#ifdef CROSS_DIRECTORY_STRUCTURE
>>> -  exe_name = concat (target_machine, "-", exe_name, NULL);
>>> -#endif
>>> +  setup_prefixes (av[0]);
>>>  
>>> -  /* Find plugin */
>>> -  /* XXX implement more magic from gcc.c? */
>>> -  nprefix = getenv ("GCC_EXEC_PREFIX");
>>> -  if (!nprefix)
>>> -    nprefix = av[0];
>>> -  else
>>> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
>>> +  /* Find the GCC LTO plugin */
>>> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
>>> +  if (!plugin)
>>> +    {
>>> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
>>> +      exit (1);
>>> +    }
>>>  
>>> -  nprefix = make_relative_prefix (nprefix,
>>> -				  standard_bin_prefix,
>>> -				  standard_libexec_prefix);
>>> -  if (nprefix == NULL)
>>> -    nprefix = standard_libexec_prefix;
>>> +  /* Find the wrapped binutils program.  */
>>> +  exe_name = find_a_file (&target_path, PERSONALITY);
>>> +  if (!exe_name)
>>> +    {
>>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>>> +      const char *cross_exe_name;
>>>  
>>> -  plugin = concat (nprefix,
>>> -		   dir_separator,
>>> -                   DEFAULT_TARGET_MACHINE, 
>>> -		   dir_separator,
>>> -		   DEFAULT_TARGET_VERSION,
>>> -	           dir_separator,
>>> -		   LTOPLUGINSONAME,
>>> -		   NULL);
>>> -  if (access (plugin, R_OK))
>>> -    {
>>> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
>>> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
>>> +      exe_name = find_a_file (&path, cross_exe_name);
>>> +      if (!exe_name)
>>> +	{
>>> +	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
>>> +		   cross_exe_name);
>>> +	  exit (1);
>>> +	}
>>> +#else
>>> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>>>        exit (1);
>>> +#endif
>>>      }
>>>  
>>>    /* Create new command line with plugin */
>>> Index: gcc/Makefile.in
>>> ===================================================================
>>> --- gcc/Makefile.in	(revision 192099)
>>> +++ gcc/Makefile.in	(working copy)
>>> @@ -1446,7 +1446,7 @@
>>>  # compiler and containing target-dependent code.
>>>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>>>  	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
>>> -	hash-table.o
>>> +	hash-table.o file-find.o
>>>  
>>>  # This lists all host objects for the front ends.
>>>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
>>> @@ -1827,19 +1827,20 @@
>>>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>>>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>>>  
>>> +AR_OBJS = file-find.o
>>>  AR_LIBS = @COLLECT2_LIBS@
>>>  
>>> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
>>> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
>>> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
>>> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
>>> -		$(LIBS) $(AR_LIBS)
>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>  
>>>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>>>  	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
>>> @@ -1867,7 +1868,7 @@
>>>  gcc-nm.c: gcc-ar.c
>>>  	cp $^ $@
>>>  
>>> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
>>> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>>>  COLLECT2_LIBS = @COLLECT2_LIBS@
>>>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>>>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
>>> @@ -1879,7 +1880,7 @@
>>>  	@TARGET_SYSTEM_ROOT_DEFINE@
>>>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>>>  	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
>>> -	$(DIAGNOSTIC_H)
>>> +	$(DIAGNOSTIC_H) file-find.h
>>>  
>>>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>>      collect2-aix.h
>>> @@ -3353,6 +3354,7 @@
>>>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>>>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>>>     $(REGS_H) hw-doloop.h
>>> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>>>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>>>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>>>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
>>> Index: gcc/file-find.c
>>> ===================================================================
>>> --- gcc/file-find.c	(revision 0)
>>> +++ gcc/file-find.c	(revision 0)
>>> @@ -0,0 +1,194 @@
>>> +/* Utility functions for finding files relative to GCC binaries.
>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>> +
>>> +This file is part of GCC.
>>> +
>>> +GCC is free software; you can redistribute it and/or modify it under
>>> +the terms of the GNU General Public License as published by the Free
>>> +Software Foundation; either version 3, or (at your option) any later
>>> +version.
>>> +
>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>> +for more details.
>>> +
>>> +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 "config.h"
>>> +#include "system.h"
>>> +#include "filenames.h"
>>> +#include "file-find.h"
>>> +
>>> +static bool debug = false;
>>> +
>>> +void
>>> +find_file_set_debug(bool debug_state)
>>> +{
>>> +  debug = debug_state;
>>> +}
>>> +
>>> +char *
>>> +find_a_file (struct path_prefix *pprefix, const char *name)
>>> +{
>>> +  char *temp;
>>> +  struct prefix_list *pl;
>>> +  int len = pprefix->max_len + strlen (name) + 1;
>>> +
>>> +  if (debug)
>>> +    fprintf (stderr, "Looking for '%s'\n", name);
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>> +#endif
>>> +
>>> +  temp = XNEWVEC (char, len);
>>> +
>>> +  /* Determine the filename to execute (special case for absolute paths).  */
>>> +
>>> +  if (IS_ABSOLUTE_PATH (name))
>>> +    {
>>> +      if (access (name, X_OK) == 0)
>>> +	{
>>> +	  strcpy (temp, name);
>>> +
>>> +	  if (debug)
>>> +	    fprintf (stderr, "  - found: absolute path\n");
>>> +
>>> +	  return temp;
>>> +	}
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +	/* Some systems have a suffix for executable files.
>>> +	   So try appending that.  */
>>> +      strcpy (temp, name);
>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> +
>>> +	if (access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +#endif
>>> +
>>> +      if (debug)
>>> +	fprintf (stderr, "  - failed to locate using absolute path\n");
>>> +    }
>>> +  else
>>> +    for (pl = pprefix->plist; pl; pl = pl->next)
>>> +      {
>>> +	struct stat st;
>>> +
>>> +	strcpy (temp, pl->prefix);
>>> +	strcat (temp, name);
>>> +
>>> +	if (stat (temp, &st) >= 0
>>> +	    && ! S_ISDIR (st.st_mode)
>>> +	    && access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +
>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>> +	/* Some systems have a suffix for executable files.
>>> +	   So try appending that.  */
>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> +
>>> +	if (stat (temp, &st) >= 0
>>> +	    && ! S_ISDIR (st.st_mode)
>>> +	    && access (temp, X_OK) == 0)
>>> +	  return temp;
>>> +#endif
>>> +      }
>>> +
>>> +  if (debug && pprefix->plist == NULL)
>>> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>> +
>>> +  free (temp);
>>> +  return 0;
>>> +}
>>> +
>>> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>> +
>>> +void
>>> +add_prefix (struct path_prefix *pprefix, const char *prefix)
>>> +{
>>> +  struct prefix_list *pl, **prev;
>>> +  int len;
>>> +
>>> +  if (pprefix->plist)
>>> +    {
>>> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>> +	;
>>> +      prev = &pl->next;
>>> +    }
>>> +  else
>>> +    prev = &pprefix->plist;
>>> +
>>> +  /* Keep track of the longest prefix.  */
>>> +
>>> +  len = strlen (prefix);
>>> +  if (len > pprefix->max_len)
>>> +    pprefix->max_len = len;
>>> +
>>> +  pl = XNEW (struct prefix_list);
>>> +  pl->prefix = xstrdup (prefix);
>>> +
>>> +  if (*prev)
>>> +    pl->next = *prev;
>>> +  else
>>> +    pl->next = (struct prefix_list *) 0;
>>> +  *prev = pl;
>>> +}
>>> +
>>> +/* Take the value of the environment variable ENV, break it into a path, and
>>> +   add of the entries to PPREFIX.  */
>>> +
>>> +void
>>> +prefix_from_env (const char *env, struct path_prefix *pprefix)
>>> +{
>>> +  const char *p;
>>> +  p = getenv (env);
>>> +
>>> +  if (p)
>>> +    prefix_from_string (p, pprefix);
>>> +}
>>> +
>>> +void
>>> +prefix_from_string (const char *p, struct path_prefix *pprefix)
>>> +{
>>> +  const char *startp, *endp;
>>> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>> +
>>> +  if (debug)
>>> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>> +
>>> +  startp = endp = p;
>>> +  while (1)
>>> +    {
>>> +      if (*endp == PATH_SEPARATOR || *endp == 0)
>>> +	{
>>> +	  strncpy (nstore, startp, endp-startp);
>>> +	  if (endp == startp)
>>> +	    {
>>> +	      strcpy (nstore, "./");
>>> +	    }
>>> +	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>> +	    {
>>> +	      nstore[endp-startp] = DIR_SEPARATOR;
>>> +	      nstore[endp-startp+1] = 0;
>>> +	    }
>>> +	  else
>>> +	    nstore[endp-startp] = 0;
>>> +
>>> +	  if (debug)
>>> +	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>> +
>>> +	  add_prefix (pprefix, nstore);
>>> +	  if (*endp == 0)
>>> +	    break;
>>> +	  endp = startp = endp + 1;
>>> +	}
>>> +      else
>>> +	endp++;
>>> +    }
>>> +  free (nstore);
>>> +}
>>> Index: gcc/file-find.h
>>> ===================================================================
>>> --- gcc/file-find.h	(revision 0)
>>> +++ gcc/file-find.h	(revision 0)
>>> @@ -0,0 +1,47 @@
>>> +/* Prototypes and data structures used for implementing functions for
>>> +   finding files relative to GCC binaries.
>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>> +
>>> +This file is part of GCC.
>>> +
>>> +GCC is free software; you can redistribute it and/or modify it under
>>> +the terms of the GNU General Public License as published by the Free
>>> +Software Foundation; either version 3, or (at your option) any later
>>> +version.
>>> +
>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>> +for more details.
>>> +
>>> +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/>.  */
>>> +
>>> +#ifndef GCC_FILE_FIND_H
>>> +#define GCC_FILE_FIND_H
>>> +
>>> +/* Structure to hold all the directories in which to search for files to
>>> +   execute.  */
>>> +
>>> +struct prefix_list
>>> +{
>>> +  const char *prefix;         /* String to prepend to the path.  */
>>> +  struct prefix_list *next;   /* Next in linked list.  */
>>> +};
>>> +
>>> +struct path_prefix
>>> +{
>>> +  struct prefix_list *plist;  /* List of prefixes to try */
>>> +  int max_len;                /* Max length of a prefix in PLIST */
>>> +  const char *name;           /* Name of this list (used in config stuff) */
>>> +};
>>> +
>>> +extern void find_file_set_debug (bool);
>>> +extern char *find_a_file (struct path_prefix *, const char *);
>>> +extern void add_prefix (struct path_prefix *, const char *);
>>> +extern void prefix_from_env (const char *, struct path_prefix *);
>>> +extern void prefix_from_string (const char *, struct path_prefix *);
>>> +
>>> +#endif /* GCC_FILE_FIND_H */
>>> Index: gcc/collect2.c
>>> ===================================================================
>>> --- gcc/collect2.c	(revision 192099)
>>> +++ gcc/collect2.c	(working copy)
>>> @@ -31,6 +31,7 @@
>>>  #include "coretypes.h"
>>>  #include "tm.h"
>>>  #include "filenames.h"
>>> +#include "file-find.h"
>>>  
>>>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>>>  #undef TARGET_64BIT
>>> @@ -243,22 +244,6 @@
>>>     would leave untouched.  */
>>>  bool may_unlink_output_file = false;
>>>  
>>> -/* Structure to hold all the directories in which to search for files to
>>> -   execute.  */
>>> -
>>> -struct prefix_list
>>> -{
>>> -  const char *prefix;         /* String to prepend to the path.  */
>>> -  struct prefix_list *next;   /* Next in linked list.  */
>>> -};
>>> -
>>> -struct path_prefix
>>> -{
>>> -  struct prefix_list *plist;  /* List of prefixes to try */
>>> -  int max_len;                /* Max length of a prefix in PLIST */
>>> -  const char *name;           /* Name of this list (used in config stuff) */
>>> -};
>>> -
>>>  #ifdef COLLECT_EXPORT_LIST
>>>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>>>  static struct head libs;                    /* list of libraries */
>>> @@ -302,10 +287,6 @@
>>>  static symkind is_ctor_dtor (const char *);
>>>  
>>>  static void handler (int);
>>> -static char *find_a_file (struct path_prefix *, const char *);
>>> -static void add_prefix (struct path_prefix *, const char *);
>>> -static void prefix_from_env (const char *, struct path_prefix *);
>>> -static void prefix_from_string (const char *, struct path_prefix *);
>>>  static void do_wait (const char *, struct pex_obj *);
>>>  static void fork_execute (const char *, char **);
>>>  static void maybe_unlink (const char *);
>>> @@ -653,168 +634,6 @@
>>>  
>>>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>>>  
>>> -static char *
>>> -find_a_file (struct path_prefix *pprefix, const char *name)
>>> -{
>>> -  char *temp;
>>> -  struct prefix_list *pl;
>>> -  int len = pprefix->max_len + strlen (name) + 1;
>>> -
>>> -  if (debug)
>>> -    fprintf (stderr, "Looking for '%s'\n", name);
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>> -#endif
>>> -
>>> -  temp = XNEWVEC (char, len);
>>> -
>>> -  /* Determine the filename to execute (special case for absolute paths).  */
>>> -
>>> -  if (IS_ABSOLUTE_PATH (name))
>>> -    {
>>> -      if (access (name, X_OK) == 0)
>>> -	{
>>> -	  strcpy (temp, name);
>>> -
>>> -	  if (debug)
>>> -	    fprintf (stderr, "  - found: absolute path\n");
>>> -
>>> -	  return temp;
>>> -	}
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -	/* Some systems have a suffix for executable files.
>>> -	   So try appending that.  */
>>> -      strcpy (temp, name);
>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> -
>>> -	if (access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -#endif
>>> -
>>> -      if (debug)
>>> -	fprintf (stderr, "  - failed to locate using absolute path\n");
>>> -    }
>>> -  else
>>> -    for (pl = pprefix->plist; pl; pl = pl->next)
>>> -      {
>>> -	struct stat st;
>>> -
>>> -	strcpy (temp, pl->prefix);
>>> -	strcat (temp, name);
>>> -
>>> -	if (stat (temp, &st) >= 0
>>> -	    && ! S_ISDIR (st.st_mode)
>>> -	    && access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -
>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>> -	/* Some systems have a suffix for executable files.
>>> -	   So try appending that.  */
>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>> -
>>> -	if (stat (temp, &st) >= 0
>>> -	    && ! S_ISDIR (st.st_mode)
>>> -	    && access (temp, X_OK) == 0)
>>> -	  return temp;
>>> -#endif
>>> -      }
>>> -
>>> -  if (debug && pprefix->plist == NULL)
>>> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>> -
>>> -  free (temp);
>>> -  return 0;
>>> -}
>>> -
>>> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>> -
>>> -static void
>>> -add_prefix (struct path_prefix *pprefix, const char *prefix)
>>> -{
>>> -  struct prefix_list *pl, **prev;
>>> -  int len;
>>> -
>>> -  if (pprefix->plist)
>>> -    {
>>> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>> -	;
>>> -      prev = &pl->next;
>>> -    }
>>> -  else
>>> -    prev = &pprefix->plist;
>>> -
>>> -  /* Keep track of the longest prefix.  */
>>> -
>>> -  len = strlen (prefix);
>>> -  if (len > pprefix->max_len)
>>> -    pprefix->max_len = len;
>>> -
>>> -  pl = XNEW (struct prefix_list);
>>> -  pl->prefix = xstrdup (prefix);
>>> -
>>> -  if (*prev)
>>> -    pl->next = *prev;
>>> -  else
>>> -    pl->next = (struct prefix_list *) 0;
>>> -  *prev = pl;
>>> -}
>>> -\f
>>> -/* Take the value of the environment variable ENV, break it into a path, and
>>> -   add of the entries to PPREFIX.  */
>>> -
>>> -static void
>>> -prefix_from_env (const char *env, struct path_prefix *pprefix)
>>> -{
>>> -  const char *p;
>>> -  p = getenv (env);
>>> -
>>> -  if (p)
>>> -    prefix_from_string (p, pprefix);
>>> -}
>>> -
>>> -static void
>>> -prefix_from_string (const char *p, struct path_prefix *pprefix)
>>> -{
>>> -  const char *startp, *endp;
>>> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>> -
>>> -  if (debug)
>>> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>> -
>>> -  startp = endp = p;
>>> -  while (1)
>>> -    {
>>> -      if (*endp == PATH_SEPARATOR || *endp == 0)
>>> -	{
>>> -	  strncpy (nstore, startp, endp-startp);
>>> -	  if (endp == startp)
>>> -	    {
>>> -	      strcpy (nstore, "./");
>>> -	    }
>>> -	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>> -	    {
>>> -	      nstore[endp-startp] = DIR_SEPARATOR;
>>> -	      nstore[endp-startp+1] = 0;
>>> -	    }
>>> -	  else
>>> -	    nstore[endp-startp] = 0;
>>> -
>>> -	  if (debug)
>>> -	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>> -
>>> -	  add_prefix (pprefix, nstore);
>>> -	  if (*endp == 0)
>>> -	    break;
>>> -	  endp = startp = endp + 1;
>>> -	}
>>> -      else
>>> -	endp++;
>>> -    }
>>> -  free (nstore);
>>> -}
>>> -
>>>  #ifdef OBJECT_FORMAT_NONE
>>>  
>>>  /* Add an entry for the object file NAME to object file list LIST.
>>> @@ -1198,6 +1017,7 @@
>>>  #endif
>>>        }
>>>      vflag = debug;
>>> +    find_file_set_debug (debug);
>>>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>>>        lto_mode = LTO_MODE_LTO;
>>>    }
>>
>>
> 
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-10-29 16:10     ` Meador Inge
@ 2012-11-07 21:51       ` Meador Inge
  2012-11-26 15:06         ` Richard Biener
  0 siblings, 1 reply; 16+ messages in thread
From: Meador Inge @ 2012-11-07 21:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.guenther, dnovillo

Ping ^ 4.

On 10/29/2012 10:46 AM, Meador Inge wrote:
> Ping ^ 3.
> 
> On 10/18/2012 10:30 AM, Meador Inge wrote:
>> Ping ^ 2.
>>
>> On 10/09/2012 09:44 PM, Meador Inge wrote:
>>> Ping.
>>>
>>> On 10/04/2012 03:45 PM, Meador Inge wrote:
>>>> Hi All,
>>>>
>>>> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
>>>> path when invoking the wrapped binutils program.  This goes against the
>>>> accepted practice in GCC to find sub-programs relative to where the
>>>> GCC binaries are stored and to not make assumptions about the PATH.
>>>>
>>>> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
>>>> by factoring out some utility code for finding files from collect2.c.
>>>> These functions are then leveraged to find the binutils programs.
>>>> Note that similar code exist in gcc.c.  Perhaps one day everything
>>>> can be merged to the file-find files.
>>>>
>>>> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
>>>> arm-none-eabi targets.  OK?
>>>>
>>>> P.S. I am not quite sure what is best for the copyrights and contributed
>>>> by comments in the file-find* files I added since that code was just moved.
>>>> This patch drops the contributed by and keeps all the copyright dates from
>>>> collect2.c.
>>>>
>>>> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
>>>>
>>>> 	* collect2.c (main): Call find_file_set_debug.
>>>> 	(find_a_find, add_prefix, prefix_from_env, prefix_from_string):
>>>> 	Factor out into ...
>>>> 	* file-find.c (New file): ... here and ...
>>>> 	* file-find.h (New file): ... here.
>>>> 	* gcc-ar.c (standard_exec_prefix): New variable.
>>>> 	(standard_libexec_prefix): Ditto.
>>>> 	(tooldir_base_prefix) Ditto.
>>>> 	(self_exec_prefix): Ditto.
>>>> 	(self_libexec_prefix): Ditto.
>>>> 	(self_tooldir_prefix): Ditto.
>>>> 	(target_version): Ditto.
>>>> 	(path): Ditto.
>>>> 	(target_path): Ditto.
>>>> 	(setup_prefixes): New function.
>>>> 	(main): Rework how wrapped programs are found.
>>>> 	* Makefile.in (OBJS-libcommon-target): Add file-find.o.
>>>> 	(AR_OBJS): New variable.
>>>> 	(gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
>>>> 	(gcc-nm$(exeext)): Ditto.
>>>> 	(gcc-ranlib(exeext)): Ditto.
>>>> 	(COLLECT2_OBJS): Add file-find.o.
>>>> 	(collect2.o): Add file-find.h prerequisite.
>>>> 	(file-find.o): New rule.
>>>>
>>>> Index: gcc/gcc-ar.c
>>>> ===================================================================
>>>> --- gcc/gcc-ar.c	(revision 192099)
>>>> +++ gcc/gcc-ar.c	(working copy)
>>>> @@ -21,21 +21,110 @@
>>>>  #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;
>>>> -static const char *const target_machine = TARGET_MACHINE;
>>>>  
>>>> +/* 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)
>>>>  {
>>>> -  const char *nprefix;
>>>>    const char *exe_name;
>>>>    char *plugin;
>>>>    int k, status, err;
>>>> @@ -44,37 +133,35 @@
>>>>    bool is_ar = !strcmp (PERSONALITY, "ar");
>>>>    int exit_code = FATAL_EXIT_CODE;
>>>>  
>>>> -  exe_name = PERSONALITY;
>>>> -#ifdef CROSS_DIRECTORY_STRUCTURE
>>>> -  exe_name = concat (target_machine, "-", exe_name, NULL);
>>>> -#endif
>>>> +  setup_prefixes (av[0]);
>>>>  
>>>> -  /* Find plugin */
>>>> -  /* XXX implement more magic from gcc.c? */
>>>> -  nprefix = getenv ("GCC_EXEC_PREFIX");
>>>> -  if (!nprefix)
>>>> -    nprefix = av[0];
>>>> -  else
>>>> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
>>>> +  /* Find the GCC LTO plugin */
>>>> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
>>>> +  if (!plugin)
>>>> +    {
>>>> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
>>>> +      exit (1);
>>>> +    }
>>>>  
>>>> -  nprefix = make_relative_prefix (nprefix,
>>>> -				  standard_bin_prefix,
>>>> -				  standard_libexec_prefix);
>>>> -  if (nprefix == NULL)
>>>> -    nprefix = standard_libexec_prefix;
>>>> +  /* Find the wrapped binutils program.  */
>>>> +  exe_name = find_a_file (&target_path, PERSONALITY);
>>>> +  if (!exe_name)
>>>> +    {
>>>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>>>> +      const char *cross_exe_name;
>>>>  
>>>> -  plugin = concat (nprefix,
>>>> -		   dir_separator,
>>>> -                   DEFAULT_TARGET_MACHINE, 
>>>> -		   dir_separator,
>>>> -		   DEFAULT_TARGET_VERSION,
>>>> -	           dir_separator,
>>>> -		   LTOPLUGINSONAME,
>>>> -		   NULL);
>>>> -  if (access (plugin, R_OK))
>>>> -    {
>>>> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
>>>> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
>>>> +      exe_name = find_a_file (&path, cross_exe_name);
>>>> +      if (!exe_name)
>>>> +	{
>>>> +	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
>>>> +		   cross_exe_name);
>>>> +	  exit (1);
>>>> +	}
>>>> +#else
>>>> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>>>>        exit (1);
>>>> +#endif
>>>>      }
>>>>  
>>>>    /* Create new command line with plugin */
>>>> Index: gcc/Makefile.in
>>>> ===================================================================
>>>> --- gcc/Makefile.in	(revision 192099)
>>>> +++ gcc/Makefile.in	(working copy)
>>>> @@ -1446,7 +1446,7 @@
>>>>  # compiler and containing target-dependent code.
>>>>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>>>>  	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
>>>> -	hash-table.o
>>>> +	hash-table.o file-find.o
>>>>  
>>>>  # This lists all host objects for the front ends.
>>>>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
>>>> @@ -1827,19 +1827,20 @@
>>>>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>>>>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>>>>  
>>>> +AR_OBJS = file-find.o
>>>>  AR_LIBS = @COLLECT2_LIBS@
>>>>  
>>>> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
>>>> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
>>>> -		$(LIBS) $(AR_LIBS)
>>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>  
>>>> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
>>>> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
>>>> -		$(LIBS) $(AR_LIBS)
>>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>  
>>>> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
>>>> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>>>>  	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
>>>> -		$(LIBS) $(AR_LIBS)
>>>> +		$(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>  
>>>>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>>>>  	-DTARGET_MACHINE=\"$(target_noncanonical)\" \
>>>> @@ -1867,7 +1868,7 @@
>>>>  gcc-nm.c: gcc-ar.c
>>>>  	cp $^ $@
>>>>  
>>>> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
>>>> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>>>>  COLLECT2_LIBS = @COLLECT2_LIBS@
>>>>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>>>>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
>>>> @@ -1879,7 +1880,7 @@
>>>>  	@TARGET_SYSTEM_ROOT_DEFINE@
>>>>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>>>>  	$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
>>>> -	$(DIAGNOSTIC_H)
>>>> +	$(DIAGNOSTIC_H) file-find.h
>>>>  
>>>>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>>>      collect2-aix.h
>>>> @@ -3353,6 +3354,7 @@
>>>>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>>>>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>>>>     $(REGS_H) hw-doloop.h
>>>> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>>>>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>>>>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>>>>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
>>>> Index: gcc/file-find.c
>>>> ===================================================================
>>>> --- gcc/file-find.c	(revision 0)
>>>> +++ gcc/file-find.c	(revision 0)
>>>> @@ -0,0 +1,194 @@
>>>> +/* Utility functions for finding files relative to GCC binaries.
>>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>>> +
>>>> +This file is part of GCC.
>>>> +
>>>> +GCC is free software; you can redistribute it and/or modify it under
>>>> +the terms of the GNU General Public License as published by the Free
>>>> +Software Foundation; either version 3, or (at your option) any later
>>>> +version.
>>>> +
>>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>>> +for more details.
>>>> +
>>>> +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 "config.h"
>>>> +#include "system.h"
>>>> +#include "filenames.h"
>>>> +#include "file-find.h"
>>>> +
>>>> +static bool debug = false;
>>>> +
>>>> +void
>>>> +find_file_set_debug(bool debug_state)
>>>> +{
>>>> +  debug = debug_state;
>>>> +}
>>>> +
>>>> +char *
>>>> +find_a_file (struct path_prefix *pprefix, const char *name)
>>>> +{
>>>> +  char *temp;
>>>> +  struct prefix_list *pl;
>>>> +  int len = pprefix->max_len + strlen (name) + 1;
>>>> +
>>>> +  if (debug)
>>>> +    fprintf (stderr, "Looking for '%s'\n", name);
>>>> +
>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>>> +#endif
>>>> +
>>>> +  temp = XNEWVEC (char, len);
>>>> +
>>>> +  /* Determine the filename to execute (special case for absolute paths).  */
>>>> +
>>>> +  if (IS_ABSOLUTE_PATH (name))
>>>> +    {
>>>> +      if (access (name, X_OK) == 0)
>>>> +	{
>>>> +	  strcpy (temp, name);
>>>> +
>>>> +	  if (debug)
>>>> +	    fprintf (stderr, "  - found: absolute path\n");
>>>> +
>>>> +	  return temp;
>>>> +	}
>>>> +
>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>> +	/* Some systems have a suffix for executable files.
>>>> +	   So try appending that.  */
>>>> +      strcpy (temp, name);
>>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>> +
>>>> +	if (access (temp, X_OK) == 0)
>>>> +	  return temp;
>>>> +#endif
>>>> +
>>>> +      if (debug)
>>>> +	fprintf (stderr, "  - failed to locate using absolute path\n");
>>>> +    }
>>>> +  else
>>>> +    for (pl = pprefix->plist; pl; pl = pl->next)
>>>> +      {
>>>> +	struct stat st;
>>>> +
>>>> +	strcpy (temp, pl->prefix);
>>>> +	strcat (temp, name);
>>>> +
>>>> +	if (stat (temp, &st) >= 0
>>>> +	    && ! S_ISDIR (st.st_mode)
>>>> +	    && access (temp, X_OK) == 0)
>>>> +	  return temp;
>>>> +
>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>> +	/* Some systems have a suffix for executable files.
>>>> +	   So try appending that.  */
>>>> +	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>> +
>>>> +	if (stat (temp, &st) >= 0
>>>> +	    && ! S_ISDIR (st.st_mode)
>>>> +	    && access (temp, X_OK) == 0)
>>>> +	  return temp;
>>>> +#endif
>>>> +      }
>>>> +
>>>> +  if (debug && pprefix->plist == NULL)
>>>> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>>> +
>>>> +  free (temp);
>>>> +  return 0;
>>>> +}
>>>> +
>>>> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>>> +
>>>> +void
>>>> +add_prefix (struct path_prefix *pprefix, const char *prefix)
>>>> +{
>>>> +  struct prefix_list *pl, **prev;
>>>> +  int len;
>>>> +
>>>> +  if (pprefix->plist)
>>>> +    {
>>>> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>>> +	;
>>>> +      prev = &pl->next;
>>>> +    }
>>>> +  else
>>>> +    prev = &pprefix->plist;
>>>> +
>>>> +  /* Keep track of the longest prefix.  */
>>>> +
>>>> +  len = strlen (prefix);
>>>> +  if (len > pprefix->max_len)
>>>> +    pprefix->max_len = len;
>>>> +
>>>> +  pl = XNEW (struct prefix_list);
>>>> +  pl->prefix = xstrdup (prefix);
>>>> +
>>>> +  if (*prev)
>>>> +    pl->next = *prev;
>>>> +  else
>>>> +    pl->next = (struct prefix_list *) 0;
>>>> +  *prev = pl;
>>>> +}
>>>> +
>>>> +/* Take the value of the environment variable ENV, break it into a path, and
>>>> +   add of the entries to PPREFIX.  */
>>>> +
>>>> +void
>>>> +prefix_from_env (const char *env, struct path_prefix *pprefix)
>>>> +{
>>>> +  const char *p;
>>>> +  p = getenv (env);
>>>> +
>>>> +  if (p)
>>>> +    prefix_from_string (p, pprefix);
>>>> +}
>>>> +
>>>> +void
>>>> +prefix_from_string (const char *p, struct path_prefix *pprefix)
>>>> +{
>>>> +  const char *startp, *endp;
>>>> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>>> +
>>>> +  if (debug)
>>>> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>>> +
>>>> +  startp = endp = p;
>>>> +  while (1)
>>>> +    {
>>>> +      if (*endp == PATH_SEPARATOR || *endp == 0)
>>>> +	{
>>>> +	  strncpy (nstore, startp, endp-startp);
>>>> +	  if (endp == startp)
>>>> +	    {
>>>> +	      strcpy (nstore, "./");
>>>> +	    }
>>>> +	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>>> +	    {
>>>> +	      nstore[endp-startp] = DIR_SEPARATOR;
>>>> +	      nstore[endp-startp+1] = 0;
>>>> +	    }
>>>> +	  else
>>>> +	    nstore[endp-startp] = 0;
>>>> +
>>>> +	  if (debug)
>>>> +	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>>> +
>>>> +	  add_prefix (pprefix, nstore);
>>>> +	  if (*endp == 0)
>>>> +	    break;
>>>> +	  endp = startp = endp + 1;
>>>> +	}
>>>> +      else
>>>> +	endp++;
>>>> +    }
>>>> +  free (nstore);
>>>> +}
>>>> Index: gcc/file-find.h
>>>> ===================================================================
>>>> --- gcc/file-find.h	(revision 0)
>>>> +++ gcc/file-find.h	(revision 0)
>>>> @@ -0,0 +1,47 @@
>>>> +/* Prototypes and data structures used for implementing functions for
>>>> +   finding files relative to GCC binaries.
>>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>>> +
>>>> +This file is part of GCC.
>>>> +
>>>> +GCC is free software; you can redistribute it and/or modify it under
>>>> +the terms of the GNU General Public License as published by the Free
>>>> +Software Foundation; either version 3, or (at your option) any later
>>>> +version.
>>>> +
>>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>>> +for more details.
>>>> +
>>>> +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/>.  */
>>>> +
>>>> +#ifndef GCC_FILE_FIND_H
>>>> +#define GCC_FILE_FIND_H
>>>> +
>>>> +/* Structure to hold all the directories in which to search for files to
>>>> +   execute.  */
>>>> +
>>>> +struct prefix_list
>>>> +{
>>>> +  const char *prefix;         /* String to prepend to the path.  */
>>>> +  struct prefix_list *next;   /* Next in linked list.  */
>>>> +};
>>>> +
>>>> +struct path_prefix
>>>> +{
>>>> +  struct prefix_list *plist;  /* List of prefixes to try */
>>>> +  int max_len;                /* Max length of a prefix in PLIST */
>>>> +  const char *name;           /* Name of this list (used in config stuff) */
>>>> +};
>>>> +
>>>> +extern void find_file_set_debug (bool);
>>>> +extern char *find_a_file (struct path_prefix *, const char *);
>>>> +extern void add_prefix (struct path_prefix *, const char *);
>>>> +extern void prefix_from_env (const char *, struct path_prefix *);
>>>> +extern void prefix_from_string (const char *, struct path_prefix *);
>>>> +
>>>> +#endif /* GCC_FILE_FIND_H */
>>>> Index: gcc/collect2.c
>>>> ===================================================================
>>>> --- gcc/collect2.c	(revision 192099)
>>>> +++ gcc/collect2.c	(working copy)
>>>> @@ -31,6 +31,7 @@
>>>>  #include "coretypes.h"
>>>>  #include "tm.h"
>>>>  #include "filenames.h"
>>>> +#include "file-find.h"
>>>>  
>>>>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>>>>  #undef TARGET_64BIT
>>>> @@ -243,22 +244,6 @@
>>>>     would leave untouched.  */
>>>>  bool may_unlink_output_file = false;
>>>>  
>>>> -/* Structure to hold all the directories in which to search for files to
>>>> -   execute.  */
>>>> -
>>>> -struct prefix_list
>>>> -{
>>>> -  const char *prefix;         /* String to prepend to the path.  */
>>>> -  struct prefix_list *next;   /* Next in linked list.  */
>>>> -};
>>>> -
>>>> -struct path_prefix
>>>> -{
>>>> -  struct prefix_list *plist;  /* List of prefixes to try */
>>>> -  int max_len;                /* Max length of a prefix in PLIST */
>>>> -  const char *name;           /* Name of this list (used in config stuff) */
>>>> -};
>>>> -
>>>>  #ifdef COLLECT_EXPORT_LIST
>>>>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>>>>  static struct head libs;                    /* list of libraries */
>>>> @@ -302,10 +287,6 @@
>>>>  static symkind is_ctor_dtor (const char *);
>>>>  
>>>>  static void handler (int);
>>>> -static char *find_a_file (struct path_prefix *, const char *);
>>>> -static void add_prefix (struct path_prefix *, const char *);
>>>> -static void prefix_from_env (const char *, struct path_prefix *);
>>>> -static void prefix_from_string (const char *, struct path_prefix *);
>>>>  static void do_wait (const char *, struct pex_obj *);
>>>>  static void fork_execute (const char *, char **);
>>>>  static void maybe_unlink (const char *);
>>>> @@ -653,168 +634,6 @@
>>>>  
>>>>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>>>>  
>>>> -static char *
>>>> -find_a_file (struct path_prefix *pprefix, const char *name)
>>>> -{
>>>> -  char *temp;
>>>> -  struct prefix_list *pl;
>>>> -  int len = pprefix->max_len + strlen (name) + 1;
>>>> -
>>>> -  if (debug)
>>>> -    fprintf (stderr, "Looking for '%s'\n", name);
>>>> -
>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>>> -#endif
>>>> -
>>>> -  temp = XNEWVEC (char, len);
>>>> -
>>>> -  /* Determine the filename to execute (special case for absolute paths).  */
>>>> -
>>>> -  if (IS_ABSOLUTE_PATH (name))
>>>> -    {
>>>> -      if (access (name, X_OK) == 0)
>>>> -	{
>>>> -	  strcpy (temp, name);
>>>> -
>>>> -	  if (debug)
>>>> -	    fprintf (stderr, "  - found: absolute path\n");
>>>> -
>>>> -	  return temp;
>>>> -	}
>>>> -
>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>> -	/* Some systems have a suffix for executable files.
>>>> -	   So try appending that.  */
>>>> -      strcpy (temp, name);
>>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>> -
>>>> -	if (access (temp, X_OK) == 0)
>>>> -	  return temp;
>>>> -#endif
>>>> -
>>>> -      if (debug)
>>>> -	fprintf (stderr, "  - failed to locate using absolute path\n");
>>>> -    }
>>>> -  else
>>>> -    for (pl = pprefix->plist; pl; pl = pl->next)
>>>> -      {
>>>> -	struct stat st;
>>>> -
>>>> -	strcpy (temp, pl->prefix);
>>>> -	strcat (temp, name);
>>>> -
>>>> -	if (stat (temp, &st) >= 0
>>>> -	    && ! S_ISDIR (st.st_mode)
>>>> -	    && access (temp, X_OK) == 0)
>>>> -	  return temp;
>>>> -
>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>> -	/* Some systems have a suffix for executable files.
>>>> -	   So try appending that.  */
>>>> -	strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>> -
>>>> -	if (stat (temp, &st) >= 0
>>>> -	    && ! S_ISDIR (st.st_mode)
>>>> -	    && access (temp, X_OK) == 0)
>>>> -	  return temp;
>>>> -#endif
>>>> -      }
>>>> -
>>>> -  if (debug && pprefix->plist == NULL)
>>>> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>>> -
>>>> -  free (temp);
>>>> -  return 0;
>>>> -}
>>>> -
>>>> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>>> -
>>>> -static void
>>>> -add_prefix (struct path_prefix *pprefix, const char *prefix)
>>>> -{
>>>> -  struct prefix_list *pl, **prev;
>>>> -  int len;
>>>> -
>>>> -  if (pprefix->plist)
>>>> -    {
>>>> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>>> -	;
>>>> -      prev = &pl->next;
>>>> -    }
>>>> -  else
>>>> -    prev = &pprefix->plist;
>>>> -
>>>> -  /* Keep track of the longest prefix.  */
>>>> -
>>>> -  len = strlen (prefix);
>>>> -  if (len > pprefix->max_len)
>>>> -    pprefix->max_len = len;
>>>> -
>>>> -  pl = XNEW (struct prefix_list);
>>>> -  pl->prefix = xstrdup (prefix);
>>>> -
>>>> -  if (*prev)
>>>> -    pl->next = *prev;
>>>> -  else
>>>> -    pl->next = (struct prefix_list *) 0;
>>>> -  *prev = pl;
>>>> -}
>>>> -\f
>>>> -/* Take the value of the environment variable ENV, break it into a path, and
>>>> -   add of the entries to PPREFIX.  */
>>>> -
>>>> -static void
>>>> -prefix_from_env (const char *env, struct path_prefix *pprefix)
>>>> -{
>>>> -  const char *p;
>>>> -  p = getenv (env);
>>>> -
>>>> -  if (p)
>>>> -    prefix_from_string (p, pprefix);
>>>> -}
>>>> -
>>>> -static void
>>>> -prefix_from_string (const char *p, struct path_prefix *pprefix)
>>>> -{
>>>> -  const char *startp, *endp;
>>>> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>>> -
>>>> -  if (debug)
>>>> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>>> -
>>>> -  startp = endp = p;
>>>> -  while (1)
>>>> -    {
>>>> -      if (*endp == PATH_SEPARATOR || *endp == 0)
>>>> -	{
>>>> -	  strncpy (nstore, startp, endp-startp);
>>>> -	  if (endp == startp)
>>>> -	    {
>>>> -	      strcpy (nstore, "./");
>>>> -	    }
>>>> -	  else if (! IS_DIR_SEPARATOR (endp[-1]))
>>>> -	    {
>>>> -	      nstore[endp-startp] = DIR_SEPARATOR;
>>>> -	      nstore[endp-startp+1] = 0;
>>>> -	    }
>>>> -	  else
>>>> -	    nstore[endp-startp] = 0;
>>>> -
>>>> -	  if (debug)
>>>> -	    fprintf (stderr, "  - add prefix: %s\n", nstore);
>>>> -
>>>> -	  add_prefix (pprefix, nstore);
>>>> -	  if (*endp == 0)
>>>> -	    break;
>>>> -	  endp = startp = endp + 1;
>>>> -	}
>>>> -      else
>>>> -	endp++;
>>>> -    }
>>>> -  free (nstore);
>>>> -}
>>>> -
>>>>  #ifdef OBJECT_FORMAT_NONE
>>>>  
>>>>  /* Add an entry for the object file NAME to object file list LIST.
>>>> @@ -1198,6 +1017,7 @@
>>>>  #endif
>>>>        }
>>>>      vflag = debug;
>>>> +    find_file_set_debug (debug);
>>>>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>>>>        lto_mode = LTO_MODE_LTO;
>>>>    }
>>>
>>>
>>
>>
> 
> 


-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-11-07 21:51       ` Meador Inge
@ 2012-11-26 15:06         ` Richard Biener
  2012-11-27 18:14           ` Meador Inge
  0 siblings, 1 reply; 16+ messages in thread
From: Richard Biener @ 2012-11-26 15:06 UTC (permalink / raw)
  To: Meador Inge; +Cc: gcc-patches, dnovillo

On Wed, Nov 7, 2012 at 10:51 PM, Meador Inge <meadori@codesourcery.com> wrote:
> Ping ^ 4.

Ok.

Thanks,
Richard.

> On 10/29/2012 10:46 AM, Meador Inge wrote:
>> Ping ^ 3.
>>
>> On 10/18/2012 10:30 AM, Meador Inge wrote:
>>> Ping ^ 2.
>>>
>>> On 10/09/2012 09:44 PM, Meador Inge wrote:
>>>> Ping.
>>>>
>>>> On 10/04/2012 03:45 PM, Meador Inge wrote:
>>>>> Hi All,
>>>>>
>>>>> Currently the gcc-{ar,nm,ranlib} utilities assume that binutils is in
>>>>> path when invoking the wrapped binutils program.  This goes against the
>>>>> accepted practice in GCC to find sub-programs relative to where the
>>>>> GCC binaries are stored and to not make assumptions about the PATH.
>>>>>
>>>>> This patch changes the gcc-{ar,nm,ranlib} utilities to do the same
>>>>> by factoring out some utility code for finding files from collect2.c.
>>>>> These functions are then leveraged to find the binutils programs.
>>>>> Note that similar code exist in gcc.c.  Perhaps one day everything
>>>>> can be merged to the file-find files.
>>>>>
>>>>> Tested for Windows and GNU/Linux hosts and i686-pc-linux-gnu and
>>>>> arm-none-eabi targets.  OK?
>>>>>
>>>>> P.S. I am not quite sure what is best for the copyrights and contributed
>>>>> by comments in the file-find* files I added since that code was just moved.
>>>>> This patch drops the contributed by and keeps all the copyright dates from
>>>>> collect2.c.
>>>>>
>>>>> 2012-10-04  Meador Inge  <meadori@codesourcery.com>
>>>>>
>>>>>    * collect2.c (main): Call find_file_set_debug.
>>>>>    (find_a_find, add_prefix, prefix_from_env, prefix_from_string):
>>>>>    Factor out into ...
>>>>>    * file-find.c (New file): ... here and ...
>>>>>    * file-find.h (New file): ... here.
>>>>>    * gcc-ar.c (standard_exec_prefix): New variable.
>>>>>    (standard_libexec_prefix): Ditto.
>>>>>    (tooldir_base_prefix) Ditto.
>>>>>    (self_exec_prefix): Ditto.
>>>>>    (self_libexec_prefix): Ditto.
>>>>>    (self_tooldir_prefix): Ditto.
>>>>>    (target_version): Ditto.
>>>>>    (path): Ditto.
>>>>>    (target_path): Ditto.
>>>>>    (setup_prefixes): New function.
>>>>>    (main): Rework how wrapped programs are found.
>>>>>    * Makefile.in (OBJS-libcommon-target): Add file-find.o.
>>>>>    (AR_OBJS): New variable.
>>>>>    (gcc-ar$(exeext)): Add dependency on $(AR_OBJS).
>>>>>    (gcc-nm$(exeext)): Ditto.
>>>>>    (gcc-ranlib(exeext)): Ditto.
>>>>>    (COLLECT2_OBJS): Add file-find.o.
>>>>>    (collect2.o): Add file-find.h prerequisite.
>>>>>    (file-find.o): New rule.
>>>>>
>>>>> Index: gcc/gcc-ar.c
>>>>> ===================================================================
>>>>> --- gcc/gcc-ar.c   (revision 192099)
>>>>> +++ gcc/gcc-ar.c   (working copy)
>>>>> @@ -21,21 +21,110 @@
>>>>>  #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;
>>>>> -static const char *const target_machine = TARGET_MACHINE;
>>>>>
>>>>> +/* 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)
>>>>>  {
>>>>> -  const char *nprefix;
>>>>>    const char *exe_name;
>>>>>    char *plugin;
>>>>>    int k, status, err;
>>>>> @@ -44,37 +133,35 @@
>>>>>    bool is_ar = !strcmp (PERSONALITY, "ar");
>>>>>    int exit_code = FATAL_EXIT_CODE;
>>>>>
>>>>> -  exe_name = PERSONALITY;
>>>>> -#ifdef CROSS_DIRECTORY_STRUCTURE
>>>>> -  exe_name = concat (target_machine, "-", exe_name, NULL);
>>>>> -#endif
>>>>> +  setup_prefixes (av[0]);
>>>>>
>>>>> -  /* Find plugin */
>>>>> -  /* XXX implement more magic from gcc.c? */
>>>>> -  nprefix = getenv ("GCC_EXEC_PREFIX");
>>>>> -  if (!nprefix)
>>>>> -    nprefix = av[0];
>>>>> -  else
>>>>> -    nprefix = concat (nprefix, "gcc-" PERSONALITY, NULL);
>>>>> +  /* Find the GCC LTO plugin */
>>>>> +  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
>>>>> +  if (!plugin)
>>>>> +    {
>>>>> +      fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
>>>>> +      exit (1);
>>>>> +    }
>>>>>
>>>>> -  nprefix = make_relative_prefix (nprefix,
>>>>> -                            standard_bin_prefix,
>>>>> -                            standard_libexec_prefix);
>>>>> -  if (nprefix == NULL)
>>>>> -    nprefix = standard_libexec_prefix;
>>>>> +  /* Find the wrapped binutils program.  */
>>>>> +  exe_name = find_a_file (&target_path, PERSONALITY);
>>>>> +  if (!exe_name)
>>>>> +    {
>>>>> +#ifdef CROSS_DIRECTORY_STRUCTURE
>>>>> +      const char *cross_exe_name;
>>>>>
>>>>> -  plugin = concat (nprefix,
>>>>> -             dir_separator,
>>>>> -                   DEFAULT_TARGET_MACHINE,
>>>>> -             dir_separator,
>>>>> -             DEFAULT_TARGET_VERSION,
>>>>> -             dir_separator,
>>>>> -             LTOPLUGINSONAME,
>>>>> -             NULL);
>>>>> -  if (access (plugin, R_OK))
>>>>> -    {
>>>>> -      fprintf (stderr, "%s: Cannot find plugin %s\n", av[0], plugin);
>>>>> +      cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
>>>>> +      exe_name = find_a_file (&path, cross_exe_name);
>>>>> +      if (!exe_name)
>>>>> +  {
>>>>> +    fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
>>>>> +             cross_exe_name);
>>>>> +    exit (1);
>>>>> +  }
>>>>> +#else
>>>>> +      fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY);
>>>>>        exit (1);
>>>>> +#endif
>>>>>      }
>>>>>
>>>>>    /* Create new command line with plugin */
>>>>> Index: gcc/Makefile.in
>>>>> ===================================================================
>>>>> --- gcc/Makefile.in        (revision 192099)
>>>>> +++ gcc/Makefile.in        (working copy)
>>>>> @@ -1446,7 +1446,7 @@
>>>>>  # compiler and containing target-dependent code.
>>>>>  OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
>>>>>    opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
>>>>> -  hash-table.o
>>>>> +  hash-table.o file-find.o
>>>>>
>>>>>  # This lists all host objects for the front ends.
>>>>>  ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
>>>>> @@ -1827,19 +1827,20 @@
>>>>>  ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(EBITMAP_H)
>>>>>  sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
>>>>>
>>>>> +AR_OBJS = file-find.o
>>>>>  AR_LIBS = @COLLECT2_LIBS@
>>>>>
>>>>> -gcc-ar$(exeext): gcc-ar.o $(LIBDEPS)
>>>>> +gcc-ar$(exeext): gcc-ar.o $(AR_OBJS) $(LIBDEPS)
>>>>>    +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ar.o -o $@ \
>>>>> -          $(LIBS) $(AR_LIBS)
>>>>> +          $(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>>
>>>>> -gcc-nm$(exeext): gcc-nm.o $(LIBDEPS)
>>>>> +gcc-nm$(exeext): gcc-nm.o $(AR_OBJS) $(LIBDEPS)
>>>>>    +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-nm.o -o $@ \
>>>>> -          $(LIBS) $(AR_LIBS)
>>>>> +          $(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>>
>>>>> -gcc-ranlib$(exeext): gcc-ranlib.o $(LIBDEPS)
>>>>> +gcc-ranlib$(exeext): gcc-ranlib.o $(AR_OBJS) $(LIBDEPS)
>>>>>    +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) gcc-ranlib.o -o $@ \
>>>>> -          $(LIBS) $(AR_LIBS)
>>>>> +          $(AR_OBJS) $(LIBS) $(AR_LIBS)
>>>>>
>>>>>  CFLAGS-gcc-ar.o += $(DRIVER_DEFINES) \
>>>>>    -DTARGET_MACHINE=\"$(target_noncanonical)\" \
>>>>> @@ -1867,7 +1868,7 @@
>>>>>  gcc-nm.c: gcc-ar.c
>>>>>    cp $^ $@
>>>>>
>>>>> -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
>>>>> +COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o file-find.o
>>>>>  COLLECT2_LIBS = @COLLECT2_LIBS@
>>>>>  collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
>>>>>  # Don't try modifying collect2 (aka ld) in place--it might be linking this.
>>>>> @@ -1879,7 +1880,7 @@
>>>>>    @TARGET_SYSTEM_ROOT_DEFINE@
>>>>>  collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
>>>>>    $(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h \
>>>>> -  $(DIAGNOSTIC_H)
>>>>> +  $(DIAGNOSTIC_H) file-find.h
>>>>>
>>>>>  collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>>>>      collect2-aix.h
>>>>> @@ -3353,6 +3354,7 @@
>>>>>     $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
>>>>>     $(DF_H) $(CFGLOOP_H) $(RECOG_H) $(TARGET_H) \
>>>>>     $(REGS_H) hw-doloop.h
>>>>> +file-find.o: file-find.c $(CONFIG_H) $(SYSTEM_H) file-find.h
>>>>>  $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
>>>>>     $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
>>>>>     output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \
>>>>> Index: gcc/file-find.c
>>>>> ===================================================================
>>>>> --- gcc/file-find.c        (revision 0)
>>>>> +++ gcc/file-find.c        (revision 0)
>>>>> @@ -0,0 +1,194 @@
>>>>> +/* Utility functions for finding files relative to GCC binaries.
>>>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>>>> +
>>>>> +This file is part of GCC.
>>>>> +
>>>>> +GCC is free software; you can redistribute it and/or modify it under
>>>>> +the terms of the GNU General Public License as published by the Free
>>>>> +Software Foundation; either version 3, or (at your option) any later
>>>>> +version.
>>>>> +
>>>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>>>> +for more details.
>>>>> +
>>>>> +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 "config.h"
>>>>> +#include "system.h"
>>>>> +#include "filenames.h"
>>>>> +#include "file-find.h"
>>>>> +
>>>>> +static bool debug = false;
>>>>> +
>>>>> +void
>>>>> +find_file_set_debug(bool debug_state)
>>>>> +{
>>>>> +  debug = debug_state;
>>>>> +}
>>>>> +
>>>>> +char *
>>>>> +find_a_file (struct path_prefix *pprefix, const char *name)
>>>>> +{
>>>>> +  char *temp;
>>>>> +  struct prefix_list *pl;
>>>>> +  int len = pprefix->max_len + strlen (name) + 1;
>>>>> +
>>>>> +  if (debug)
>>>>> +    fprintf (stderr, "Looking for '%s'\n", name);
>>>>> +
>>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> +  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>>>> +#endif
>>>>> +
>>>>> +  temp = XNEWVEC (char, len);
>>>>> +
>>>>> +  /* Determine the filename to execute (special case for absolute paths).  */
>>>>> +
>>>>> +  if (IS_ABSOLUTE_PATH (name))
>>>>> +    {
>>>>> +      if (access (name, X_OK) == 0)
>>>>> +  {
>>>>> +    strcpy (temp, name);
>>>>> +
>>>>> +    if (debug)
>>>>> +      fprintf (stderr, "  - found: absolute path\n");
>>>>> +
>>>>> +    return temp;
>>>>> +  }
>>>>> +
>>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> +  /* Some systems have a suffix for executable files.
>>>>> +     So try appending that.  */
>>>>> +      strcpy (temp, name);
>>>>> +  strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>>> +
>>>>> +  if (access (temp, X_OK) == 0)
>>>>> +    return temp;
>>>>> +#endif
>>>>> +
>>>>> +      if (debug)
>>>>> +  fprintf (stderr, "  - failed to locate using absolute path\n");
>>>>> +    }
>>>>> +  else
>>>>> +    for (pl = pprefix->plist; pl; pl = pl->next)
>>>>> +      {
>>>>> +  struct stat st;
>>>>> +
>>>>> +  strcpy (temp, pl->prefix);
>>>>> +  strcat (temp, name);
>>>>> +
>>>>> +  if (stat (temp, &st) >= 0
>>>>> +      && ! S_ISDIR (st.st_mode)
>>>>> +      && access (temp, X_OK) == 0)
>>>>> +    return temp;
>>>>> +
>>>>> +#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> +  /* Some systems have a suffix for executable files.
>>>>> +     So try appending that.  */
>>>>> +  strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>>> +
>>>>> +  if (stat (temp, &st) >= 0
>>>>> +      && ! S_ISDIR (st.st_mode)
>>>>> +      && access (temp, X_OK) == 0)
>>>>> +    return temp;
>>>>> +#endif
>>>>> +      }
>>>>> +
>>>>> +  if (debug && pprefix->plist == NULL)
>>>>> +    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>>>> +
>>>>> +  free (temp);
>>>>> +  return 0;
>>>>> +}
>>>>> +
>>>>> +/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>>>> +
>>>>> +void
>>>>> +add_prefix (struct path_prefix *pprefix, const char *prefix)
>>>>> +{
>>>>> +  struct prefix_list *pl, **prev;
>>>>> +  int len;
>>>>> +
>>>>> +  if (pprefix->plist)
>>>>> +    {
>>>>> +      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>>>> +  ;
>>>>> +      prev = &pl->next;
>>>>> +    }
>>>>> +  else
>>>>> +    prev = &pprefix->plist;
>>>>> +
>>>>> +  /* Keep track of the longest prefix.  */
>>>>> +
>>>>> +  len = strlen (prefix);
>>>>> +  if (len > pprefix->max_len)
>>>>> +    pprefix->max_len = len;
>>>>> +
>>>>> +  pl = XNEW (struct prefix_list);
>>>>> +  pl->prefix = xstrdup (prefix);
>>>>> +
>>>>> +  if (*prev)
>>>>> +    pl->next = *prev;
>>>>> +  else
>>>>> +    pl->next = (struct prefix_list *) 0;
>>>>> +  *prev = pl;
>>>>> +}
>>>>> +
>>>>> +/* Take the value of the environment variable ENV, break it into a path, and
>>>>> +   add of the entries to PPREFIX.  */
>>>>> +
>>>>> +void
>>>>> +prefix_from_env (const char *env, struct path_prefix *pprefix)
>>>>> +{
>>>>> +  const char *p;
>>>>> +  p = getenv (env);
>>>>> +
>>>>> +  if (p)
>>>>> +    prefix_from_string (p, pprefix);
>>>>> +}
>>>>> +
>>>>> +void
>>>>> +prefix_from_string (const char *p, struct path_prefix *pprefix)
>>>>> +{
>>>>> +  const char *startp, *endp;
>>>>> +  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>>>> +
>>>>> +  if (debug)
>>>>> +    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>>>> +
>>>>> +  startp = endp = p;
>>>>> +  while (1)
>>>>> +    {
>>>>> +      if (*endp == PATH_SEPARATOR || *endp == 0)
>>>>> +  {
>>>>> +    strncpy (nstore, startp, endp-startp);
>>>>> +    if (endp == startp)
>>>>> +      {
>>>>> +        strcpy (nstore, "./");
>>>>> +      }
>>>>> +    else if (! IS_DIR_SEPARATOR (endp[-1]))
>>>>> +      {
>>>>> +        nstore[endp-startp] = DIR_SEPARATOR;
>>>>> +        nstore[endp-startp+1] = 0;
>>>>> +      }
>>>>> +    else
>>>>> +      nstore[endp-startp] = 0;
>>>>> +
>>>>> +    if (debug)
>>>>> +      fprintf (stderr, "  - add prefix: %s\n", nstore);
>>>>> +
>>>>> +    add_prefix (pprefix, nstore);
>>>>> +    if (*endp == 0)
>>>>> +      break;
>>>>> +    endp = startp = endp + 1;
>>>>> +  }
>>>>> +      else
>>>>> +  endp++;
>>>>> +    }
>>>>> +  free (nstore);
>>>>> +}
>>>>> Index: gcc/file-find.h
>>>>> ===================================================================
>>>>> --- gcc/file-find.h        (revision 0)
>>>>> +++ gcc/file-find.h        (revision 0)
>>>>> @@ -0,0 +1,47 @@
>>>>> +/* Prototypes and data structures used for implementing functions for
>>>>> +   finding files relative to GCC binaries.
>>>>> +   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
>>>>> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
>>>>> +
>>>>> +This file is part of GCC.
>>>>> +
>>>>> +GCC is free software; you can redistribute it and/or modify it under
>>>>> +the terms of the GNU General Public License as published by the Free
>>>>> +Software Foundation; either version 3, or (at your option) any later
>>>>> +version.
>>>>> +
>>>>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>>>>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>>>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>>>>> +for more details.
>>>>> +
>>>>> +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/>.  */
>>>>> +
>>>>> +#ifndef GCC_FILE_FIND_H
>>>>> +#define GCC_FILE_FIND_H
>>>>> +
>>>>> +/* Structure to hold all the directories in which to search for files to
>>>>> +   execute.  */
>>>>> +
>>>>> +struct prefix_list
>>>>> +{
>>>>> +  const char *prefix;         /* String to prepend to the path.  */
>>>>> +  struct prefix_list *next;   /* Next in linked list.  */
>>>>> +};
>>>>> +
>>>>> +struct path_prefix
>>>>> +{
>>>>> +  struct prefix_list *plist;  /* List of prefixes to try */
>>>>> +  int max_len;                /* Max length of a prefix in PLIST */
>>>>> +  const char *name;           /* Name of this list (used in config stuff) */
>>>>> +};
>>>>> +
>>>>> +extern void find_file_set_debug (bool);
>>>>> +extern char *find_a_file (struct path_prefix *, const char *);
>>>>> +extern void add_prefix (struct path_prefix *, const char *);
>>>>> +extern void prefix_from_env (const char *, struct path_prefix *);
>>>>> +extern void prefix_from_string (const char *, struct path_prefix *);
>>>>> +
>>>>> +#endif /* GCC_FILE_FIND_H */
>>>>> Index: gcc/collect2.c
>>>>> ===================================================================
>>>>> --- gcc/collect2.c (revision 192099)
>>>>> +++ gcc/collect2.c (working copy)
>>>>> @@ -31,6 +31,7 @@
>>>>>  #include "coretypes.h"
>>>>>  #include "tm.h"
>>>>>  #include "filenames.h"
>>>>> +#include "file-find.h"
>>>>>
>>>>>  /* TARGET_64BIT may be defined to use driver specific functionality. */
>>>>>  #undef TARGET_64BIT
>>>>> @@ -243,22 +244,6 @@
>>>>>     would leave untouched.  */
>>>>>  bool may_unlink_output_file = false;
>>>>>
>>>>> -/* Structure to hold all the directories in which to search for files to
>>>>> -   execute.  */
>>>>> -
>>>>> -struct prefix_list
>>>>> -{
>>>>> -  const char *prefix;         /* String to prepend to the path.  */
>>>>> -  struct prefix_list *next;   /* Next in linked list.  */
>>>>> -};
>>>>> -
>>>>> -struct path_prefix
>>>>> -{
>>>>> -  struct prefix_list *plist;  /* List of prefixes to try */
>>>>> -  int max_len;                /* Max length of a prefix in PLIST */
>>>>> -  const char *name;           /* Name of this list (used in config stuff) */
>>>>> -};
>>>>> -
>>>>>  #ifdef COLLECT_EXPORT_LIST
>>>>>  /* Lists to keep libraries to be scanned for global constructors/destructors.  */
>>>>>  static struct head libs;                    /* list of libraries */
>>>>> @@ -302,10 +287,6 @@
>>>>>  static symkind is_ctor_dtor (const char *);
>>>>>
>>>>>  static void handler (int);
>>>>> -static char *find_a_file (struct path_prefix *, const char *);
>>>>> -static void add_prefix (struct path_prefix *, const char *);
>>>>> -static void prefix_from_env (const char *, struct path_prefix *);
>>>>> -static void prefix_from_string (const char *, struct path_prefix *);
>>>>>  static void do_wait (const char *, struct pex_obj *);
>>>>>  static void fork_execute (const char *, char **);
>>>>>  static void maybe_unlink (const char *);
>>>>> @@ -653,168 +634,6 @@
>>>>>
>>>>>     Return 0 if not found, otherwise return its name, allocated with malloc.  */
>>>>>
>>>>> -static char *
>>>>> -find_a_file (struct path_prefix *pprefix, const char *name)
>>>>> -{
>>>>> -  char *temp;
>>>>> -  struct prefix_list *pl;
>>>>> -  int len = pprefix->max_len + strlen (name) + 1;
>>>>> -
>>>>> -  if (debug)
>>>>> -    fprintf (stderr, "Looking for '%s'\n", name);
>>>>> -
>>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> -  len += strlen (HOST_EXECUTABLE_SUFFIX);
>>>>> -#endif
>>>>> -
>>>>> -  temp = XNEWVEC (char, len);
>>>>> -
>>>>> -  /* Determine the filename to execute (special case for absolute paths).  */
>>>>> -
>>>>> -  if (IS_ABSOLUTE_PATH (name))
>>>>> -    {
>>>>> -      if (access (name, X_OK) == 0)
>>>>> -  {
>>>>> -    strcpy (temp, name);
>>>>> -
>>>>> -    if (debug)
>>>>> -      fprintf (stderr, "  - found: absolute path\n");
>>>>> -
>>>>> -    return temp;
>>>>> -  }
>>>>> -
>>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> -  /* Some systems have a suffix for executable files.
>>>>> -     So try appending that.  */
>>>>> -      strcpy (temp, name);
>>>>> -  strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>>> -
>>>>> -  if (access (temp, X_OK) == 0)
>>>>> -    return temp;
>>>>> -#endif
>>>>> -
>>>>> -      if (debug)
>>>>> -  fprintf (stderr, "  - failed to locate using absolute path\n");
>>>>> -    }
>>>>> -  else
>>>>> -    for (pl = pprefix->plist; pl; pl = pl->next)
>>>>> -      {
>>>>> -  struct stat st;
>>>>> -
>>>>> -  strcpy (temp, pl->prefix);
>>>>> -  strcat (temp, name);
>>>>> -
>>>>> -  if (stat (temp, &st) >= 0
>>>>> -      && ! S_ISDIR (st.st_mode)
>>>>> -      && access (temp, X_OK) == 0)
>>>>> -    return temp;
>>>>> -
>>>>> -#ifdef HOST_EXECUTABLE_SUFFIX
>>>>> -  /* Some systems have a suffix for executable files.
>>>>> -     So try appending that.  */
>>>>> -  strcat (temp, HOST_EXECUTABLE_SUFFIX);
>>>>> -
>>>>> -  if (stat (temp, &st) >= 0
>>>>> -      && ! S_ISDIR (st.st_mode)
>>>>> -      && access (temp, X_OK) == 0)
>>>>> -    return temp;
>>>>> -#endif
>>>>> -      }
>>>>> -
>>>>> -  if (debug && pprefix->plist == NULL)
>>>>> -    fprintf (stderr, "  - failed: no entries in prefix list\n");
>>>>> -
>>>>> -  free (temp);
>>>>> -  return 0;
>>>>> -}
>>>>> -
>>>>> -/* Add an entry for PREFIX to prefix list PPREFIX.  */
>>>>> -
>>>>> -static void
>>>>> -add_prefix (struct path_prefix *pprefix, const char *prefix)
>>>>> -{
>>>>> -  struct prefix_list *pl, **prev;
>>>>> -  int len;
>>>>> -
>>>>> -  if (pprefix->plist)
>>>>> -    {
>>>>> -      for (pl = pprefix->plist; pl->next; pl = pl->next)
>>>>> -  ;
>>>>> -      prev = &pl->next;
>>>>> -    }
>>>>> -  else
>>>>> -    prev = &pprefix->plist;
>>>>> -
>>>>> -  /* Keep track of the longest prefix.  */
>>>>> -
>>>>> -  len = strlen (prefix);
>>>>> -  if (len > pprefix->max_len)
>>>>> -    pprefix->max_len = len;
>>>>> -
>>>>> -  pl = XNEW (struct prefix_list);
>>>>> -  pl->prefix = xstrdup (prefix);
>>>>> -
>>>>> -  if (*prev)
>>>>> -    pl->next = *prev;
>>>>> -  else
>>>>> -    pl->next = (struct prefix_list *) 0;
>>>>> -  *prev = pl;
>>>>> -}
>>>>> -
>>>>> -/* Take the value of the environment variable ENV, break it into a path, and
>>>>> -   add of the entries to PPREFIX.  */
>>>>> -
>>>>> -static void
>>>>> -prefix_from_env (const char *env, struct path_prefix *pprefix)
>>>>> -{
>>>>> -  const char *p;
>>>>> -  p = getenv (env);
>>>>> -
>>>>> -  if (p)
>>>>> -    prefix_from_string (p, pprefix);
>>>>> -}
>>>>> -
>>>>> -static void
>>>>> -prefix_from_string (const char *p, struct path_prefix *pprefix)
>>>>> -{
>>>>> -  const char *startp, *endp;
>>>>> -  char *nstore = XNEWVEC (char, strlen (p) + 3);
>>>>> -
>>>>> -  if (debug)
>>>>> -    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
>>>>> -
>>>>> -  startp = endp = p;
>>>>> -  while (1)
>>>>> -    {
>>>>> -      if (*endp == PATH_SEPARATOR || *endp == 0)
>>>>> -  {
>>>>> -    strncpy (nstore, startp, endp-startp);
>>>>> -    if (endp == startp)
>>>>> -      {
>>>>> -        strcpy (nstore, "./");
>>>>> -      }
>>>>> -    else if (! IS_DIR_SEPARATOR (endp[-1]))
>>>>> -      {
>>>>> -        nstore[endp-startp] = DIR_SEPARATOR;
>>>>> -        nstore[endp-startp+1] = 0;
>>>>> -      }
>>>>> -    else
>>>>> -      nstore[endp-startp] = 0;
>>>>> -
>>>>> -    if (debug)
>>>>> -      fprintf (stderr, "  - add prefix: %s\n", nstore);
>>>>> -
>>>>> -    add_prefix (pprefix, nstore);
>>>>> -    if (*endp == 0)
>>>>> -      break;
>>>>> -    endp = startp = endp + 1;
>>>>> -  }
>>>>> -      else
>>>>> -  endp++;
>>>>> -    }
>>>>> -  free (nstore);
>>>>> -}
>>>>> -
>>>>>  #ifdef OBJECT_FORMAT_NONE
>>>>>
>>>>>  /* Add an entry for the object file NAME to object file list LIST.
>>>>> @@ -1198,6 +1017,7 @@
>>>>>  #endif
>>>>>        }
>>>>>      vflag = debug;
>>>>> +    find_file_set_debug (debug);
>>>>>      if (no_partition && lto_mode == LTO_MODE_WHOPR)
>>>>>        lto_mode = LTO_MODE_LTO;
>>>>>    }
>>>>
>>>>
>>>
>>>
>>
>>
>
>
> --
> Meador Inge
> CodeSourcery / Mentor Embedded
> http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-11-26 15:06         ` Richard Biener
@ 2012-11-27 18:14           ` Meador Inge
  2013-06-19 12:03             ` Matthias Klose
  0 siblings, 1 reply; 16+ messages in thread
From: Meador Inge @ 2012-11-27 18:14 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On 11/26/2012 09:05 AM, Richard Biener wrote:

> On Wed, Nov 7, 2012 at 10:51 PM, Meador Inge <meadori@codesourcery.com> wrote:
>> Ping ^ 4.
> 
> Ok.

Thanks for the review.  Committed to trunk.

-- 
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2012-11-27 18:14           ` Meador Inge
@ 2013-06-19 12:03             ` Matthias Klose
  2013-06-19 12:10               ` Jakub Jelinek
  2013-06-19 12:20               ` Matthias Klose
  0 siblings, 2 replies; 16+ messages in thread
From: Matthias Klose @ 2013-06-19 12:03 UTC (permalink / raw)
  To: Meador Inge; +Cc: Richard Biener, gcc-patches

Am 27.11.2012 19:14, schrieb Meador Inge:
> On 11/26/2012 09:05 AM, Richard Biener wrote:
> 
>> On Wed, Nov 7, 2012 at 10:51 PM, Meador Inge <meadori@codesourcery.com> wrote:
>>> Ping ^ 4.
>>
>> Ok.
> 
> Thanks for the review.  Committed to trunk.

This did break gcc-ar and gcc-nm; now a regression on the 4.8 branch.

$ gcc-ar-4.8 -h
gcc-ar-4.8: Cannot find plugin 'liblto_plugin.so'

the plugin is *not* installed with x permission flags (which seems to be the
standard for shared libraries).   You did change the code to use find_a_file
which searches only for files with the x bit set.

Work around is to install the plugin with the x bits set, or use some helper
function which doesn't look for the x bits.  I assume that wasn't catched,
because the plugin then was found in another location?

  Matthias

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2013-06-19 12:03             ` Matthias Klose
@ 2013-06-19 12:10               ` Jakub Jelinek
  2013-06-19 15:29                 ` Matthias Klose
  2013-06-19 12:20               ` Matthias Klose
  1 sibling, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2013-06-19 12:10 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Meador Inge, Richard Biener, gcc-patches

On Wed, Jun 19, 2013 at 02:03:34PM +0200, Matthias Klose wrote:
> Am 27.11.2012 19:14, schrieb Meador Inge:
> > On 11/26/2012 09:05 AM, Richard Biener wrote:
> > 
> >> On Wed, Nov 7, 2012 at 10:51 PM, Meador Inge <meadori@codesourcery.com> wrote:
> >>> Ping ^ 4.
> >>
> >> Ok.
> > 
> > Thanks for the review.  Committed to trunk.
> 
> This did break gcc-ar and gcc-nm; now a regression on the 4.8 branch.
> 
> $ gcc-ar-4.8 -h
> gcc-ar-4.8: Cannot find plugin 'liblto_plugin.so'
> 
> the plugin is *not* installed with x permission flags (which seems to be the
> standard for shared libraries).   You did change the code to use find_a_file
> which searches only for files with the x bit set.

That actually is the standard for shared libraries, the linker creates
libraries with those permissions and libtool/automake installs them that way
too.  So if you override this, you need to cope with that decision.

	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2013-06-19 12:03             ` Matthias Klose
  2013-06-19 12:10               ` Jakub Jelinek
@ 2013-06-19 12:20               ` Matthias Klose
  1 sibling, 0 replies; 16+ messages in thread
From: Matthias Klose @ 2013-06-19 12:20 UTC (permalink / raw)
  Cc: Meador Inge, Richard Biener, gcc-patches

Am 19.06.2013 14:03, schrieb Matthias Klose:
> $ gcc-ar-4.8 -h
> gcc-ar-4.8: Cannot find plugin 'liblto_plugin.so'
> 
> the plugin is *not* installed with x permission flags (which seems to be the
> standard for shared libraries).   You did change the code to use find_a_file
> which searches only for files with the x bit set.
> 
> Work around is to install the plugin with the x bits set, or use some helper
> function which doesn't look for the x bits.  I assume that wasn't catched,
> because the plugin then was found in another location?

openend 57651 for that.

now, working around the permission bit, I get:

$ gcc-ar-4.8
gcc-ar-4.8: Cannot find binary 'ar'

so it only searches ar in the given paths, not on the path of the file system
(/usr/bin in this case)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2013-06-19 12:10               ` Jakub Jelinek
@ 2013-06-19 15:29                 ` Matthias Klose
  2013-06-19 17:47                   ` Jakub Jelinek
  0 siblings, 1 reply; 16+ messages in thread
From: Matthias Klose @ 2013-06-19 15:29 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Meador Inge, Richard Biener, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1165 bytes --]

Am 19.06.2013 14:10, schrieb Jakub Jelinek:
> On Wed, Jun 19, 2013 at 02:03:34PM +0200, Matthias Klose wrote:
>> Am 27.11.2012 19:14, schrieb Meador Inge:
>>> On 11/26/2012 09:05 AM, Richard Biener wrote:
>>>
>>>> On Wed, Nov 7, 2012 at 10:51 PM, Meador Inge <meadori@codesourcery.com> wrote:
>>>>> Ping ^ 4.
>>>>
>>>> Ok.
>>>
>>> Thanks for the review.  Committed to trunk.
>>
>> This did break gcc-ar and gcc-nm; now a regression on the 4.8 branch.
>>
>> $ gcc-ar-4.8 -h
>> gcc-ar-4.8: Cannot find plugin 'liblto_plugin.so'
>>
>> the plugin is *not* installed with x permission flags (which seems to be the
>> standard for shared libraries).   You did change the code to use find_a_file
>> which searches only for files with the x bit set.
> 
> That actually is the standard for shared libraries, the linker creates
> libraries with those permissions and libtool/automake installs them that way
> too.  So if you override this, you need to cope with that decision.

well, I did fix this assumption last year in gcc.c, then lets fix it in other
places too, just adding a mode parameter to the public find_a_file function.
Testing the attached patch.

  Matthias



[-- Attachment #2: ff.diff --]
[-- Type: text/plain, Size: 6200 bytes --]

Index: gcc-ar.c
===================================================================
--- gcc-ar.c	(revision 200203)
+++ gcc-ar.c	(working copy)
@@ -136,7 +136,7 @@
   setup_prefixes (av[0]);
 
   /* Find the GCC LTO plugin */
-  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
+  plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK);
   if (!plugin)
     {
       fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
@@ -151,7 +151,7 @@
       const char *cross_exe_name;
 
       cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
-      exe_name = find_a_file (&path, cross_exe_name);
+      exe_name = find_a_file (&path, cross_exe_name, X_OK);
       if (!exe_name)
 	{
 	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
Index: file-find.c
===================================================================
--- file-find.c	(revision 200203)
+++ file-find.c	(working copy)
@@ -31,7 +31,7 @@
 }
 
 char *
-find_a_file (struct path_prefix *pprefix, const char *name)
+find_a_file (struct path_prefix *pprefix, const char *name, int mode)
 {
   char *temp;
   struct prefix_list *pl;
@@ -50,7 +50,7 @@
 
   if (IS_ABSOLUTE_PATH (name))
     {
-      if (access (name, X_OK) == 0)
+      if (access (name, mode) == 0)
 	{
 	  strcpy (temp, name);
 
@@ -66,7 +66,7 @@
       strcpy (temp, name);
 	strcat (temp, HOST_EXECUTABLE_SUFFIX);
 
-	if (access (temp, X_OK) == 0)
+	if (access (temp, mode) == 0)
 	  return temp;
 #endif
 
@@ -83,7 +83,7 @@
 
 	if (stat (temp, &st) >= 0
 	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
+	    && access (temp, mode) == 0)
 	  return temp;
 
 #ifdef HOST_EXECUTABLE_SUFFIX
@@ -93,7 +93,7 @@
 
 	if (stat (temp, &st) >= 0
 	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
+	    && access (temp, mode) == 0)
 	  return temp;
 #endif
       }
Index: file-find.h
===================================================================
--- file-find.h	(revision 200203)
+++ file-find.h	(working copy)
@@ -38,7 +38,7 @@
 };
 
 extern void find_file_set_debug (bool);
-extern char *find_a_file (struct path_prefix *, const char *);
+extern char *find_a_file (struct path_prefix *, const char *, int mode);
 extern void add_prefix (struct path_prefix *, const char *);
 extern void prefix_from_env (const char *, struct path_prefix *);
 extern void prefix_from_string (const char *, struct path_prefix *);
Index: collect2.c
===================================================================
--- collect2.c	(revision 200203)
+++ collect2.c	(working copy)
@@ -1110,55 +1110,55 @@
   if (ld_file_name == 0)
 #endif
 #ifdef REAL_LD_FILE_NAME
-  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
+    ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME, X_OK);
   if (ld_file_name == 0)
 #endif
   /* Search the (target-specific) compiler dirs for ld'.  */
-  ld_file_name = find_a_file (&cpath, real_ld_suffix);
+    ld_file_name = find_a_file (&cpath, real_ld_suffix, X_OK);
   /* Likewise for `collect-ld'.  */
   if (ld_file_name == 0)
     {
-      ld_file_name = find_a_file (&cpath, collect_ld_suffix);
+      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]);
+    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]);
+    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);
+  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
   if (nm_file_name == 0)
 #endif
-  nm_file_name = find_a_file (&cpath, gnm_suffix);
+    nm_file_name = find_a_file (&cpath, gnm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&path, full_gnm_suffix);
+    nm_file_name = find_a_file (&path, full_gnm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&cpath, nm_suffix);
+    nm_file_name = find_a_file (&cpath, nm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&path, full_nm_suffix);
+    nm_file_name = find_a_file (&path, full_nm_suffix, X_OK);
 
 #ifdef LDD_SUFFIX
-  ldd_file_name = find_a_file (&cpath, ldd_suffix);
+  ldd_file_name = find_a_file (&cpath, ldd_suffix, X_OK);
   if (ldd_file_name == 0)
-    ldd_file_name = find_a_file (&path, full_ldd_suffix);
+    ldd_file_name = find_a_file (&path, full_ldd_suffix, X_OK);
 #endif
 
 #ifdef REAL_STRIP_FILE_NAME
-  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
+  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME, X_OK);
   if (strip_file_name == 0)
 #endif
-  strip_file_name = find_a_file (&cpath, gstrip_suffix);
+    strip_file_name = find_a_file (&cpath, gstrip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&path, full_gstrip_suffix);
+    strip_file_name = find_a_file (&path, full_gstrip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&cpath, strip_suffix);
+    strip_file_name = find_a_file (&cpath, strip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&path, full_strip_suffix);
+    strip_file_name = find_a_file (&path, full_strip_suffix, X_OK);
 
   /* Determine the full path name of the C compiler to use.  */
   c_file_name = getenv ("COLLECT_GCC");
@@ -1171,12 +1171,12 @@
 #endif
     }
 
-  p = find_a_file (&cpath, c_file_name);
+  p = find_a_file (&cpath, c_file_name, X_OK);
 
   /* Here it should be safe to use the system search path since we should have
      already qualified the name of the compiler when it is needed.  */
   if (p == 0)
-    p = find_a_file (&path, c_file_name);
+    p = find_a_file (&path, c_file_name, X_OK);
 
   if (p)
     c_file_name = p;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2013-06-19 15:29                 ` Matthias Klose
@ 2013-06-19 17:47                   ` Jakub Jelinek
  2013-06-19 20:58                     ` Matthias Klose
  0 siblings, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2013-06-19 17:47 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Meador Inge, Richard Biener, gcc-patches

On Wed, Jun 19, 2013 at 05:29:42PM +0200, Matthias Klose wrote:
> well, I did fix this assumption last year in gcc.c, then lets fix it in other
> places too, just adding a mode parameter to the public find_a_file function.
> Testing the attached patch.

Ok, provided you:
1) write proper ChangeLog
2) adjust the gcc-ar.c change (because it won't apply cleanly now that
   I've committed the other gcc-ar.c fix
3) 
> --- file-find.h	(revision 200203)
> +++ file-find.h	(working copy)
> @@ -38,7 +38,7 @@
>  };
>  
>  extern void find_file_set_debug (bool);
> -extern char *find_a_file (struct path_prefix *, const char *);
> +extern char *find_a_file (struct path_prefix *, const char *, int mode);

Remove " mode" above, none of the arguments have names, so adding it
is both inconsistent and useless.

4)
>    if (ld_file_name == 0)
> -    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker]);
> +    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);

This line looks too long now.

	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self
  2013-06-19 17:47                   ` Jakub Jelinek
@ 2013-06-19 20:58                     ` Matthias Klose
  0 siblings, 0 replies; 16+ messages in thread
From: Matthias Klose @ 2013-06-19 20:58 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Meador Inge, Richard Biener, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1230 bytes --]

Am 19.06.2013 19:46, schrieb Jakub Jelinek:
> On Wed, Jun 19, 2013 at 05:29:42PM +0200, Matthias Klose wrote:
>> well, I did fix this assumption last year in gcc.c, then lets fix it in other
>> places too, just adding a mode parameter to the public find_a_file function.
>> Testing the attached patch.
> 
> Ok, provided you:
> 1) write proper ChangeLog
> 2) adjust the gcc-ar.c change (because it won't apply cleanly now that
>    I've committed the other gcc-ar.c fix
> 3) 
>> --- file-find.h	(revision 200203)
>> +++ file-find.h	(working copy)
>> @@ -38,7 +38,7 @@
>>  };
>>  
>>  extern void find_file_set_debug (bool);
>> -extern char *find_a_file (struct path_prefix *, const char *);
>> +extern char *find_a_file (struct path_prefix *, const char *, int mode);
> 
> Remove " mode" above, none of the arguments have names, so adding it
> is both inconsistent and useless.
> 
> 4)
>>    if (ld_file_name == 0)
>> -    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker]);
>> +    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
> 
> This line looks too long now.

addressed 1-3, the semicolon is in column 79. committed to the trunk and the 4.8
branch as attached.

  Matthias




[-- Attachment #2: ff.diff --]
[-- Type: text/plain, Size: 6736 bytes --]

2013-06-19  Matthias Klose  <doko@ubuntu.com>

	PR driver/57651
	* file-find.h (find_a_file): Add a mode parameter.
	* file-find.c (find_a_file): Likewise.
	* gcc-ar.c (main): Call find_a_file with R_OK for the plugin,
	with X_OK for the executables.
	* collect2.c (main): Call find_a_file with X_OK.

Index: gcc-ar.c
===================================================================
--- gcc-ar.c	(revision 200217)
+++ gcc-ar.c	(working copy)
@@ -136,7 +136,7 @@
   setup_prefixes (av[0]);
 
   /* Find the GCC LTO plugin */
-  plugin = find_a_file (&target_path, LTOPLUGINSONAME);
+  plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK);
   if (!plugin)
     {
       fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
@@ -144,14 +144,14 @@
     }
 
   /* Find the wrapped binutils program.  */
-  exe_name = find_a_file (&target_path, PERSONALITY);
+  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);
+      exe_name = find_a_file (&path, real_exe_name, X_OK);
       if (!exe_name)
 	{
 	  fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
Index: file-find.c
===================================================================
--- file-find.c	(revision 200217)
+++ file-find.c	(working copy)
@@ -31,7 +31,7 @@
 }
 
 char *
-find_a_file (struct path_prefix *pprefix, const char *name)
+find_a_file (struct path_prefix *pprefix, const char *name, int mode)
 {
   char *temp;
   struct prefix_list *pl;
@@ -50,7 +50,7 @@
 
   if (IS_ABSOLUTE_PATH (name))
     {
-      if (access (name, X_OK) == 0)
+      if (access (name, mode) == 0)
 	{
 	  strcpy (temp, name);
 
@@ -66,7 +66,7 @@
       strcpy (temp, name);
 	strcat (temp, HOST_EXECUTABLE_SUFFIX);
 
-	if (access (temp, X_OK) == 0)
+	if (access (temp, mode) == 0)
 	  return temp;
 #endif
 
@@ -83,7 +83,7 @@
 
 	if (stat (temp, &st) >= 0
 	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
+	    && access (temp, mode) == 0)
 	  return temp;
 
 #ifdef HOST_EXECUTABLE_SUFFIX
@@ -93,7 +93,7 @@
 
 	if (stat (temp, &st) >= 0
 	    && ! S_ISDIR (st.st_mode)
-	    && access (temp, X_OK) == 0)
+	    && access (temp, mode) == 0)
 	  return temp;
 #endif
       }
Index: file-find.h
===================================================================
--- file-find.h	(revision 200217)
+++ file-find.h	(working copy)
@@ -38,7 +38,7 @@
 };
 
 extern void find_file_set_debug (bool);
-extern char *find_a_file (struct path_prefix *, const char *);
+extern char *find_a_file (struct path_prefix *, const char *, int);
 extern void add_prefix (struct path_prefix *, const char *);
 extern void prefix_from_env (const char *, struct path_prefix *);
 extern void prefix_from_string (const char *, struct path_prefix *);
Index: collect2.c
===================================================================
--- collect2.c	(revision 200217)
+++ collect2.c	(working copy)
@@ -1110,55 +1110,55 @@
   if (ld_file_name == 0)
 #endif
 #ifdef REAL_LD_FILE_NAME
-  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
+  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME, X_OK);
   if (ld_file_name == 0)
 #endif
   /* Search the (target-specific) compiler dirs for ld'.  */
-  ld_file_name = find_a_file (&cpath, real_ld_suffix);
+  ld_file_name = find_a_file (&cpath, real_ld_suffix, X_OK);
   /* Likewise for `collect-ld'.  */
   if (ld_file_name == 0)
     {
-      ld_file_name = find_a_file (&cpath, collect_ld_suffix);
+      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]);
+    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]);
+    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);
+  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
   if (nm_file_name == 0)
 #endif
-  nm_file_name = find_a_file (&cpath, gnm_suffix);
+  nm_file_name = find_a_file (&cpath, gnm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&path, full_gnm_suffix);
+    nm_file_name = find_a_file (&path, full_gnm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&cpath, nm_suffix);
+    nm_file_name = find_a_file (&cpath, nm_suffix, X_OK);
   if (nm_file_name == 0)
-    nm_file_name = find_a_file (&path, full_nm_suffix);
+    nm_file_name = find_a_file (&path, full_nm_suffix, X_OK);
 
 #ifdef LDD_SUFFIX
-  ldd_file_name = find_a_file (&cpath, ldd_suffix);
+  ldd_file_name = find_a_file (&cpath, ldd_suffix, X_OK);
   if (ldd_file_name == 0)
-    ldd_file_name = find_a_file (&path, full_ldd_suffix);
+    ldd_file_name = find_a_file (&path, full_ldd_suffix, X_OK);
 #endif
 
 #ifdef REAL_STRIP_FILE_NAME
-  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
+  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME, X_OK);
   if (strip_file_name == 0)
 #endif
-  strip_file_name = find_a_file (&cpath, gstrip_suffix);
+  strip_file_name = find_a_file (&cpath, gstrip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&path, full_gstrip_suffix);
+    strip_file_name = find_a_file (&path, full_gstrip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&cpath, strip_suffix);
+    strip_file_name = find_a_file (&cpath, strip_suffix, X_OK);
   if (strip_file_name == 0)
-    strip_file_name = find_a_file (&path, full_strip_suffix);
+    strip_file_name = find_a_file (&path, full_strip_suffix, X_OK);
 
   /* Determine the full path name of the C compiler to use.  */
   c_file_name = getenv ("COLLECT_GCC");
@@ -1171,12 +1171,12 @@
 #endif
     }
 
-  p = find_a_file (&cpath, c_file_name);
+  p = find_a_file (&cpath, c_file_name, X_OK);
 
   /* Here it should be safe to use the system search path since we should have
      already qualified the name of the compiler when it is needed.  */
   if (p == 0)
-    p = find_a_file (&path, c_file_name);
+    p = find_a_file (&path, c_file_name, X_OK);
 
   if (p)
     c_file_name = p;

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-06-19 20:58 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-04 20:46 [PATCH] gcc-{ar,nm,ranlib}: Find binutils binaries relative to self Meador Inge
2012-10-10  2:47 ` Meador Inge
2012-10-18 15:39   ` Meador Inge
2012-10-18 19:08     ` Bernhard Reutner-Fischer
2012-10-19 21:55       ` Meador Inge
2012-10-19 22:26     ` Meador Inge
2012-10-29 16:10     ` Meador Inge
2012-11-07 21:51       ` Meador Inge
2012-11-26 15:06         ` Richard Biener
2012-11-27 18:14           ` Meador Inge
2013-06-19 12:03             ` Matthias Klose
2013-06-19 12:10               ` Jakub Jelinek
2013-06-19 15:29                 ` Matthias Klose
2013-06-19 17:47                   ` Jakub Jelinek
2013-06-19 20:58                     ` Matthias Klose
2013-06-19 12:20               ` Matthias Klose

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).