aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoer <noer@138bc75d-0d04-0410-961f-82ee72b054a4>1998-10-19 23:16:29 +0000
committernoer <noer@138bc75d-0d04-0410-961f-82ee72b054a4>1998-10-19 23:16:29 +0000
commit98042d819f812ef29254d457445089aa51a2fcde (patch)
tree8d62f0b8f7ec6ba0ebf57799b2febd697248caff
parent1d23f0ca80f14fae99c581b777b8307a9080ef8b (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/ChangeLog17
-rw-r--r--gcc/Makefile.in11
-rw-r--r--gcc/gcc.c270
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;