diff options
author | noer <noer@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-19 23:16:29 +0000 |
---|---|---|
committer | noer <noer@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-19 23:16:29 +0000 |
commit | 98042d819f812ef29254d457445089aa51a2fcde (patch) | |
tree | 8d62f0b8f7ec6ba0ebf57799b2febd697248caff | |
parent | 1d23f0ca80f14fae99c581b777b8307a9080ef8b (diff) |
Fri Mar 13 17:54:04 1998 Michael Meissner <meissner@cygnus.com>
* gcc.c (DIR_UP): If not defined, define as "..".
(standard_bindir_prefix): New static, holds target location to
install binaries.
(split_directories): New function to split a filename into
component directories.
(free_split_directories): New function, release memory allocated
by split_directories.
(make_relative_prefix): New function, make a relative pathname if
the compiler is not in the expected location.
(process_command): Use GET_ENVIRONMENT to read GCC_EXEC_PREFIX.
If GCC_EXEC_PREFIX was not specified, see if we can figure out an
appropriate prefix from argv[0].
* Makefile.in (gcc.o): Define STANDARD_BINDIR_PREFIX.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gnu-win32-b20-branch@23190 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/Makefile.in | 11 | ||||
-rw-r--r-- | gcc/gcc.c | 270 |
3 files changed, 288 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c8a00266a7..af6cb06d5e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +Fri Mar 13 17:54:04 1998 Michael Meissner <meissner@cygnus.com> + + * gcc.c (DIR_UP): If not defined, define as "..". + (standard_bindir_prefix): New static, holds target location to + install binaries. + (split_directories): New function to split a filename into + component directories. + (free_split_directories): New function, release memory allocated + by split_directories. + (make_relative_prefix): New function, make a relative pathname if + the compiler is not in the expected location. + (process_command): Use GET_ENVIRONMENT to read GCC_EXEC_PREFIX. + If GCC_EXEC_PREFIX was not specified, see if we can figure out an + appropriate prefix from argv[0]. + + * Makefile.in (gcc.o): Define STANDARD_BINDIR_PREFIX. + Wed Aug 12 18:18:16 1998 Mumit Khan <khan@xraylith.wisc.edu> * i386/winnt.c (i386_pe_dllexport_p): Check TREE_TYPE for diff --git a/gcc/Makefile.in b/gcc/Makefile.in index bdfffb08a6f..683fc3470a9 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -297,6 +297,11 @@ tooldir = $(exec_prefix)/$(target_alias) # Dir for temp files. tmpdir = /tmp +# CYGNUS LOCAL texinfo +# Directory where texinfo.tex lives +texidir = $(srcdir)/../texinfo +# END CYGNUS LOCAL + # Additional system libraries to link with. CLIB= @@ -1326,20 +1331,20 @@ c-common.o : c-common.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h \ # Language-independent files. -# CYGNUS LOCAL: We use relative paths for TOOLDIR_BASE_PREFIX and -# STANDARD_STARTFILE_PREFIX so that we can move the installed tree. +# CYGNUS LOCAL -- meissner/relative pathnames DRIVER_DEFINES = \ -DSTANDARD_STARTFILE_PREFIX=\"$(unlibsubdir)/\" \ -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-lib/\" \ -DDEFAULT_TARGET_VERSION=\"$(version)\" \ -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \ + -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \ -DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\" - gcc.o: gcc.c $(CONFIG_H) system.h gansidecl.h multilib.h Makefile \ $(lang_specs_files) $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(DRIVER_DEFINES) \ -c `echo $(srcdir)/gcc.c | sed 's,^\./,,'` +# END CYGNUS LOCAL -- meissner/relative pathnames tree-check.h: s-check ; @true s-check : gencheck $(srcdir)/move-if-change diff --git a/gcc/gcc.c b/gcc/gcc.c index c186df30011..6ee6ed1bb65 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -112,13 +112,19 @@ extern void set_std_prefix PROTO((char *, int)); #define DIR_SEPARATOR '/' #endif +/* CYGNUS LOCAL -- meissner/relative pathnames */ +#ifndef DIR_UP +#define DIR_UP ".." +#endif +/* END CYGNUS LOCAL -- meissner/relative pathnames */ + static char dir_separator_str[] = {DIR_SEPARATOR, 0}; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free -#ifndef GET_ENVIRONMENT -#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME) +#ifndef GET_ENV_PATH_LIST +#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) #endif extern char *my_strerror PROTO((int)); @@ -217,6 +223,11 @@ static void set_spec PROTO((char *, char *)); static struct compiler *lookup_compiler PROTO((char *, size_t, char *)); static char *build_search_list PROTO((struct path_prefix *, char *, int)); static void putenv_from_prefixes PROTO((struct path_prefix *, char *)); +/* CYGNUS LOCAL -- meissner/relative pathnames */ +static char **split_directories PROTO((char *, int *)); +static void free_split_directories PROTO((char **)); +static char *make_relative_prefix PROTO((char *, char *, char *)); +/* END CYGNUS LOCAL -- meissner/relative pathnames */ static char *find_a_file PROTO((struct path_prefix *, char *, int)); static void add_prefix PROTO((struct path_prefix *, char *, char *, int, int, int *)); @@ -1420,6 +1431,12 @@ static char *standard_startfile_prefix_2 = "/usr/lib/"; static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX; static char *tooldir_prefix; +/* CYGNUS LOCAL -- meissner/relative pathnames */ +#ifdef STANDARD_BINDIR_PREFIX +static char *standard_bindir_prefix = STANDARD_BINDIR_PREFIX; +#endif +/* END CYGNUS LOCAL -- meissner/relative pathnames */ + /* Subdirectory to use for locating libraries. Set by set_multilib_dir based on the compilation options. */ @@ -1974,6 +1991,234 @@ putenv_from_prefixes (paths, env_var) putenv (build_search_list (paths, env_var, 1)); } +/* CYGNUS LOCAL -- meissner/relative pathnames */ +/* Split a filename into component directories. */ + +static char ** +split_directories (name, ptr_num_dirs) + char *name; + int *ptr_num_dirs; +{ + int num_dirs = 0; + char **dirs; + char *p, *q; + int ch; + + /* Count the number of directories. Special case MSDOS disk names as part + of the initial directory. */ + p = name; + if (DIR_SEPARATOR == '\\' && name[1] == ':' + && (name[2] == DIR_SEPARATOR || name[2] == '/')) + { + p += 3; + num_dirs++; + } + + while ((ch = *p++) != '\0') + { + if (ch == '/' || ch == DIR_SEPARATOR) + { + num_dirs++; + while ((ch = *p) == '/' || ch == DIR_SEPARATOR) + p++; + } + } + + dirs = (char **) xmalloc (sizeof (char *) * (num_dirs + 2)); + + /* Now copy the directory parts. */ + num_dirs = 0; + p = name; + if (DIR_SEPARATOR == '\\' && name[1] == ':' + && (name[2] == DIR_SEPARATOR || name[2] == '/')) + { + dirs[num_dirs++] = save_string (p, 3); + p += 3; + } + + q = p; + while ((ch = *p++) != '\0') + { + if (ch == '/' || ch == DIR_SEPARATOR) + { + while ((ch = *p) == '/' || ch == DIR_SEPARATOR) + p++; + + dirs[num_dirs++] = save_string (q, p - q); + q = p; + } + } + + if (p - 1 - q > 0) + dirs[num_dirs++] = save_string (q, p - 1 - q); + + dirs[num_dirs] = NULL_PTR; + if (ptr_num_dirs) + *ptr_num_dirs = num_dirs; + + return dirs; +} + +/* Release storage held by split directories. */ + +static void +free_split_directories (dirs) + char **dirs; +{ + int i = 0; + + while (dirs[i] != NULL_PTR) + free (dirs[i++]); + + free ((char *)dirs); +} + +/* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string that gets + to PREFIX starting with the directory portion of PROGNAME and a relative + pathname of the difference between BIN_PREFIX and PREFIX. + + For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX is + /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, then this + function will return /reg/green/blue/../omega. + + If no relative prefix can be found, return NULL. */ + +static char * +make_relative_prefix (progname, bin_prefix, prefix) + char *progname; + char *bin_prefix; + char *prefix; +{ + char **prog_dirs, **bin_dirs, **prefix_dirs; + int prog_num, bin_num, prefix_num, std_loc_p; + int i, n, common; + + prog_dirs = split_directories (progname, &prog_num); + bin_dirs = split_directories (bin_prefix, &bin_num); + + /* If there is no full pathname, try to find the program by checking in each + of the directories specified in the PATH environment variable. */ + if (prog_num == 1) + { + char *temp; + + GET_ENV_PATH_LIST (temp, "PATH"); + if (temp) + { + char *startp, *endp; + char *nstore = (char *) alloca (strlen (temp) + strlen (progname) + 1\ +); + + startp = endp = temp; + while (1) + { + if (*endp == PATH_SEPARATOR || *endp == 0) + { + if (endp == startp) + { + nstore[0] = '.'; + nstore[1] = DIR_SEPARATOR; + nstore[2] = '\0'; + } + else + { + strncpy (nstore, startp, endp-startp); + if (endp[-1] != '/' && endp[-1] != DIR_SEPARATOR) + { + nstore[endp-startp] = DIR_SEPARATOR; + nstore[endp-startp+1] = 0; + } + else + nstore[endp-startp] = 0; + } + strcat (nstore, progname); + if (!access (nstore, X_OK)) + { + free_split_directories (prog_dirs); + progname = nstore; + prog_dirs = split_directories (progname, &prog_num); + break; + } + + if (*endp == 0) + break; + endp = startp = endp + 1; + } + else + endp++; + } + } + } + + /* Remove the program name from comparison of directory names. */ + prog_num--; + + /* Determine if the compiler is installed in the standard location, and if + so, we don't need to specify relative directories. Also, if argv[0] + doesn't contain any directory specifiers, there is not much we can do. */ + std_loc_p = 0; + if (prog_num == bin_num) + { + for (i = 0; i < bin_num; i++) + { + if (strcmp (prog_dirs[i], bin_dirs[i]) != 0) + break; + } + + if (prog_num <= 0 || i == bin_num) + { + std_loc_p = 1; + free_split_directories (prog_dirs); + free_split_directories (bin_dirs); + prog_dirs = bin_dirs = (char **)0; + return NULL_PTR; + } + } + + prefix_dirs = split_directories (prefix, &prefix_num); + + /* Find how many directories are in common between bin_prefix & prefix */ + n = (prefix_num < bin_num) ? prefix_num : bin_num; + for (common = 0; common < n; common++) + { + if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0) + break; + } + + /* If there are no common directories, there can be no relative prefix. */ + if (common == 0) + { + free_split_directories (prog_dirs); + free_split_directories (bin_dirs); + free_split_directories (prefix_dirs); + return NULL_PTR; + } + + /* Build up the pathnames in argv[0]. */ + for (i = 0; i < prog_num; i++) + obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i])); + + /* Now build up the ..'s. */ + for (i = common; i < n; i++) + { + obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP)-1); + obstack_1grow (&obstack, DIR_SEPARATOR); + } + + /* Put in directories to move over to prefix. */ + for (i = common; i < prefix_num; i++) + obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i])); + + free_split_directories (prog_dirs); + free_split_directories (bin_dirs); + free_split_directories (prefix_dirs); + + obstack_1grow (&obstack, '\0'); + return obstack_finish (&obstack); +} +/* END CYGNUS LOCAL -- meissner/relative pathnames */ + + /* Search for NAME using the prefix list PREFIXES. MODE is passed to access to check permissions. Return 0 if not found, otherwise return its name, allocated with malloc. */ @@ -2570,7 +2815,7 @@ process_command (argc, argv) int have_o = 0; int lang_n_infiles = 0; - GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); + GET_ENV_PATH_LIST (gcc_exec_prefix, "GCC_EXEC_PREFIX"); n_switches = 0; n_infiles = 0; @@ -2588,7 +2833,18 @@ process_command (argc, argv) } } - /* Set up the default search paths. */ + /* CYGNUS LOCAL meissner/relative pathnames */ + /* Set up the default search paths. If there is no GCC_EXEC_PREFIX, see if we + can create it from the pathname specified in argv[0]. */ + + if (!gcc_exec_prefix) + { + gcc_exec_prefix = make_relative_prefix (argv[0], standard_bindir_prefix, + standard_exec_prefix); + if (gcc_exec_prefix) + putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL_PTR)); + } + /* END CYGNUS LOCAL -- meissner/relative pathnames */ if (gcc_exec_prefix) { @@ -2613,7 +2869,7 @@ process_command (argc, argv) /* COMPILER_PATH and LIBRARY_PATH have values that are lists of directory names with colons. */ - GET_ENVIRONMENT (temp, "COMPILER_PATH"); + GET_ENV_PATH_LIST (temp, "COMPILER_PATH"); if (temp) { char *startp, *endp; @@ -2647,7 +2903,7 @@ process_command (argc, argv) } } - GET_ENVIRONMENT (temp, "LIBRARY_PATH"); + GET_ENV_PATH_LIST (temp, "LIBRARY_PATH"); if (temp && *cross_compile == '0') { char *startp, *endp; @@ -2680,7 +2936,7 @@ process_command (argc, argv) } /* Use LPATH like LIBRARY_PATH (for the CMU build program). */ - GET_ENVIRONMENT (temp, "LPATH"); + GET_ENV_PATH_LIST (temp, "LPATH"); if (temp && *cross_compile == '0') { char *startp, *endp; |