From: jakub Date: Thu, 3 Oct 2002 20:35:14 +0000 (+0000) Subject: * gcc.c (print_multi_os_directory): New variable. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c954ff02f308a7c03628c9c7882c21b0fd032c67;p=thirdparty%2Fgcc.git * gcc.c (print_multi_os_directory): New variable. (option_map): Support --print-multi-os-directory. (struct prefix_list): Add os_multilib field. (multilib_os_dir): New variable. (static_specs): Add multilib_options. (find_a_file): Add multilib argument. Search in GCC or OS multilib subdirs if non-zero. (read_specs, execute): Update callers. (find_file): Likewise. Don't prefix name with multilib_dir, instead pass 1 as multilib option. (display_help): Include --print-multi-os-directory. (add_prefix): Add os_multilib argument. Initialize pl->os_multilib. (process_command): Update callers. Handle --print-multi-os-directory. (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is set. (main): Update find_a_file and add_prefix callers. Handle print_multi_os_directory. (struct mdswitchstr): New. (mdswitches, n_mdswitches): New variables. (used_arg): Add MULTILIB_DEFAULT switches too if they are not present on the command line nor their mutually incompatible switches. (default_arg): Optimize. (set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches array. (print_multilib_info): Only print GCC multilib dir name, not OS multilib dirname. * genmultilib: Add osdirnames parameter. Output multilib_options variable. If osdirnames is specified, output dirnames as dirname:osdirname. * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES to compute libgcc_s soname and install path. * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of SHLIB_SLIBDIR_SUFFIXES to mklibgcc. (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib argument. * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64, ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove. (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32 and -m64. * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. * config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove. (STARTFILE_ARCH_SPEC): Remove. * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove. * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57786 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1ad35bd70627..5e9e0737fa8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,59 @@ +2002-10-03 Jakub Jelinek + + * gcc.c (print_multi_os_directory): New variable. + (option_map): Support --print-multi-os-directory. + (struct prefix_list): Add os_multilib field. + (multilib_os_dir): New variable. + (static_specs): Add multilib_options. + (find_a_file): Add multilib argument. Search in GCC or OS multilib + subdirs if non-zero. + (read_specs, execute): Update callers. + (find_file): Likewise. Don't prefix name with multilib_dir, instead + pass 1 as multilib option. + (display_help): Include --print-multi-os-directory. + (add_prefix): Add os_multilib argument. Initialize pl->os_multilib. + (process_command): Update callers. Handle --print-multi-os-directory. + (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is + set. + (main): Update find_a_file and add_prefix callers. + Handle print_multi_os_directory. + (struct mdswitchstr): New. + (mdswitches, n_mdswitches): New variables. + (used_arg): Add MULTILIB_DEFAULT switches too if they are not + present on the command line nor their mutually incompatible + switches. + (default_arg): Optimize. + (set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches + array. + (print_multilib_info): Only print GCC multilib dir name, not OS + multilib dirname. + * genmultilib: Add osdirnames parameter. Output multilib_options + variable. If osdirnames is specified, output dirnames as + dirname:osdirname. + * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory + and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES + to compute libgcc_s soname and install path. + * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of + SHLIB_SLIBDIR_SUFFIXES to mklibgcc. + (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib + argument. + + * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64, + ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove. + (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32 + and -m64. + * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + * config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove. + (STARTFILE_ARCH_SPEC): Remove. + * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove. + * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + Thu Oct 3 21:42:20 CEST 2002 Jan Hubicka * predict.c (choose_function_section): Avoid choice for linkonce functions. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d7aad602c59a..edf95572d608 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1027,7 +1027,7 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext SHLIB_MKMAP_OPTS='$(SHLIB_MKMAP_OPTS)' \ SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \ SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \ - SHLIB_SLIBDIR_SUFFIXES='$(SHLIB_SLIBDIR_SUFFIXES)' \ + MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \ mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \ $(SHELL) mklibgcc > tmp-libgcc.mk mv tmp-libgcc.mk libgcc.mk @@ -1069,9 +1069,10 @@ s-mlib: $(srcdir)/genmultilib Makefile "$(MULTILIB_EXCEPTIONS)" \ "$(MULTILIB_EXTRA_OPTS)" \ "$(MULTILIB_EXCLUSIONS)" \ + "$(MULTILIB_OSDIRNAMES)" \ > tmp-mlib.h; \ else \ - $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' > tmp-mlib.h; \ + $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' > tmp-mlib.h; \ fi $(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h $(STAMP) s-mlib diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index d2113909ece3..965120a1bb61 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -60,10 +60,6 @@ Boston, MA 02111-1307, USA. */ %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \ %{static:-static}}" -#define STARTFILE_PREFIX_SPEC "\ - %{m32: /usr/local/lib/ /lib/ /usr/lib/} \ - %{!m32: /usr/local/lib64/ /lib64/ /usr/lib64/}" - #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: \ diff --git a/gcc/config/i386/t-linux64 b/gcc/config/i386/t-linux64 index 46a7caadf772..8780321ca35e 100644 --- a/gcc/config/i386/t-linux64 +++ b/gcc/config/i386/t-linux64 @@ -6,10 +6,9 @@ SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \ MULTILIB_OPTIONS = m64/m32 MULTILIB_DIRNAMES = 64 32 +MULTILIB_OSDIRNAMES = ../lib64 ../lib32 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o - -SHLIB_SLIBDIR_SUFFIXES = 64:64 32: diff --git a/gcc/config/mips/t-iris6 b/gcc/config/mips/t-iris6 index 582ec4c79490..b55bc36aca8d 100644 --- a/gcc/config/mips/t-iris6 +++ b/gcc/config/mips/t-iris6 @@ -4,6 +4,7 @@ MULTILIB_OPTIONS=mabi=n32/mabi=64 MULTILIB_DIRNAMES= MULTILIB_MATCHES= +MULTILIB_OSDIRNAMES=../lib32 ../lib64 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib @@ -14,8 +15,6 @@ INSTALL_LIBGCC = install-multilib EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o CRTSTUFF_T_CFLAGS=-g1 -SHLIB_SLIBDIR_SUFFIXES = mabi=64:/mabi=64 mabi=n32: - # This is only needed in the static libgcc as a band-aid until gcc correctly # implements the N32/N64 ABI structure passing conventions LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h index 51eca1661ae3..eb81eb61401c 100644 --- a/gcc/config/sparc/linux64.h +++ b/gcc/config/sparc/linux64.h @@ -1,5 +1,5 @@ /* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF. - Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc. Contributed by David S. Miller (davem@caip.rutgers.edu) This file is part of GNU CC. @@ -55,38 +55,11 @@ Boston, MA 02111-1307, USA. */ #undef STARTFILE_SPEC -#define STARTFILE_SPEC32 \ - "%{!shared: \ - %{pg:/usr/lib/gcrt1.o%s} %{!pg:%{p:/usr/lib/gcrt1.o%s} %{!p:/usr/lib/crt1.o%s}}}\ - /usr/lib/crti.o%s %{static:crtbeginT.o%s}\ +#define STARTFILE_SPEC \ + "%{!shared:%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\ + crti.o%s %{static:crtbeginT.o%s}\ %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" -#define STARTFILE_SPEC64 \ - "%{!shared: \ - %{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} %{!p:/usr/lib64/crt1.o%s}}}\ - /usr/lib64/crti.o%s %{static:crtbeginT.o%s}\ - %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" - -#ifdef SPARC_BI_ARCH - -#if DEFAULT_ARCH32_P -#define STARTFILE_SPEC "\ -%{m32:" STARTFILE_SPEC32 "} \ -%{m64:" STARTFILE_SPEC64 "} \ -%{!m32:%{!m64:" STARTFILE_SPEC32 "}}" -#else -#define STARTFILE_SPEC "\ -%{m32:" STARTFILE_SPEC32 "} \ -%{m64:" STARTFILE_SPEC64 "} \ -%{!m32:%{!m64:" STARTFILE_SPEC64 "}}" -#endif - -#else - -#define STARTFILE_SPEC STARTFILE_SPEC64 - -#endif - /* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on the GNU/Linux magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static @@ -95,36 +68,9 @@ Boston, MA 02111-1307, USA. */ #undef ENDFILE_SPEC -#define ENDFILE_SPEC32 \ - "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib/crtn.o%s" - -#define ENDFILE_SPEC64 \ - "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s" - -#define ENDFILE_SPEC_COMMON \ - "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}" - -#ifdef SPARC_BI_ARCH - -#if DEFAULT_ARCH32_P -#define ENDFILE_SPEC "\ -%{m32:" ENDFILE_SPEC32 "} \ -%{m64:" ENDFILE_SPEC64 "} \ -%{!m32:%{!m64:" ENDFILE_SPEC32 "}} " \ -ENDFILE_SPEC_COMMON -#else -#define ENDFILE_SPEC "\ -%{m32:" ENDFILE_SPEC32 "} \ -%{m64:" ENDFILE_SPEC64 "} \ -%{!m32:%{!m64:" ENDFILE_SPEC64 "}} " \ -ENDFILE_SPEC_COMMON -#endif - -#else - -#define ENDFILE_SPEC ENDFILE_SPEC64 " " ENDFILE_SPEC_COMMON - -#endif +#define ENDFILE_SPEC \ + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\ + %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}" /* The GNU C++ standard library requires that these macros be defined. */ #undef CPLUSPLUS_CPP_SPEC diff --git a/gcc/config/sparc/sol2-bi.h b/gcc/config/sparc/sol2-bi.h index 1ba52606aa3b..3f9416daaa09 100644 --- a/gcc/config/sparc/sol2-bi.h +++ b/gcc/config/sparc/sol2-bi.h @@ -57,24 +57,6 @@ %{!mcpu*:%(asm_cpu_default)} \ " -#define STARTFILE_ARCH64_SPEC "\ -%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \ -%{!ansi:/usr/lib/sparcv9/values-Xa.o%s}" - -#undef STARTFILE_ARCH_SPEC - -#if DEFAULT_ARCH32_P -#define STARTFILE_ARCH_SPEC "\ -%{m32:" STARTFILE_ARCH32_SPEC "} \ -%{m64:" STARTFILE_ARCH64_SPEC "} \ -%{!m32:%{!m64:" STARTFILE_ARCH32_SPEC "}}" -#else -#define STARTFILE_ARCH_SPEC "\ -%{m32:" STARTFILE_ARCH32_SPEC "} \ -%{m64:" STARTFILE_ARCH64_SPEC "} \ -%{!m32:%{!m64:" STARTFILE_ARCH64_SPEC "}}" -#endif - #undef CPP_CPU_DEFAULT_SPEC #define CPP_CPU_DEFAULT_SPEC \ (DEFAULT_ARCH32_P ? "\ diff --git a/gcc/config/sparc/t-linux64 b/gcc/config/sparc/t-linux64 index a64862638355..5b6603334f0a 100644 --- a/gcc/config/sparc/t-linux64 +++ b/gcc/config/sparc/t-linux64 @@ -3,6 +3,7 @@ MULTILIB_DIRNAMES = 64 32 alt MULTILIB_MATCHES = mcmodel?medany=mcmodel?medmid MULTILIB_EXCEPTIONS = m32/mno-app-regs* m32/mcmodel=* MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany +MULTILIB_OSDIRNAMES = ../lib64 ../lib alt LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib @@ -10,8 +11,6 @@ INSTALL_LIBGCC = install-multilib EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \ crtfastmath.o -SHLIB_SLIBDIR_SUFFIXES = 64:64 32: - # Override t-slibgcc-elf-ver to export some libgcc symbols with # the symbol versions that glibc used. # Avoid the t-linux version file. diff --git a/gcc/config/sparc/t-sol2-64 b/gcc/config/sparc/t-sol2-64 index 39204d7368fe..3c15f0a712a1 100644 --- a/gcc/config/sparc/t-sol2-64 +++ b/gcc/config/sparc/t-sol2-64 @@ -1,11 +1,10 @@ MULTILIB_OPTIONS = m32/m64 MULTILIB_DIRNAMES = sparcv7 sparcv9 MULTILIB_MATCHES = +MULTILIB_OSDIRNAMES = . sparcv9 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \ crtfastmath.o - -SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7: diff --git a/gcc/gcc.c b/gcc/gcc.c index f14a29cdc398..b9794fe39984 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -162,6 +162,11 @@ static const char *print_prog_name = NULL; static int print_multi_directory; +/* Flag saying to print the relative path we'd use to + find OS libraries given the current compiler flags. */ + +static int print_multi_os_directory; + /* Flag saying to print the list of subdirectories and compiler flags used to select them in a standard form. */ @@ -275,9 +280,10 @@ static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const cha static char *build_search_list PARAMS ((struct path_prefix *, const char *, int)); static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *)); static int access_check PARAMS ((const char *, int)); -static char *find_a_file PARAMS ((struct path_prefix *, const char *, int)); +static char *find_a_file PARAMS ((struct path_prefix *, const char *, + int, int)); static void add_prefix PARAMS ((struct path_prefix *, const char *, - const char *, int, int, int *)); + const char *, int, int, int *, int)); static void translate_options PARAMS ((int *, const char *const **)); static char *skip_whitespace PARAMS ((char *)); static void delete_if_ordinary PARAMS ((const char *)); @@ -961,6 +967,7 @@ static const struct option_map option_map[] = {"--print-missing-file-dependencies", "-MG", 0}, {"--print-multi-lib", "-print-multi-lib", 0}, {"--print-multi-directory", "-print-multi-directory", 0}, + {"--print-multi-os-directory", "-print-multi-os-directory", 0}, {"--print-prog-name", "-print-prog-name=", "aj"}, {"--profile", "-p", 0}, {"--profile-blocks", "-a", 0}, @@ -1246,7 +1253,9 @@ struct prefix_list int require_machine_suffix; /* Don't use without machine_suffix. */ /* 2 means try both machine_suffix and just_machine_suffix. */ int *used_flag_ptr; /* 1 if a file was found with this prefix. */ - int priority; /* Sort key - priority within list */ + int priority; /* Sort key - priority within list. */ + int os_multilib; /* 1 if OS multilib scheme should be used, + 0 for GCC multilib scheme. */ }; struct path_prefix @@ -1335,6 +1344,11 @@ static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX; set_multilib_dir based on the compilation options. */ static const char *multilib_dir; + +/* Subdirectory to use for locating libraries in OS conventions. Set by + set_multilib_dir based on the compilation options. */ + +static const char *multilib_os_dir; /* Structure to keep track of the specs that have been defined so far. These are accessed using %(specname) or %[specname] in a compiler @@ -1389,6 +1403,7 @@ static struct spec_list static_specs[] = INIT_STATIC_SPEC ("multilib_extra", &multilib_extra), INIT_STATIC_SPEC ("multilib_matches", &multilib_matches), INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions), + INIT_STATIC_SPEC ("multilib_options", &multilib_options), INIT_STATIC_SPEC ("linker", &linker_name_spec), INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec), INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix), @@ -1836,7 +1851,7 @@ read_specs (filename, main_p) (long) (p1 - buffer + 1)); p[-2] = '\0'; - new_filename = find_a_file (&startfile_prefixes, p1, R_OK); + new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0); read_specs (new_filename ? new_filename : p1, FALSE); continue; } @@ -1855,7 +1870,7 @@ read_specs (filename, main_p) (long) (p1 - buffer + 1)); p[-2] = '\0'; - new_filename = find_a_file (&startfile_prefixes, p1, R_OK); + new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0); if (new_filename) read_specs (new_filename, FALSE); else if (verbose_flag) @@ -2490,16 +2505,17 @@ access_check (name, mode) Return 0 if not found, otherwise return its name, allocated with malloc. */ static char * -find_a_file (pprefix, name, mode) +find_a_file (pprefix, name, mode, multilib) struct path_prefix *pprefix; const char *name; - int mode; + int mode, multilib; { char *temp; const char *const file_suffix = ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : ""); struct prefix_list *pl; int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; + const char *multilib_name, *multilib_os_name; #ifdef DEFAULT_ASSEMBLER if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0) @@ -2514,6 +2530,22 @@ find_a_file (pprefix, name, mode) if (machine_suffix) len += strlen (machine_suffix); + multilib_name = name; + multilib_os_name = name; + if (multilib && multilib_os_dir) + { + int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0; + int len2 = strlen (multilib_os_dir) + 1; + + len += len1 > len2 ? len1 : len2; + if (multilib_dir) + multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name, + NULL)); + if (strcmp (multilib_os_dir, ".") != 0) + multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name, + NULL)); + } + temp = xmalloc (len); /* Determine the filename to execute (special case for absolute paths). */ @@ -2529,6 +2561,9 @@ find_a_file (pprefix, name, mode) else for (pl = pprefix->plist; pl; pl = pl->next) { + const char *this_name + = pl->os_multilib ? multilib_os_name : multilib_name; + if (machine_suffix) { /* Some systems have a suffix for executable files. @@ -2537,7 +2572,7 @@ find_a_file (pprefix, name, mode) { strcpy (temp, pl->prefix); strcat (temp, machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2547,10 +2582,10 @@ find_a_file (pprefix, name, mode) } } - /* Now try just the name. */ + /* Now try just the multilib_name. */ strcpy (temp, pl->prefix); strcat (temp, machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2569,7 +2604,7 @@ find_a_file (pprefix, name, mode) { strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2581,7 +2616,7 @@ find_a_file (pprefix, name, mode) strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2599,7 +2634,7 @@ find_a_file (pprefix, name, mode) if (file_suffix[0] != 0) { strcpy (temp, pl->prefix); - strcat (temp, name); + strcat (temp, this_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2610,7 +2645,7 @@ find_a_file (pprefix, name, mode) } strcpy (temp, pl->prefix); - strcat (temp, name); + strcat (temp, this_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2648,13 +2683,15 @@ enum path_prefix_priority 2 means try both machine_suffix and just_machine_suffix. */ static void -add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn) +add_prefix (pprefix, prefix, component, priority, require_machine_suffix, + warn, os_multilib) struct path_prefix *pprefix; const char *prefix; const char *component; /* enum prefix_priority */ int priority; int require_machine_suffix; int *warn; + int os_multilib; { struct prefix_list *pl, **prev; int len; @@ -2676,6 +2713,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn) pl->require_machine_suffix = require_machine_suffix; pl->used_flag_ptr = warn; pl->priority = priority; + pl->os_multilib = os_multilib; if (warn) *warn = 0; @@ -2719,7 +2757,7 @@ execute () commands[0].prog = argbuf[0]; /* first command. */ commands[0].argv = &argbuf[0]; - string = find_a_file (&exec_prefixes, commands[0].prog, X_OK); + string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0); if (string) commands[0].argv[0] = string; @@ -2733,7 +2771,8 @@ execute () argbuf[i] = 0; /* termination of command args. */ commands[n_commands].prog = argbuf[i + 1]; commands[n_commands].argv = &argbuf[i + 1]; - string = find_a_file (&exec_prefixes, commands[n_commands].prog, X_OK); + string = find_a_file (&exec_prefixes, commands[n_commands].prog, + X_OK, 0); if (string) commands[n_commands].argv[0] = string; n_commands++; @@ -3048,6 +3087,7 @@ display_help () fputs (_("\ -print-multi-lib Display the mapping between command line options and\n\ multiple library search directories\n"), stdout); + fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout); fputs (_(" -Wa, Pass comma-separated on to the assembler\n"), stdout); fputs (_(" -Wp, Pass comma-separated on to the preprocessor\n"), stdout); fputs (_(" -Wl, Pass comma-separated on to the linker\n"), stdout); @@ -3264,9 +3304,9 @@ process_command (argc, argv) set_std_prefix (gcc_exec_prefix, len); add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); } /* COMPILER_PATH and LIBRARY_PATH have values @@ -3294,10 +3334,10 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&exec_prefixes, nstore, 0, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&include_prefixes, concat (nstore, "include", NULL), - 0, PREFIX_PRIORITY_LAST, 0, NULL); + 0, PREFIX_PRIORITY_LAST, 0, NULL, 0); if (*endp == 0) break; endp = startp = endp + 1; @@ -3329,7 +3369,7 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&startfile_prefixes, nstore, NULL, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*endp == 0) break; endp = startp = endp + 1; @@ -3362,7 +3402,7 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&startfile_prefixes, nstore, NULL, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*endp == 0) break; endp = startp = endp + 1; @@ -3462,6 +3502,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" print_multi_lib = 1; else if (! strcmp (argv[i], "-print-multi-directory")) print_multi_directory = 1; + else if (! strcmp (argv[i], "-print-multi-os-directory")) + print_multi_os_directory = 1; else if (! strncmp (argv[i], "-Wa,", 4)) { int prev, j; @@ -3624,7 +3666,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" { if (len == 7) add_prefix (&include_prefixes, "include", NULL, - PREFIX_PRIORITY_B_OPT, 0, NULL); + PREFIX_PRIORITY_B_OPT, 0, NULL, 0); else { char * string = xmalloc (len + 1); @@ -3632,16 +3674,16 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" strncpy (string, value, len - 7); strcpy (string + len - 7, "include"); add_prefix (&include_prefixes, string, NULL, - PREFIX_PRIORITY_B_OPT, 0, NULL); + PREFIX_PRIORITY_B_OPT, 0, NULL, 0); } } add_prefix (&exec_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, &warn_B); + PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0); add_prefix (&startfile_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, &warn_B); + PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0); add_prefix (&include_prefixes, concat (value, "include", NULL), - NULL, PREFIX_PRIORITY_B_OPT, 0, NULL); + NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0); n_switches++; } break; @@ -3771,17 +3813,17 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" as well as trying the machine and the version. */ #ifndef OS2 add_prefix (&exec_prefixes, standard_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 2, warn_std_ptr); + PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0); add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS", - PREFIX_PRIORITY_LAST, 2, warn_std_ptr); + PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0); #endif add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); tooldir_prefix = concat (tooldir_base_prefix, spec_machine, dir_separator_str, NULL); @@ -3804,11 +3846,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" add_prefix (&exec_prefixes, concat (gcc_exec_tooldir_prefix, "bin", dir_separator_str, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, concat (gcc_exec_tooldir_prefix, "lib", dir_separator_str, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); } tooldir_prefix = concat (standard_exec_prefix, spec_machine, @@ -3818,10 +3860,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" add_prefix (&exec_prefixes, concat (tooldir_prefix, "bin", dir_separator_str, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, concat (tooldir_prefix, "lib", dir_separator_str, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); /* More prefixes are enabled in main, after we read the specs file and determine whether this is cross-compilation or not. */ @@ -3871,6 +3913,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" ; else if (! strcmp (argv[i], "-print-multi-directory")) ; + else if (! strcmp (argv[i], "-print-multi-os-directory")) + ; else if (! strcmp (argv[i], "-ftarget-help")) ; else if (! strcmp (argv[i], "-fhelp")) @@ -4381,9 +4425,14 @@ do_spec_1 (spec, inswitch, soft_matched_part) continue; #endif /* Try subdirectory if there is one. */ - if (multilib_dir != NULL) + if (multilib_dir != NULL + || (pl->os_multilib && multilib_os_dir != NULL)) { - if (machine_suffix) + const char *multi_dir; + + multi_dir = pl->os_multilib ? multilib_os_dir + : multilib_dir; + if (machine_suffix && multilib_dir) { if (strlen (pl->prefix) + strlen (machine_suffix) >= bufsize) @@ -4406,14 +4455,14 @@ do_spec_1 (spec, inswitch, soft_matched_part) } if (!pl->require_machine_suffix) { - if (is_directory (pl->prefix, multilib_dir, 1)) + if (is_directory (pl->prefix, multi_dir, 1)) { do_spec_1 ("-L", 0, NULL); #ifdef SPACE_AFTER_L_OPTION do_spec_1 (" ", 0, NULL); #endif do_spec_1 (pl->prefix, 1, NULL); - do_spec_1 (multilib_dir, 1, NULL); + do_spec_1 (multi_dir, 1, NULL); /* Make this a separate argument. */ do_spec_1 (" ", 0, NULL); } @@ -5634,11 +5683,9 @@ find_file (name) char *newname; /* Try multilib_dir if it is defined. */ - if (multilib_dir != NULL) + if (multilib_os_dir != NULL) { - const char *const try = ACONCAT ((multilib_dir, dir_separator_str, name, NULL)); - - newname = find_a_file (&startfile_prefixes, try, R_OK); + newname = find_a_file (&startfile_prefixes, name, R_OK, 1); /* If we don't find it in the multi library dir, then fall through and look for it in the normal places. */ @@ -5646,7 +5693,7 @@ find_file (name) return newname; } - newname = find_a_file (&startfile_prefixes, name, R_OK); + newname = find_a_file (&startfile_prefixes, name, R_OK, 0); return newname ? newname : name; } @@ -5881,7 +5928,7 @@ main (argc, argv) spec_version, dir_separator_str, NULL); just_machine_suffix = concat (spec_machine, dir_separator_str, NULL); - specs_file = find_a_file (&startfile_prefixes, "specs", R_OK); + specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0); /* Read the specs file unless it is a default one. */ if (specs_file != 0 && strcmp (specs_file, "specs")) read_specs (specs_file, TRUE); @@ -5908,18 +5955,18 @@ main (argc, argv) if (*md_exec_prefix) { add_prefix (&exec_prefixes, md_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, md_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); } if (*md_startfile_prefix) add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*md_startfile_prefix_1) add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); /* If standard_startfile_prefix is relative, base it on standard_exec_prefix. This lets us move the installed tree @@ -5927,28 +5974,28 @@ main (argc, argv) standard_startfile_prefix on that as well. */ if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix)) add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); else { if (gcc_exec_prefix) add_prefix (&startfile_prefixes, concat (gcc_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); add_prefix (&startfile_prefixes, concat (standard_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); } add_prefix (&startfile_prefixes, standard_startfile_prefix_1, - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); add_prefix (&startfile_prefixes, standard_startfile_prefix_2, - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); #if 0 /* Can cause surprises, and one can use -B./ instead. */ add_prefix (&startfile_prefixes, "./", NULL, - PREFIX_PRIORITY_LAST, 1, NULL); + PREFIX_PRIORITY_LAST, 1, NULL, 0); #endif } else @@ -5958,7 +6005,7 @@ main (argc, argv) add_prefix (&startfile_prefixes, concat (gcc_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); } if (*startfile_prefix_spec != 0 @@ -5968,14 +6015,15 @@ main (argc, argv) int ndx; for (ndx = 0; ndx < argbuf_index; ndx++) add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); } /* Process any user specified specs in the order given on the command line. */ for (uptr = user_specs_head; uptr; uptr = uptr->next) { - char *filename = find_a_file (&startfile_prefixes, uptr->filename, R_OK); + char *filename = find_a_file (&startfile_prefixes, uptr->filename, + R_OK, 0); read_specs (filename ? filename : uptr->filename, FALSE); } @@ -6017,7 +6065,7 @@ main (argc, argv) if (print_prog_name) { - char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK); + char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0); printf ("%s\n", (newname ? newname : print_prog_name)); return (0); } @@ -6037,6 +6085,15 @@ main (argc, argv) return (0); } + if (print_multi_os_directory) + { + if (multilib_os_dir == NULL) + printf (".\n"); + else + printf ("%s\n", multilib_os_dir); + return (0); + } + if (target_help_flag) { /* Print if any target specific options. */ @@ -6196,7 +6253,7 @@ main (argc, argv) /* We'll use ld if we can't find collect2. */ if (! strcmp (linker_name_spec, "collect2")) { - char *s = find_a_file (&exec_prefixes, "collect2", X_OK); + char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0); if (s == NULL) linker_name_spec = "ld"; } @@ -6490,6 +6547,15 @@ next_member: goto next_member; } +struct mdswitchstr +{ + const char *str; + int len; +}; + +static struct mdswitchstr *mdswitches; +static int n_mdswitches; + /* Check whether a particular argument was used. The first time we canonicalize the switches to keep only the ones we care about. */ @@ -6555,8 +6621,9 @@ used_arg (p, len) xmalloc from calling fatal, and prevents us from re-executing this block of code. */ mswitches - = (struct mswitchstr *) xmalloc ((sizeof (struct mswitchstr)) - * (n_switches ? n_switches : 1)); + = (struct mswitchstr *) + xmalloc (sizeof (struct mswitchstr) + * (n_mdswitches + (n_switches ? n_switches : 1))); for (i = 0; i < n_switches; i++) { int xlen = strlen (switches[i].part1); @@ -6572,6 +6639,57 @@ used_arg (p, len) break; } } + + /* Add MULTILIB_DEFAULTS switches too, as long as they were not present + on the command line nor any options mutually incompatible with + them. */ + for (i = 0; i < n_mdswitches; i++) + { + const char *r; + + for (q = multilib_options; *q != '\0'; q++) + { + while (*q == ' ') + q++; + + r = q; + while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0 + || strchr (" /", q[mdswitches[i].len]) == NULL) + { + while (*q != ' ' && *q != '/' && *q != '\0') + q++; + if (*q != '/') + break; + q++; + } + + if (*q != ' ' && *q != '\0') + { + while (*r != ' ' && *r != '\0') + { + q = r; + while (*q != ' ' && *q != '/' && *q != '\0') + q++; + + if (used_arg (r, q - r)) + break; + + if (*q != '/') + { + mswitches[n_mswitches].str = mdswitches[i].str; + mswitches[n_mswitches].len = mdswitches[i].len; + mswitches[n_mswitches].replace = (char *) 0; + mswitches[n_mswitches].rep_len = 0; + n_mswitches++; + break; + } + + r = q + 1; + } + break; + } + } + } } for (i = 0; i < n_mswitches; i++) @@ -6586,25 +6704,11 @@ default_arg (p, len) const char *p; int len; { - const char *start, *end; - - for (start = multilib_defaults; *start != '\0'; start = end + 1) - { - while (*start == ' ' || *start == '\t') - start++; - - if (*start == '\0') - break; - - for (end = start + 1; *end != ' ' && *end != '\t' && *end != '\0'; end++) - ; - - if ((end - start) == len && strncmp (p, start, len) == 0) - return 1; + int i; - if (*end == '\0') - break; - } + for (i = 0; i < n_mdswitches; i++) + if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len)) + return 1; return 0; } @@ -6626,8 +6730,51 @@ set_multilib_dir () const char *p; unsigned int this_path_len; const char *this_path, *this_arg; + const char *start, *end; int not_arg; - int ok; + int ok, ndfltok, first; + + n_mdswitches = 0; + start = multilib_defaults; + while (*start == ' ' || *start == '\t') + start++; + while (*start != '\0') + { + n_mdswitches++; + while (*start != ' ' && *start != '\t' && *start != '\0') + start++; + while (*start == ' ' || *start == '\t') + start++; + } + + if (n_mdswitches) + { + int i = 0; + + mdswitches + = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr) + * n_mdswitches); + for (start = multilib_defaults; *start != '\0'; start = end + 1) + { + while (*start == ' ' || *start == '\t') + start++; + + if (*start == '\0') + break; + + for (end = start + 1; + *end != ' ' && *end != '\t' && *end != '\0'; end++) + ; + + obstack_grow (&multilib_obstack, start, end - start); + obstack_1grow (&multilib_obstack, 0); + mdswitches[i].str = obstack_finish (&multilib_obstack); + mdswitches[i++].len = end - start; + + if (*end == '\0') + break; + } + } p = multilib_exclusions; while (*p != '\0') @@ -6682,6 +6829,7 @@ set_multilib_dir () ++p; } + first = 1; p = multilib_select; while (*p != '\0') { @@ -6704,6 +6852,7 @@ set_multilib_dir () /* Check the arguments. */ ok = 1; + ndfltok = 1; ++p; while (*p != ';') { @@ -6739,32 +6888,65 @@ set_multilib_dir () there is a more specific library which uses this argument. If this argument is a default, we need not consider that more specific library. */ - if (! default_arg (this_arg, p - this_arg)) - { - ok = used_arg (this_arg, p - this_arg); - if (not_arg) - ok = ! ok; - } + ok = used_arg (this_arg, p - this_arg); + if (not_arg) + ok = ! ok; + + if (! ok) + ndfltok = 0; + + if (default_arg (this_arg, p - this_arg)) + ok = 1; if (*p == ' ') ++p; } - if (ok) + if (ok && first) { if (this_path_len != 1 || this_path[0] != '.') { char *new_multilib_dir = xmalloc (this_path_len + 1); + char *q; + strncpy (new_multilib_dir, this_path, this_path_len); new_multilib_dir[this_path_len] = '\0'; + q = strchr (new_multilib_dir, ':'); + if (q != NULL) + *q = '\0'; multilib_dir = new_multilib_dir; } - break; + first = 0; + } + + if (ndfltok) + { + const char *q = this_path, *end = this_path + this_path_len; + + while (q < end && *q != ':') + q++; + if (*q == ':') + { + char *new_multilib_os_dir = xmalloc (end - q); + strncpy (new_multilib_os_dir, q + 1, end - q - 1); + new_multilib_os_dir[end - q] = '\0'; + multilib_os_dir = new_multilib_os_dir; + break; + } } ++p; } + + if (multilib_dir == NULL && multilib_os_dir != NULL + && strcmp (multilib_os_dir, ".") == 0) + { + free ((char *) multilib_os_dir); + multilib_os_dir = NULL; + } + else if (multilib_dir != NULL && multilib_os_dir == NULL) + multilib_os_dir = multilib_dir; } /* Print out the multiple library subdirectory selection @@ -6945,7 +7127,7 @@ print_multilib_info () { const char *p1; - for (p1 = last_path; p1 < p; p1++) + for (p1 = last_path; p1 < p && *p1 != ':'; p1++) putchar (*p1); putchar (';'); } diff --git a/gcc/genmultilib b/gcc/genmultilib index 3cbfaa1ebab2..c687537d7004 100644 --- a/gcc/genmultilib +++ b/gcc/genmultilib @@ -63,6 +63,11 @@ # for the rule to exclude a set. Options can be preceded with a '!' to # match a logical NOT. +# The optional sevenths argument is a list of OS subdirectory names. +# The format is the same as of the second argument. +# The difference is that second argument describes multilib directories +# in GCC conventions, while this one the OS multilib convention. + # The output looks like # #define MULTILIB_MATCHES "\ # SUBDIRECTORY OPTIONS;\ @@ -79,17 +84,18 @@ # Here is an example (this is from the actual sparc64 case): # genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt' # 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*' -# 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany' +# '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany' +# '../lib64 ../lib32 alt' # This produces: # ". !m64 !m32 !mno-app-regs !mcmodel=medany;", -# "64 m64 !m32 !mno-app-regs !mcmodel=medany;", -# "32 !m64 m32 !mno-app-regs !mcmodel=medany;", +# "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;", +# "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;", # "alt !m64 !m32 mno-app-regs mcmodel=medany;", # "alt !m64 !m32 mno-app-regs !mcmodel=medany;", # "alt !m64 !m32 !mno-app-regs mcmodel=medany;", -# "64/alt m64 !m32 mno-app-regs mcmodel=medany;", -# "64/alt m64 !m32 mno-app-regs !mcmodel=medany;", -# "64/alt m64 !m32 !mno-app-regs mcmodel=medany;", +# "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;", +# "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;", +# "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;", # # The effect is that `gcc -mno-app-regs' (for example) will append "alt" # to the directory name when searching for libraries or startup files and @@ -106,6 +112,7 @@ matches=$3 exceptions=$4 extra=$5 exclusions=$6 +osdirnames=$7 echo "static const char *const multilib_raw[] = {" @@ -202,6 +209,29 @@ if [ -n "${dirnames}" ]; then done fi +# Construct a sed pattern which will convert option names to OS directory +# names. +toosdirnames= +if [ -n "${osdirnames}" ]; then + set x ${osdirnames} + shift + for set in ${options}; do + for opts in `echo ${set} | sed -e 's|/| |'g`; do + patt="/" + for opt in `echo ${opts} | sed -e 's_|_ _'g`; do + if [ "$1" != "${opt}" ]; then + toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g" + patt="${patt}${1}/" + if [ "${patt}" != "/${1}/" ]; then + toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g" + fi + fi + done + shift + done + done +fi + # We need another recursive shell script to correctly handle positive # matches. If we are invoked as # genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2" @@ -257,6 +287,16 @@ for combo in ${combinations}; do # Remove the leading and trailing slashes. dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'` + # Use the OS directory names rather than the option names. + if [ -n "${toosdirnames}" ]; then + osdirout=`echo ${combo} | sed ${toosdirnames}` + # Remove the leading and trailing slashes. + osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'` + if [ "x${dirout}" != "x${osdirout}" ]; then + dirout="${dirout}:${osdirout}" + fi + fi + # Look through the options. We must output each option that is # present, and negate each option that is not present. optout= @@ -313,6 +353,11 @@ done echo "NULL" echo "};" +# Output the options now +moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'` +echo "" +echo "static const char *multilib_options = \"${moptions}\";" + rm -f tmpmultilib2 exit 0 diff --git a/gcc/mklibgcc.in b/gcc/mklibgcc.in index 12f54460a6f0..81d2e47f52b8 100644 --- a/gcc/mklibgcc.in +++ b/gcc/mklibgcc.in @@ -32,7 +32,7 @@ # SHLIB_MAPFILES # SHLIB_NM_FLAGS # SHLIB_INSTALL -# SHLIB_SLIBDIR_SUFFIXES +# MULTILIB_OSDIRNAMES # Make needs VPATH to be literal. echo 'srcdir = @srcdir@' @@ -317,22 +317,18 @@ for ml in $MULTILIBS; do fi shlib_so_name="$shlib_base_name" shlib_dir= - if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then + if [ -n "$MULTILIB_OSDIRNAMES" ]; then if [ "$dir" != . ]; then + gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory` + os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory` shlib_dir="$dir"/ - for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do - base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'` - if [ "$dir" = "$base_ml_dir" ]; then - shlib_so_name=libgcc_s - break - else - canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"` - if [ -n "$canon_dir" ]; then - shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g` - break - fi - fi - done + gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'` + os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"` + if [ -z "$os_multilib_base" ]; then + shlib_so_name=libgcc_s + else + shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g` + fi fi fi echo "" @@ -438,6 +434,7 @@ echo "" echo "install: $all" for ml in $MULTILIBS; do dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; if [ $dir != . ]; then ldir='$(libsubdir)'/$dir echo " if [ -d $ldir ]; then true; else mkdir $ldir; chmod a+rx $ldir; fi;" @@ -460,39 +457,22 @@ for ml in $MULTILIBS; do shlib_so_name="$shlib_base_name" shlib_dir= shlib_slibdir_qual= - if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then - shlib_slibdir_qual=none + if [ -n "$MULTILIB_OSDIRNAMES" ]; then + gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory` + os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory` if [ "$dir" != . ]; then shlib_dir="$dir"/ - for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do - base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'` - if [ "$dir" = "$base_ml_dir" ]; then - shlib_so_name=libgcc_s - shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'` - break - else - canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"` - if [ -n "$canon_dir" ]; then - shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g` - shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'` - break - fi - fi - done fi - if [ "$shlib_slibdir_qual" = none ]; then - for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do - base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'` - shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'` - for ml2 in $MULTILIBS; do - dir2=`echo ${ml2} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` - if [ "$base_ml_dir" = "$dir2" ]; then - shlib_slibdir_qual= - break - fi - done - if [ -n "$shlib_slibdir_qual" ]; then break; fi - done + gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'` + os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"` + if [ -z "$os_multilib_base" ]; then + shlib_so_name=libgcc_s + if [ "$os_multilib_dir" != "." ]; then + shlib_slibdir_qual="/$os_multilib_dir" + fi + else + shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g` + shlib_slibdir_qual="/$os_multilib_base" fi fi echo " $SHLIB_INSTALL" \