diff mbox

support for multiarch systems

Message ID 4FE88F8E.5030100@ubuntu.com
State New
Headers show

Commit Message

Matthias Klose June 25, 2012, 4:19 p.m. UTC
On 25.06.2012 15:56, Joseph S. Myers wrote:
> On Mon, 25 Jun 2012, Matthias Klose wrote:
> 
>> Please find attached the patch updated for trunk 20120625, x86 only, tested on
>> x86-linux-gnu, KFreeBSD and the Hurd.
> 
> This patch appears to include changes to config.gcc for other targets, not 
> mentioned in your ChangeLog entries.  Please resubmit without those 
> changes, and submit them separately with their own rationale if needed.

my mistake, removed these bits now again.
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: Add tmake fragments to tmake_file ( i386/t-kfreebsd
	for i[34567]86-*-kfreebsd*-gnu and x86_64-*-kfreebsd*-gnu, i386/t-gnu
	for i[34567]86-*-gnu*).
	* config/i386/t-kfreebsd: Add multiarch names in
	MULTILIB_OSDIRNAMES, define MULTIARCH_DIRNAME.
	* config/i386/t-linux64: Likewise.
	* config/i386/t-linux: Define MULTIARCH_DIRNAME.
	* config/i386/t-gnu: Likewise.

Comments

Thomas Schwinge June 28, 2012, 10:01 a.m. UTC | #1
Hi!

On Mon, 25 Jun 2012 18:19:26 +0200, Matthias Klose <doko@ubuntu.com> wrote:
> On 25.06.2012 15:56, Joseph S. Myers wrote:
> > On Mon, 25 Jun 2012, Matthias Klose wrote:
> > 
> >> Please find attached the patch updated for trunk 20120625, x86 only, tested on
> >> x86-linux-gnu, KFreeBSD and the Hurd.

> 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: Add tmake fragments to tmake_file ( i386/t-kfreebsd
> 	for i[34567]86-*-kfreebsd*-gnu and x86_64-*-kfreebsd*-gnu, i386/t-gnu
> 	for i[34567]86-*-gnu*).
> 	* config/i386/t-kfreebsd: Add multiarch names in
> 	MULTILIB_OSDIRNAMES, define MULTIARCH_DIRNAME.
> 	* config/i386/t-linux64: Likewise.
> 	* config/i386/t-linux: Define MULTIARCH_DIRNAME.
> 	* config/i386/t-gnu: Likewise.

As I said before, »config/i386/t-{gnu,kfreebsd,linux}« are new files.
Instead of repeating: my comments from
<http://news.gmane.org/find-root.php?message_id=%3C87zk94cg1h.fsf%40schwinge.name%3E>
as well as the follow-up still hold.

> 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.

»ninth argument«.


Grüße,
 Thomas
Matthias Klose June 28, 2012, 10:42 a.m. UTC | #2
On 28.06.2012 12:01, Thomas Schwinge wrote:
> Hi!
> 
> On Mon, 25 Jun 2012 18:19:26 +0200, Matthias Klose <doko@ubuntu.com>
> wrote:
>> On 25.06.2012 15:56, Joseph S. Myers wrote:
>>> On Mon, 25 Jun 2012, Matthias Klose wrote:
>>> 
>>>> Please find attached the patch updated for trunk 20120625, x86 only,
>>>> tested on x86-linux-gnu, KFreeBSD and the Hurd.
> 
>> 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: Add tmake fragments to tmake_file ( i386/t-kfreebsd for
>> i[34567]86-*-kfreebsd*-gnu and x86_64-*-kfreebsd*-gnu, i386/t-gnu for
>> i[34567]86-*-gnu*). * config/i386/t-kfreebsd: Add multiarch names in 
>> MULTILIB_OSDIRNAMES, define MULTIARCH_DIRNAME. * config/i386/t-linux64:
>> Likewise. * config/i386/t-linux: Define MULTIARCH_DIRNAME. *
>> config/i386/t-gnu: Likewise.
> 
> As I said before, »config/i386/t-{gnu,kfreebsd,linux}« are new files. 
> Instead of repeating: my comments from 
> <http://news.gmane.org/find-root.php?message_id=%3C87zk94cg1h.fsf%40schwinge.name%3E>
>
> 
as well as the follow-up still hold.

Like

	* config/i386/t-gnu: New, define MULTIARCH_DIRNAME.

?

>> 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.
> 
> »ninth argument«.

fixed.
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 +3449,14 @@ 
 
 	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*)
 		;;
+	i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
+		tmake_file="${tmake_file} i386/t-linux i386/t-kfreebsd"
+		;;
+	i[34567]86-*-gnu*)
+		tmake_file="${tmake_file} i386/t-linux 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);
 	}