diff mbox

[v2] support for multiarch systems

Message ID 4FF9D5F7.6090505@ubuntu.com
State New
Headers show

Commit Message

Matthias Klose July 8, 2012, 6:48 p.m. UTC
Please find attached v2 of the patch updated for trunk 20120706, x86 only, tested on
x86-linux-gnu, KFreeBSD and the Hurd.

I left in the comment about the multiarch names, but I'm fine to change/discard
it. It was first required by Joseph Myers, then not found necessary by Paolo
Bonzini. The patch includes the changes suggested by Thomas Schwinge.

Ok for the trunk?

  Matthias
2012-06-25  Matthias Klose  <doko@ubuntu.com>

	* doc/invoke.texi: Document -print-multiarch.
	* doc/install.texi: Document --enable-multiarch.
	* doc/fragments.texi: Document MULTILIB_OSDIRNAMES, MULTIARCH_DIRNAME.
	* configure.ac: Add --enable-multiarch option.
	* configure.in: Regenerate.
	* Makefile.in (s-mlib): Pass MULTIARCH_DIRNAME to genmultilib.
	enable_multiarch, with_float: New macros.
	if_multiarch: New macro, define in terms of enable_multiarch.
	* genmultilib: Add new argument for the multiarch name.
	* gcc.c (multiarch_dir): Define.
	(for_each_path): Search for multiarch suffixes.
	(driver_handle_option): Handle multiarch option.
	(do_spec_1): Pass -imultiarch if defined.
	(main): Print multiarch.
	(set_multilib_dir): Separate multilib and multiarch names
	from multilib_select.
	(print_multilib_info): Ignore multiarch names in multilib_select.
	* incpath.c (add_standard_paths): Search the multiarch include dirs.
	* cppdeault.h (default_include): Document multiarch in multilib
	member.
	* cppdefault.c: [LOCAL_INCLUDE_DIR, STANDARD_INCLUDE_DIR] Add an
        include directory for multiarch directories.
	* common.opt: New options --print-multiarch and -imultilib.
	* config.gcc <i[34567]86-*-linux* | x86_64-*-linux*> (tmake_file):
	Include i386/t-linux.
	<i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu> (tmake_file):
	Include i386/t-kfreebsd.
	<i[34567]86-*-gnu*> (tmake_file): Include i386/t-gnu.
	* config/i386/t-linux64: Add multiarch names in
	MULTILIB_OSDIRNAMES, define MULTIARCH_DIRNAME.
	* config/i386/t-gnu: New file.
	* config/i386/t-kfreebsd: Likewise.
	* config/i386/t-linux: Likewise.

Comments

Thomas Schwinge July 18, 2012, 6:59 p.m. UTC | #1
Hi!

On Sun, 08 Jul 2012 20:48:23 +0200, Matthias Klose <doko@ubuntu.com> wrote:
> Please find attached v2 of the patch updated for trunk 20120706, x86 only, tested on
> x86-linux-gnu, KFreeBSD and the Hurd.

As suggested by Diego Novillo I have now attached this patch to
<http://gcc.gnu.org/PR53468>.

> I left in the comment about the multiarch names, but I'm fine to change/discard
> it. It was first required by Joseph Myers, then not found necessary by Paolo
> Bonzini. The patch includes the changes suggested by Thomas Schwinge.

I'm confirming that this version of that patch is identical to the patch
that I have been using "ever since", only this current one includes
additional documentation changes, and the s%eight%ninth documentation
change is missing from gcc/genmultilib.

> Ok for the trunk?
> 
>   Matthias
> 2012-06-25  Matthias Klose  <doko@ubuntu.com>
> 
> 	* doc/invoke.texi: Document -print-multiarch.
> 	* doc/install.texi: Document --enable-multiarch.
> 	* doc/fragments.texi: Document MULTILIB_OSDIRNAMES, MULTIARCH_DIRNAME.
> 	* configure.ac: Add --enable-multiarch option.
> 	* configure.in: Regenerate.
> 	* Makefile.in (s-mlib): Pass MULTIARCH_DIRNAME to genmultilib.
> 	enable_multiarch, with_float: New macros.
> 	if_multiarch: New macro, define in terms of enable_multiarch.
> 	* genmultilib: Add new argument for the multiarch name.
> 	* gcc.c (multiarch_dir): Define.
> 	(for_each_path): Search for multiarch suffixes.
> 	(driver_handle_option): Handle multiarch option.
> 	(do_spec_1): Pass -imultiarch if defined.
> 	(main): Print multiarch.
> 	(set_multilib_dir): Separate multilib and multiarch names
> 	from multilib_select.
> 	(print_multilib_info): Ignore multiarch names in multilib_select.
> 	* incpath.c (add_standard_paths): Search the multiarch include dirs.
> 	* cppdeault.h (default_include): Document multiarch in multilib
> 	member.
> 	* cppdefault.c: [LOCAL_INCLUDE_DIR, STANDARD_INCLUDE_DIR] Add an
>         include directory for multiarch directories.
> 	* common.opt: New options --print-multiarch and -imultilib.
> 	* config.gcc <i[34567]86-*-linux* | x86_64-*-linux*> (tmake_file):
> 	Include i386/t-linux.
> 	<i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu> (tmake_file):
> 	Include i386/t-kfreebsd.
> 	<i[34567]86-*-gnu*> (tmake_file): Include i386/t-gnu.
> 	* config/i386/t-linux64: Add multiarch names in
> 	MULTILIB_OSDIRNAMES, define MULTIARCH_DIRNAME.
> 	* config/i386/t-gnu: New file.
> 	* config/i386/t-kfreebsd: Likewise.
> 	* config/i386/t-linux: Likewise.


Grüße,
 Thomas
John David Anglin July 19, 2012, 1:12 a.m. UTC | #2
On Sun, 08 Jul 2012, Matthias Klose wrote:

> Please find attached v2 of the patch updated for trunk 20120706, x86 only, tested on
> x86-linux-gnu, KFreeBSD and the Hurd.

Currently, Debian gcc packages for hppa contain multiarch support.  Because
of this, I have used a multiarch patch for testing Debian Linux for hppa for
a long time.  My test system is multiarch.

It would make my life easier if the change included the multiarch bits for
hppa.  I imagine other Debian ports are in a similar situation.

Dave
David Miller July 19, 2012, 3:19 a.m. UTC | #3
From: John David Anglin <dave@hiauly1.hia.nrc.ca>
Date: Wed, 18 Jul 2012 21:12:26 -0400

> I imagine other Debian ports are in a similar situation.

GCC hacking has been extremely painful on sparc for me because of this
debian multiarch situation, so yes I'm in this group as well.
Joseph Myers July 19, 2012, 3:14 p.m. UTC | #4
On Wed, 18 Jul 2012, John David Anglin wrote:

> It would make my life easier if the change included the multiarch bits for
> hppa.  I imagine other Debian ports are in a similar situation.

I explained at length in reviews of previous patch versions how each 
architecture needs its own review to make sure that the changes for that 
architecture won't end up using an inappropriate multiarch name for some 
configure options, and thus it's best to get the basic support in first 
then handle each architecture individually with a separate patch.
diff mbox

Patch

Index: configure.ac
===================================================================
--- configure.ac	(revision 188931)
+++ configure.ac	(working copy)
@@ -623,6 +623,21 @@ 
 [], [enable_multilib=yes])
 AC_SUBST(enable_multilib)
 
+# Determine whether or not multiarch is enabled.
+AC_ARG_ENABLE(multiarch,
+[AS_HELP_STRING([--enable-multiarch],
+		[enable support for multiarch paths])],
+[case "${withval}" in
+yes|no|auto-detect) enable_multiarch=$withval;;
+*) AC_MSG_ERROR(bad value ${withval} given for --enable-multiarch option) ;;
+esac], [enable_multiarch=auto-detect])
+AC_MSG_CHECKING(for multiarch configuration)
+AC_SUBST(enable_multiarch)
+AC_MSG_RESULT($enable_multiarch)
+
+# needed for setting the multiarch name on ARM
+AC_SUBST(with_float)
+
 # Enable __cxa_atexit for C++.
 AC_ARG_ENABLE(__cxa_atexit,
 [AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])],
Index: cppdefault.c
===================================================================
--- cppdefault.c	(revision 188931)
+++ cppdefault.c	(working copy)
@@ -63,6 +63,7 @@ 
 #endif
 #ifdef LOCAL_INCLUDE_DIR
     /* /usr/local/include comes before the fixincluded header files.  */
+    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 2 },
     { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 },
 #endif
 #ifdef PREFIX_INCLUDE_DIR
@@ -90,6 +91,7 @@ 
 #endif
 #ifdef NATIVE_SYSTEM_HEADER_DIR
     /* /usr/include comes dead last.  */
+    { NATIVE_SYSTEM_HEADER_DIR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 2 },
     { NATIVE_SYSTEM_HEADER_DIR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 0 },
 #endif
     { 0, 0, 0, 0, 0, 0 }
Index: cppdefault.h
===================================================================
--- cppdefault.h	(revision 188931)
+++ cppdefault.h	(working copy)
@@ -43,9 +43,11 @@ 
 				   C++.  */
   const char add_sysroot;	/* FNAME should be prefixed by
 				   cpp_SYSROOT.  */
-  const char multilib;		/* FNAME should have the multilib path
-				   specified with -imultilib
-				   appended.  */
+  const char multilib;		/* FNAME should have appended
+				   - the multilib path specified with -imultilib
+				     when 1 is passed,
+				   - the multiarch path specified with
+				     -imultiarch, when 2 is passed.  */
 };
 
 extern const struct default_include cpp_include_defaults[];
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 188931)
+++ Makefile.in	(working copy)
@@ -350,6 +350,17 @@ 
 
 enable_plugin = @enable_plugin@
 
+# Multiarch support
+enable_multiarch = @enable_multiarch@
+with_float = @with_float@
+ifeq ($(enable_multiarch),yes)
+  if_multiarch = $(1)
+else ifeq ($(enable_multiarch),auto-detect)
+  if_multiarch = $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o),$(1))
+else
+  if_multiarch =
+endif
+
 CPPLIB = ../libcpp/libcpp.a
 CPPINC = -I$(srcdir)/../libcpp/include
 
@@ -1845,10 +1856,11 @@ 
 	    "$(MULTILIB_EXCLUSIONS)" \
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
+	    "$(MULTIARCH_DIRNAME)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no\
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' "$(MULTIARCH_DIRNAME)" no \
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
Index: genmultilib
===================================================================
--- genmultilib	(revision 188931)
+++ genmultilib	(working copy)
@@ -84,6 +84,8 @@ 
 # This argument can be used together with MULTILIB_EXCEPTIONS and will take
 # effect after the MULTILIB_EXCEPTIONS.
 
+# The optional eight argument is the multiarch name.
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -133,7 +135,8 @@ 
 exclusions=$6
 osdirnames=$7
 multilib_required=$8
-enable_multilib=$9
+multiarch=$9
+enable_multilib=${10}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -261,6 +264,9 @@ 
 # names.
 toosdirnames=
 defaultosdirname=
+if [ -n "${multiarch}" ]; then
+  defaultosdirname=::${multiarch}
+fi
 if [ -n "${osdirnames}" ]; then
   set x ${osdirnames}
   shift
@@ -268,6 +274,9 @@ 
     case "$1" in
       .=*)
         defaultosdirname=`echo $1 | sed 's|^.=|:|'`
+	if [ -n "${multiarch}" ]; then
+	  defaultosdirname=${defaultosdirname}:${multiarch}
+	fi
 	shift
 	;;
       *=*)
@@ -353,13 +362,13 @@ 
     dirout=`echo ${combo} | sed -e 's/=/-/g'`
   fi
   # Remove the leading and trailing slashes.
-  dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
+  dirout=`echo ${dirout} | sed -e 's|^/||' -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'`
+    osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/*:/*|:|' -e 's|/$||g'`
     if [ "x${enable_multilib}" != xyes ]; then
       dirout=".:${osdirout}"
       disable_multilib=yes
Index: gcc.c
===================================================================
--- gcc.c	(revision 188931)
+++ gcc.c	(working copy)
@@ -1154,6 +1154,11 @@ 
    set_multilib_dir based on the compilation options.  */
 
 static const char *multilib_os_dir;
+
+/* Subdirectory to use for locating libraries in multiarch conventions.  Set by
+   set_multilib_dir based on the compilation options.  */
+
+static const char *multiarch_dir;
 
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) in a compiler or link
@@ -2081,6 +2086,7 @@ 
   struct prefix_list *pl;
   const char *multi_dir = NULL;
   const char *multi_os_dir = NULL;
+  const char *multiarch_suffix = NULL;
   const char *multi_suffix;
   const char *just_multi_suffix;
   char *path = NULL;
@@ -2098,11 +2104,14 @@ 
     }
   if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
     multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
+  if (multiarch_dir)
+    multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
 
   while (1)
     {
       size_t multi_dir_len = 0;
       size_t multi_os_dir_len = 0;
+      size_t multiarch_len = 0;
       size_t suffix_len;
       size_t just_suffix_len;
       size_t len;
@@ -2111,16 +2120,15 @@ 
 	multi_dir_len = strlen (multi_dir);
       if (multi_os_dir)
 	multi_os_dir_len = strlen (multi_os_dir);
+      if (multiarch_suffix)
+	multiarch_len = strlen (multiarch_suffix);
       suffix_len = strlen (multi_suffix);
       just_suffix_len = strlen (just_multi_suffix);
 
       if (path == NULL)
 	{
 	  len = paths->max_len + extra_space + 1;
-	  if (suffix_len > multi_os_dir_len)
-	    len += suffix_len;
-	  else
-	    len += multi_os_dir_len;
+	  len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
 	  path = XNEWVEC (char, len);
 	}
 
@@ -2149,6 +2157,16 @@ 
 		break;
 	    }
 
+	  /* Now try the multiarch path.  */
+	  if (!skip_multi_dir
+	      && !pl->require_machine_suffix && multiarch_dir)
+	    {
+	      memcpy (path + len, multiarch_suffix, multiarch_len + 1);
+	      ret = callback (path, callback_info);
+	      if (ret)
+		break;
+	    }
+
 	  /* Now try the base path.  */
 	  if (!pl->require_machine_suffix
 	      && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
@@ -2974,6 +2992,9 @@ 
   fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library\n"), stdout);
   fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>\n"), stdout);
   fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>\n"), stdout);
+  fputs (_("\
+  -print-multiarch         Display the target's normalized GNU triplet, used as\n\
+                           a component in the library path\n"), stdout);
   fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc\n"), stdout);
   fputs (_("\
   -print-multi-lib         Display the mapping between command line options and\n\
@@ -3257,6 +3278,7 @@ 
     case OPT_print_multi_directory:
     case OPT_print_sysroot:
     case OPT_print_multi_os_directory:
+    case OPT_print_multiarch:
     case OPT_print_sysroot_headers_suffix:
     case OPT_time:
     case OPT_wrapper:
@@ -4910,6 +4932,15 @@ 
 		  do_spec_1 (" ", 0, NULL);
 		}
 
+	      if (multiarch_dir)
+		{
+		  do_spec_1 ("-imultiarch", 1, NULL);
+		  /* Make this a separate argument.  */
+		  do_spec_1 (" ", 0, NULL);
+		  do_spec_1 (multiarch_dir, 1, NULL);
+		  do_spec_1 (" ", 0, NULL);
+		}
+
 	      if (gcc_exec_prefix)
 		{
 		  do_spec_1 ("-iprefix", 1, NULL);
@@ -6575,6 +6606,15 @@ 
       return (0);
     }
 
+  if (print_multiarch)
+    {
+      if (multiarch_dir == NULL)
+	printf ("\n");
+      else
+	printf ("%s\n", multiarch_dir);
+      return (0);
+    }
+
   if (print_sysroot)
     {
       if (target_system_root)
@@ -7558,10 +7598,26 @@ 
 	    q++;
 	  if (q < end)
 	    {
-	      char *new_multilib_os_dir = XNEWVEC (char, end - q);
+	      const char *q2 = q + 1;
+	      char *new_multilib_os_dir;
+
+	      while (q2 < end && *q2 != ':')
+		q2++;
+	      if (*q2 == ':')
+		end = q2;
+	      new_multilib_os_dir = XNEWVEC (char, end - q);
 	      memcpy (new_multilib_os_dir, q + 1, end - q - 1);
 	      new_multilib_os_dir[end - q - 1] = '\0';
-	      multilib_os_dir = new_multilib_os_dir;
+	      multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : ".";
+
+	      end = this_path + this_path_len;
+	      if (q2 < end && *q2 == ':')
+		{
+		  char *new_multiarch_dir = XNEWVEC (char, end - q2);
+		  memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
+		  new_multiarch_dir[end - q2 - 1] = '\0';
+		  multiarch_dir = new_multiarch_dir;
+		}
 	      break;
 	    }
 	}
@@ -7623,7 +7679,7 @@ 
       /* When --disable-multilib was used but target defines
 	 MULTILIB_OSDIRNAMES, entries starting with .: are there just
 	 to find multilib_os_dir, so skip them from output.  */
-      if (this_path[0] == '.' && this_path[1] == ':')
+      if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
 	skip = 1;
 
       /* Check for matches with the multilib_exclusions. We don't bother
Index: config/i386/t-kfreebsd
===================================================================
--- config/i386/t-kfreebsd	(revision 0)
+++ config/i386/t-kfreebsd	(revision 0)
@@ -0,0 +1,5 @@ 
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-kfreebsd-gnu)
+
+# MULTILIB_OSDIRNAMES are set in t-linux64.
+KFREEBSD_OS = $(filter kfreebsd%, $(word 3, $(subst -, ,$(target))))
+MULTILIB_OSDIRNAMES := $(subst linux,$(KFREEBSD_OS),$(MULTILIB_OSDIRNAMES))
Index: config/i386/t-linux
===================================================================
--- config/i386/t-linux	(revision 0)
+++ config/i386/t-linux	(revision 0)
@@ -0,0 +1 @@ 
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-linux-gnu)
Index: config/i386/t-gnu
===================================================================
--- config/i386/t-gnu	(revision 0)
+++ config/i386/t-gnu	(revision 0)
@@ -0,0 +1 @@ 
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-gnu)
Index: config/i386/t-linux64
===================================================================
--- config/i386/t-linux64	(revision 188931)
+++ config/i386/t-linux64	(working copy)
@@ -34,6 +34,6 @@ 
 comma=,
 MULTILIB_OPTIONS    = $(subst $(comma),/,$(TM_MULTILIB_CONFIG))
 MULTILIB_DIRNAMES   = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS)))
-MULTILIB_OSDIRNAMES = m64=../lib64
-MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)
+MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu)
+MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu)
 MULTILIB_OSDIRNAMES+= mx32=../libx32
Index: common.opt
===================================================================
--- common.opt	(revision 188931)
+++ common.opt	(working copy)
@@ -345,6 +345,9 @@ 
 -print-multi-os-directory
 Driver Alias(print-multi-os-directory)
 
+-print-multiarch
+Driver Alias(print-multiarch)
+
 -print-prog-name
 Driver Separate Alias(print-prog-name=)
 
@@ -2298,6 +2301,10 @@ 
 Common Joined Var(plugindir_string) Init(0)
 -iplugindir=<dir>	Set <dir> to be the default plugin directory
 
+imultiarch
+Common Joined Separate RejectDriver Var(imultiarch) Init(0)
+-imultiarch <dir>	Set <dir> to be the multiarch include subdirectory
+
 l
 Driver Joined Separate
 
@@ -2354,6 +2361,9 @@ 
 
 print-multi-os-directory
 Driver Var(print_multi_os_directory)
+ 
+print-multiarch
+Driver Var(print_multiarch)
 
 print-prog-name=
 Driver JoinedOrMissing Var(print_prog_name)
Index: doc/install.texi
===================================================================
--- doc/install.texi	(revision 188931)
+++ doc/install.texi	(working copy)
@@ -1038,6 +1038,11 @@ 
 conventions, etc.@: should not be built.  The default is to build a
 predefined set of them.
 
+@item --enable-multiarch
+Specify wether to enable or disable multiarch support.  The default is
+to detect for glibc start files in a multiarch location, and enable it
+if the files are found.
+
 Some targets provide finer-grained control over which multilibs are built
 (e.g., @option{--disable-softfloat}):
 @table @code
Index: doc/fragments.texi
===================================================================
--- doc/fragments.texi	(revision 188931)
+++ doc/fragments.texi	(working copy)
@@ -93,6 +93,12 @@ 
 default value will be @code{MULTILIB_OPTIONS}, with all slashes treated
 as spaces.
 
+@code{MULTILIB_DIRNAMES} describes the multilib directories using GCC
+conventions and is applied to directories that are part of the GCC
+installation.  When multilib-enabled, the compiler will add a
+subdirectory of the form @var{prefix}/@var{multilib} before each
+directory in the search path for libraries and crt files.
+
 For example, if @code{MULTILIB_OPTIONS} is set to @samp{m68000/m68020
 msoft-float}, then the default value of @code{MULTILIB_DIRNAMES} is
 @samp{m68000 m68020 msoft-float}.  You may specify a different value if
@@ -152,6 +158,60 @@ 
 of options to be used for all builds.  If you set this, you should
 probably set @code{CRTSTUFF_T_CFLAGS} to a dash followed by it.
 
+@findex MULTILIB_OSDIRNAMES
+@item MULTILIB_OSDIRNAMES
+If @code{MULTILIB_OPTIONS} is used, this variable specifies 
+a list of subdirectory names, that are used to modify the search
+path depending on the chosen multilib.  Unlike @code{MULTILIB_DIRNAMES},
+@code{MULTILIB_OSDIRNAMES} describes the multilib directories using
+operating systems conventions, and is applied to the directories such as
+@code{lib} or those in the @env{LIBRARY_PATH} environment variable.
+The format is either the same as of
+@code{MULTILIB_DIRNAMES}, or a set of mappings.  When it is the same
+as @code{MULTILIB_DIRNAMES}, it describes the multilib directories
+using operating system conventions, rather than GCC conventions.  When it is a set
+of mappings of the form @var{gccdir}=@var{osdir}, the left side gives
+the GCC convention and the right gives the equivalent OS defined
+location.  If the @var{osdir} part begins with a @samp{!},
+GCC will not search in the non-multilib directory and use
+exclusively the multilib directory.  Otherwise, the compiler will
+examine the search path for libraries and crt files twice; the first
+time it will add @var{multilib} to each directory in the search path,
+the second it will not.
+
+For configurations that support both multilib and multiarch,
+@code{MULTILIB_OSDIRNAMES} also encodes the multiarch name, thus
+subsuming @code{MULTIARCH_DIRNAME}.  The multiarch name is appended to
+each directory name, separated by a colon (e.g.
+@samp{../lib32:i386-linux-gnu}).
+
+Each multiarch subdirectory will be searched before the corresponding OS
+multilib directory, for example @samp{/lib/i386-linux-gnu} before
+@samp{/lib/../lib32}.  The multiarch name will also be used to modify the
+system header search path, as explained for @code{MULTIARCH_DIRNAME}.
+
+@findex MULTIARCH_DIRNAME
+@item MULTIARCH_DIRNAME
+This variable specifies the multiarch name for configurations that are
+multiarch-enabled but not multilibbed configurations.
+
+The multiarch name is used to augment the search path for libraries, crt
+files and system header files with additional locations.  The compiler
+will add a multiarch subdirectory of the form
+@var{prefix}/@var{multiarch} before each directory in the library and
+crt search path.  It will also add two directories
+@code{LOCAL_INCLUDE_DIR}/@var{multiarch} and
+@code{NATIVE_SYSTEM_HEADER_DIR}/@var{multiarch}) to the system header
+search path, respectively before @code{LOCAL_INCLUDE_DIR} and
+@code{NATIVE_SYSTEM_HEADER_DIR}.
+
+@code{MULTIARCH_DIRNAME} is not used for configurations that support
+both multilib and multiarch.  In that case, multiarch names are encoded
+in @code{MULTILIB_OSDIRNAMES} instead.
+
+More documentation about multiarch can be found at
+@uref{http://wiki.debian.org/Multiarch}.
+
 @findex SPECS
 @item SPECS
 Unfortunately, setting @code{MULTILIB_EXTRA_OPTS} is not enough, since
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 188931)
+++ doc/invoke.texi	(working copy)
@@ -6111,6 +6111,11 @@ 
 @file{../lib32}, or if OS libraries are present in @file{lib/@var{subdir}}
 subdirectories it prints e.g.@: @file{amd64}, @file{sparcv9} or @file{ev6}.
 
+@item -print-multiarch
+@opindex print-multiarch
+Print the path to OS libraries for the selected multiarch,
+relative to some @file{lib} subdirectory.
+
 @item -print-prog-name=@var{program}
 @opindex print-prog-name
 Like @option{-print-file-name}, but searches for a program such as @samp{cpp}.
Index: config.gcc
===================================================================
--- config.gcc	(revision 188931)
+++ config.gcc	(working copy)
@@ -3445,10 +3445,15 @@ 
 
 	i[34567]86-*-darwin* | x86_64-*-darwin*)
 		;;
-	i[34567]86-*-linux* | x86_64-*-linux* | \
-	  i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu | \
-	  i[34567]86-*-gnu*)
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="$tmake_file i386/t-linux"
 		;;
+	i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
+		tmake_file="$tmake_file i386/t-kfreebsd"
+		;;
+	i[34567]86-*-gnu*)
+		tmake_file="$tmake_file i386/t-gnu"
+		;;
 	i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
 		;;
 	i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw*)
Index: incpath.c
===================================================================
--- incpath.c	(revision 188931)
+++ incpath.c	(working copy)
@@ -150,8 +150,14 @@ 
 	      if (!filename_ncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
 		{
 		  char *str = concat (iprefix, p->fname + len, NULL);
-		  if (p->multilib && imultilib)
+		  if (p->multilib == 1 && imultilib)
 		    str = concat (str, dir_separator_str, imultilib, NULL);
+		  else if (p->multilib == 2)
+		    {
+		      if (!imultiarch)
+			continue;
+		      str = concat (str, dir_separator_str, imultiarch, NULL);
+		    }
 		  add_path (str, SYSTEM, p->cxx_aware, false);
 		}
 	    }
@@ -203,8 +209,14 @@ 
 	  else
 	    str = update_path (p->fname, p->component);
 
-	  if (p->multilib && imultilib)
+	  if (p->multilib == 1 && imultilib)
 	    str = concat (str, dir_separator_str, imultilib, NULL);
+	  else if (p->multilib == 2)
+	    {
+	      if (!imultiarch)
+		continue;
+	      str = concat (str, dir_separator_str, imultiarch, NULL);
+	    }
 
 	  add_path (str, SYSTEM, p->cxx_aware, false);
 	}