On 20.08.2011 21:51, Matthias Klose wrote:
> Multiarch [1] is the term being used to refer to the capability of a system to
> install and run applications of multiple different binary targets on the same
> system.

please find attached an updated for the trunk (2012-05-08). The multiarch
triplets are now defined in the Debian Wiki [1], and progress is made to get the
triplet definitions into Debian Policy [2].

  Matthias

[1] http://wiki.debian.org/Multiarch/Tuples
[2] http://bugs.debian.org/664257

gcc/

2012-05-08  Matthias Klose  <d...@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 (alpha/t-linux
        for alpha*-*-linux*, pa/t-linux for hppa*64*-*-linux*, ia64/t-glibc
        for ia64*-*-linux*, rs6000/t-linux for powerpc-*-linux*, 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/s390/t-linux64: Add multiarch names in MULTILIB_OSDIRNAMES.
        * config/sparc/t-linux64: Likewise.
        * config/rs6000/t-linux64: Likewise.
        * config/i386/t-linux64: Likewise.
        * config/mips/t-linux64: Likewise.
        * config/alpha/t-linux: Define MULTIARCH_DIRNAME.
        * config/arm/t-linux-eabi: Likewise.
        * config/i386/t-gnu: Likewise:
        * config/i386/t-linux: Likewise.
        * config/pa/t-linux: Likewise.
        * config/rs6000/t-linux: Likewise.
        * config/rs6000/t-spe: Likewise.
        * config/sparc/t-linux: Likewise.
        * config/ia64/t-glibc: Define MULTIARCH_DIRNAME for linux target.

Index: libstdc++-v3/python/hook.in
===================================================================
--- libstdc++-v3/python/hook.in (revision 187271)
+++ libstdc++-v3/python/hook.in (working copy)
@@ -47,7 +47,10 @@
     libdir = libdir[len (prefix):]
 
     # Compute the ".."s needed to get from libdir to the prefix.
-    dotdots = ('..' + os.sep) * len (libdir.split (os.sep))
+    backdirs = len (libdir.split (os.sep))
+    if not os.path.basename(os.path.dirname(__file__)).startswith('lib'):
+        backdirs += 1 # multiarch subdir
+    dotdots = ('..' + os.sep) * backdirs
 
     objfile = gdb.current_objfile ().filename
     dir_ = os.path.join (os.path.dirname (objfile), dotdots, pythondir)
Index: gcc/common.opt
===================================================================
--- gcc/common.opt      (revision 187271)
+++ gcc/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=)
 
@@ -2286,6 +2289,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
 
@@ -2342,6 +2349,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: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in     (revision 187271)
+++ gcc/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
 
@@ -1830,10 +1841,11 @@
            "$(MULTILIB_EXTRA_OPTS)" \
            "$(MULTILIB_EXCLUSIONS)" \
            "$(MULTILIB_OSDIRNAMES)" \
+           "$(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: gcc/config.gcc
===================================================================
--- gcc/config.gcc      (revision 187271)
+++ gcc/config.gcc      (working copy)
@@ -791,6 +791,7 @@
 case ${target} in
 alpha*-*-linux*)
        tm_file="elfos.h ${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h 
glibc-stdint.h"
+       tmake_file="${tmake_file} alpha/t-linux"
        extra_options="${extra_options} alpha/elf.opt"
        ;;
 alpha*-*-freebsd*)
@@ -1039,6 +1040,7 @@
        tm_file="pa/pa64-start.h ${tm_file} dbxelf.h elfos.h gnu-user.h linux.h 
\
                 glibc-stdint.h pa/pa-linux.h pa/pa64-regs.h pa/pa-64.h \
                 pa/pa64-linux.h"
+       tmake_file="${tmake_file} pa/t-linux"
        gas=yes gnu_ld=yes
        need_64bit_hwint=yes
        ;;
@@ -1046,6 +1048,7 @@
        target_cpu_default="MASK_PA_11|MASK_NO_SPACE_REGS"
        tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h 
pa/pa-linux.h \
                 pa/pa32-regs.h pa/pa32-linux.h"
+       tmake_file="${tmake_file} pa/t-linux"
        ;;
 # port not yet contributed.
 #hppa*-*-openbsd*)
@@ -1521,7 +1524,7 @@
        ;;
 ia64*-*-linux*)
        tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h 
ia64/sysv4.h ia64/linux.h"
-       tmake_file="${tmake_file} ia64/t-ia64 t-libunwind"
+       tmake_file="${tmake_file} ia64/t-ia64 ia64/t-glibc t-libunwind"
        target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
        ;;
 ia64*-*-hpux*)
@@ -2007,6 +2010,7 @@
                ;;
            *)
                tm_file="${tm_file} rs6000/linux.h glibc-stdint.h"
+               tmake_file="$tmake_file rs6000/t-linux"
                ;;
        esac
        case ${target} in
@@ -3472,10 +3476,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: gcc/config/s390/t-linux64
===================================================================
--- gcc/config/s390/t-linux64   (revision 187271)
+++ gcc/config/s390/t-linux64   (working copy)
@@ -7,4 +7,5 @@
 
 MULTILIB_OPTIONS = m64/m31
 MULTILIB_DIRNAMES = 64 32
-MULTILIB_OSDIRNAMES = ../lib64 $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)
+MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:s390x-linux-gnu)
+MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call 
if_multiarch,:s390-linux-gnu)
Index: gcc/config/i386/t-linux
===================================================================
--- gcc/config/i386/t-linux     (revision 0)
+++ gcc/config/i386/t-linux     (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-linux-gnu)
Index: gcc/config/i386/t-gnu
===================================================================
--- gcc/config/i386/t-gnu       (revision 0)
+++ gcc/config/i386/t-gnu       (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-gnu)
Index: gcc/config/i386/t-linux64
===================================================================
--- gcc/config/i386/t-linux64   (revision 187271)
+++ gcc/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: gcc/config/i386/t-kfreebsd
===================================================================
--- gcc/config/i386/t-kfreebsd  (revision 0)
+++ gcc/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: gcc/config/rs6000/t-linux64
===================================================================
--- gcc/config/rs6000/t-linux64 (revision 187271)
+++ gcc/config/rs6000/t-linux64 (working copy)
@@ -31,5 +31,7 @@
 MULTILIB_EXTRA_OPTS     = fPIC mstrict-align
 MULTILIB_EXCEPTIONS     = m64/msoft-float
 MULTILIB_EXCLUSIONS     = m64/!m32/msoft-float
-MULTILIB_OSDIRNAMES    = ../lib64 $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) nof
+MULTILIB_OSDIRNAMES    = ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
+MULTILIB_OSDIRNAMES    += $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call 
if_multiarch,:powerpc-linux-gnu)
+MULTILIB_OSDIRNAMES    += nof
 MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
Index: gcc/config/rs6000/t-spe
===================================================================
--- gcc/config/rs6000/t-spe     (revision 187271)
+++ gcc/config/rs6000/t-spe     (working copy)
@@ -71,3 +71,6 @@
                          mabi=altivec/mlittle \
                          maltivec/mlittle \
                          maltivec/mabi=altivec/mlittle
+
+MULTIARCH_DIRNAME = powerpc-linux-gnuspe$(if $(findstring 
rs6000/e500-double.h, $(tm_file)),,v1)
+
Index: gcc/config/rs6000/t-linux
===================================================================
--- gcc/config/rs6000/t-linux   (revision 0)
+++ gcc/config/rs6000/t-linux   (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = powerpc-linux-gnu
Index: gcc/config/pa/t-linux
===================================================================
--- gcc/config/pa/t-linux       (revision 0)
+++ gcc/config/pa/t-linux       (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = $(call if_multiarch,hppa-linux-gnu)
Index: gcc/config/ia64/t-glibc
===================================================================
--- gcc/config/ia64/t-glibc     (revision 0)
+++ gcc/config/ia64/t-glibc     (revision 0)
@@ -0,0 +1,3 @@
+ifneq (,$(findstring linux, $(target)))
+MULTIARCH_DIRNAME = $(call if_multiarch,ia64-linux-gnu)
+endif
Index: gcc/config/alpha/t-linux
===================================================================
--- gcc/config/alpha/t-linux    (revision 0)
+++ gcc/config/alpha/t-linux    (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = $(call if_multiarch,alpha-linux-gnu)
Index: gcc/config/mips/t-linux64
===================================================================
--- gcc/config/mips/t-linux64   (revision 187271)
+++ gcc/config/mips/t-linux64   (working copy)
@@ -18,4 +18,9 @@
 
 MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64
 MULTILIB_DIRNAMES = n32 32 64
-MULTILIB_OSDIRNAMES = ../lib32 ../lib ../lib64
+MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(target)))),el)
+MIPS_SOFT = $(if $(strip $(filter MASK_SOFT_FLOAT_ABI, $(target_cpu_default)) 
$(filter soft, $(with_float))),soft)
+MULTILIB_OSDIRNAMES = \
+       ../lib32$(call 
if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \
+       ../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \
+       ../lib64$(call 
if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT))
Index: gcc/config/sparc/t-linux64
===================================================================
--- gcc/config/sparc/t-linux64  (revision 187271)
+++ gcc/config/sparc/t-linux64  (working copy)
@@ -26,4 +26,5 @@
 
 MULTILIB_OPTIONS = m64/m32
 MULTILIB_DIRNAMES = 64 32
-MULTILIB_OSDIRNAMES = ../lib64 $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)
+MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:sparc64-linux-gnu)
+MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call 
if_multiarch,:sparc-linux-gnu)
Index: gcc/config/sparc/t-linux
===================================================================
--- gcc/config/sparc/t-linux    (revision 0)
+++ gcc/config/sparc/t-linux    (revision 0)
@@ -0,0 +1 @@
+MULTIARCH_DIRNAME = $(call if_multiarch,sparc-linux-gnu)
Index: gcc/config/arm/t-linux-eabi
===================================================================
--- gcc/config/arm/t-linux-eabi (revision 187271)
+++ gcc/config/arm/t-linux-eabi (working copy)
@@ -24,3 +24,6 @@
 #MULTILIB_OPTIONS     += mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te
 #MULTILIB_DIRNAMES    += fa606te fa626te fmp626 fa726te
 #MULTILIB_EXCEPTIONS  += *mthumb/*mcpu=fa606te *mthumb/*mcpu=fa626te 
*mthumb/*mcpu=fmp626 *mthumb/*mcpu=fa726te*
+
+ARM_EB = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),eb)
+MULTIARCH_DIRNAME = $(call if_multiarch,arm$(ARM_EB)-linux-gnueabi$(if 
$(filter hard,$(with_float)),hf))
Index: gcc/incpath.c
===================================================================
--- gcc/incpath.c       (revision 187271)
+++ gcc/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);
        }
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi (revision 187271)
+++ gcc/doc/invoke.texi (working copy)
@@ -6110,6 +6110,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: gcc/doc/install.texi
===================================================================
--- gcc/doc/install.texi        (revision 187271)
+++ gcc/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: gcc/doc/fragments.texi
===================================================================
--- gcc/doc/fragments.texi      (revision 187271)
+++ gcc/doc/fragments.texi      (working copy)
@@ -129,6 +129,36 @@
 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 the list
+of OS subdirectory names.  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 OS 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{!}, the os
+directory names are used exclusively.  Use the mapping when there is
+no one-to-one equivalence between GCC levels and the OS.
+
+For multilib enabled configurations (see @code{MULTIARCH_DIRNAME})
+below), the multilib name is appended to each directory name, separated
+by a colon (e.g. @samp{../lib:x86_64-linux-gnu}).
+
+@findex MULTIARCH_DIRNAME
+@item MULTIARCH_DIRNAME
+If @code{MULTIARCH_DIRNAME} is used, this variable specifies the
+multiarch name for this configuration.  For multiarch enabled
+configurations it is used to search libraries and crt files in
+@file{/lib/@var{multiarch}} and @file{/usr/lib/@var{multiarch}}, and
+system header files in @file{/usr/include/@var{multiarch}}.
+@code{MULTIARCH_DIRNAME} is not used for multilib enabled
+configurations, but encoded in @code{MULTILIB_OSDIRNAMES} instead.
+
+The multiarch tuples are defined
+in @uref{http://wiki.debian.org/Multiarch/Tuples}.
+
 @findex SPECS
 @item SPECS
 Unfortunately, setting @code{MULTILIB_EXTRA_OPTS} is not enough, since
Index: gcc/genmultilib
===================================================================
--- gcc/genmultilib     (revision 187271)
+++ gcc/genmultilib     (working copy)
@@ -73,6 +73,8 @@
 # the os directory names are used exclusively.  Use the mapping when
 # there is no one-to-one equivalence between GCC levels and the OS.
 
+# 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 ".".
 
@@ -121,7 +123,8 @@
 extra=$5
 exclusions=$6
 osdirnames=$7
-enable_multilib=$8
+multiarch=$8
+enable_multilib=$9
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -222,6 +225,9 @@
 # names.
 toosdirnames=
 defaultosdirname=
+if [ -n "${multiarch}" ]; then
+  defaultosdirname=::${multiarch}
+fi
 if [ -n "${osdirnames}" ]; then
   set x ${osdirnames}
   shift
@@ -229,6 +235,9 @@
     case "$1" in
       .=*)
         defaultosdirname=`echo $1 | sed 's|^.=|:|'`
+       if [ -n "${multiarch}" ]; then
+         defaultosdirname=${defaultosdirname}:${multiarch}
+       fi
        shift
        ;;
       *=*)
@@ -314,13 +323,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/gcc.c
===================================================================
--- gcc/gcc.c   (revision 187271)
+++ gcc/gcc.c   (working copy)
@@ -1153,6 +1153,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
@@ -2078,6 +2083,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;
@@ -2095,11 +2101,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;
@@ -2108,16 +2117,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);
        }
 
@@ -2146,6 +2154,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))
@@ -2970,6 +2988,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\
@@ -3244,6 +3265,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:
@@ -4896,6 +4918,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);
@@ -6545,6 +6576,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)
@@ -7527,10 +7567,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;
            }
        }
@@ -7592,7 +7648,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: gcc/configure.ac
===================================================================
--- gcc/configure.ac    (revision 187271)
+++ gcc/configure.ac    (working copy)
@@ -629,6 +629,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: gcc/cppdefault.c
===================================================================
--- gcc/cppdefault.c    (revision 187271)
+++ gcc/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: gcc/cppdefault.h
===================================================================
--- gcc/cppdefault.h    (revision 187271)
+++ gcc/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[];

Reply via email to