Message ID | 1349383546-25548-1-git-send-email-meadori@codesourcery.com |
---|---|
State | New |
Headers | show |
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; > }
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; >> } > >
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
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
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; >>> -} >>> - >>> -/* 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; >>> } >> >> > >
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; >>> } >> >> > >
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; >>>> -} >>>> - >>>> -/* 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; >>>> } >>> >>> >> >> > >
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
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.
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
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
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)
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; }