public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] support for multiarch systems
@ 2011-08-20 21:07 Matthias Klose
  2011-08-20 21:16 ` Jakub Jelinek
                   ` (5 more replies)
  0 siblings, 6 replies; 47+ messages in thread
From: Matthias Klose @ 2011-08-20 21:07 UTC (permalink / raw)
  To: GCC Patches; +Cc: Steve Langasek

[-- Attachment #1: Type: text/plain, Size: 1590 bytes --]

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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
confused with multiarch in glibc).

Multiarch defines new system directories for headers and libraries/object files:

  /usr/include/<multiarch>
  /lib/<multiarch>
  /usr/lib/<multiarch>

  /usr/local/include/<multiarch>
  /usr/local/lib/<multiarch>

The attached patch

 - searches for multiarch subdirectories in the list of
   startfile_prefixes
 - passes the option -imultiarch to the compiler binaries
 - the compiler binaries add the multiarch include paths
   to the system include path.
 - adds a driver option -print-multiarch

The multiarch triplets are defined in the target specific tmake files, and
provided for all known existing multiarch implementations (currently Debian,
Ubuntu and derivatives).  For non-multilib'd configurations, the triplet is
defined in MULTIARCH_DIRNAME, for multilib'd configurations each directory in
MULTILIB_OSDIRNAMES gets an multiarch directory associated, separated by a colon
(e.g. ../lib:x86_64-linux-gnu).  The multiarch names are as used by Debian, the
mips names go back to a discussion from 2006 [3] to match the ones for glibc.

Tested on non-multilib'd and multilib'd systems, both native and cross builds.
Ok for the trunk?

  Matthias

[1] http://wiki.debian.org/Multiarch
[2] http://debconf5.debconf.org/comas/general/proposals/27.html
[3] http://lists.debian.org/debian-mips/2006/03/msg00004.html



[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 18777 bytes --]

2011-08-20  Matthias Klose  <doko@ubuntu.com>

	* doc/invoke.texi: Document -print-multiarch.
	* Makefile.in (s-mlib): Pass MULTIARCH_DIRNAME to genmultilib.
	* genmultilib: Add new option 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/s390/t-linux64: Add multiarch names in MULTILIB_OSDIRNAMES.
	* config/sparc/t-linux64: Likewise.
	* config/powerpc/t-linux64: Likewise.
	* config/i386/t-linux64: Likewise.
	* config/mips/t-linux64: Likewise.
	* config/alpha/t-linux: Define MULTIARCH_DIRNAME.
	* config/arm/t-linux: Likewise.
	* config/i386/t-linux: Likewise.
	* config/pa/t-linux: Likewise.
	* config/sparc/t-linux: Likewise.
	* config/ia64/t-glibc: Define MULTIARCH_DIRNAME for linux target.
	* gcc/config/i386/t-gnu: New, Define MULTIARCH_DIRNAME.
	* gcc/config/i386/t-kfreebsd: New, Define MULTIARCH_DIRNAME and
	MULTILIB_OSDIRNAMES.



Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 177846)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5937,6 +5937,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/incpath.c
===================================================================
--- gcc/incpath.c	(revision 177846)
+++ 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);
 		}
 	    }
@@ -195,8 +201,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/gcc.c
===================================================================
--- gcc/gcc.c	(revision 177846)
+++ gcc/gcc.c	(working copy)
@@ -1147,6 +1147,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;
 \f
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) in a compiler or link
@@ -2072,6 +2077,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;
@@ -2089,11 +2095,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;
@@ -2102,6 +2111,8 @@
 	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);
 
@@ -2140,6 +2151,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))
@@ -3238,6 +3259,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:
@@ -4891,6 +4913,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);
@@ -6508,6 +6539,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)
@@ -7483,10 +7523,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;
+
+	      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;
 	    }
 	}
@@ -7548,7 +7604,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/genmultilib
===================================================================
--- gcc/genmultilib	(revision 177846)
+++ 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/cppdefault.c
===================================================================
--- gcc/cppdefault.c	(revision 177846)
+++ gcc/cppdefault.c	(working copy)
@@ -64,6 +64,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
@@ -95,6 +96,7 @@
 #endif
 #ifdef STANDARD_INCLUDE_DIR
     /* /usr/include comes dead last.  */
+    { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 2 },
     { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 0 },
 #endif
     { 0, 0, 0, 0, 0, 0 }
Index: gcc/cppdefault.h
===================================================================
--- gcc/cppdefault.h	(revision 177846)
+++ 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[];
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 177846)
+++ 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=)
 
@@ -2231,6 +2234,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
 
@@ -2288,6 +2295,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/config.gcc
===================================================================
--- gcc/config.gcc	(revision 177846)
+++ gcc/config.gcc	(working copy)
@@ -1315,12 +1315,14 @@
 		;;
 	i[34567]86-*-kfreebsd*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kfreebsd-gnu.h i386/kfreebsd-gnu.h"
+		tmake_file="${tmake_file} i386/t-kfreebsd"
 		;;
 	i[34567]86-*-kopensolaris*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kopensolaris-gnu.h i386/kopensolaris-gnu.h"
 		;;
 	i[34567]86-*-gnu*)
 		tm_file="$tm_file i386/gnu-user.h gnu.h i386/gnu.h"
+		tmake_file="${tmake_file} i386/t-gnu"
 		;;
 	esac
 	tmake_file="${tmake_file} i386/t-crtstuff"
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 177846)
+++ gcc/Makefile.in	(working copy)
@@ -1935,10 +1935,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/alpha/t-linux
===================================================================
--- gcc/config/alpha/t-linux	(revision 177846)
+++ gcc/config/alpha/t-linux	(working copy)
@@ -1 +1,3 @@
 SHLIB_MAPFILES += $(srcdir)/config/alpha/libgcc-alpha-ldbl.ver
+
+MULTIARCH_DIRNAME = alpha-linux-gnu
Index: gcc/config/s390/t-linux64
===================================================================
--- gcc/config/s390/t-linux64	(revision 177846)
+++ gcc/config/s390/t-linux64	(working copy)
@@ -7,4 +7,4 @@
 
 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:s390x-linux-gnu $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib):s390-linux-gnu
Index: gcc/config/sparc/t-linux64
===================================================================
--- gcc/config/sparc/t-linux64	(revision 177846)
+++ gcc/config/sparc/t-linux64	(working copy)
@@ -26,7 +26,7 @@
 
 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:sparc64-linux-gnu $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib):sparc-linux-gnu
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
Index: gcc/config/sparc/t-linux
===================================================================
--- gcc/config/sparc/t-linux	(revision 177846)
+++ gcc/config/sparc/t-linux	(working copy)
@@ -3,3 +3,5 @@
 # Avoid the t-linux version file.
 SHLIB_MAPFILES = $$(libgcc_objdir)/libgcc-std.ver \
 		 $(srcdir)/config/sparc/libgcc-sparc-glibc.ver
+
+MULTIARCH_DIRNAME = sparc-linux-gnu
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 = i386-kfreebsd-gnu
+
+# MULTILIB_OSDIRNAMES are set in t-linux64.
+KFREEBSD_OS = $(filter kfreebsd%, $(word 3, $(subst -, ,$(arch2))))
+MULTILIB_OSDIRNAMES := $(subst linux,$(KFREEBSD_OS),$(MULTILIB_OSDIRNAMES))
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 = i386-gnu
Index: gcc/config/i386/t-linux
===================================================================
--- gcc/config/i386/t-linux	(revision 177846)
+++ gcc/config/i386/t-linux	(working copy)
@@ -3,3 +3,5 @@
 # t-slibgcc-elf-ver and t-linux
 SHLIB_MAPFILES = $$(libgcc_objdir)/libgcc-std.ver \
 		 $(srcdir)/config/i386/libgcc-glibc.ver
+
+MULTIARCH_DIRNAME = i386-linux-gnu
Index: gcc/config/i386/t-linux64
===================================================================
--- gcc/config/i386/t-linux64	(revision 177846)
+++ gcc/config/i386/t-linux64	(working copy)
@@ -34,8 +34,8 @@
 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:x86_64-linux-gnu
+MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib):i386-linux-gnu
 MULTILIB_OSDIRNAMES+= mx32=../libx32
 
 LIBGCC = stmp-multilib
Index: gcc/config/ia64/t-glibc
===================================================================
--- gcc/config/ia64/t-glibc	(revision 177846)
+++ gcc/config/ia64/t-glibc	(working copy)
@@ -1 +1,5 @@
 SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver
+
+ifneq (,$(findstring linux, $(target)))
+MULTIARCH_DIRNAME = ia64-linux-gnu
+endif
Index: gcc/config/m68k/t-linux
===================================================================
--- gcc/config/m68k/t-linux	(revision 177846)
+++ gcc/config/m68k/t-linux	(working copy)
@@ -21,6 +21,8 @@
 # Only include multilibs for 680x0 CPUs with an MMU.
 M68K_MLIB_CPU += && (CPU ~ "^m680") && (FLAGS ~ "FL_MMU")
 
+MULTIARCH_DIRNAME = m68k-linux-gnu
+
 # This rule uses MULTILIB_MATCHES to generate a definition of
 # SYSROOT_SUFFIX_SPEC.
 sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
Index: gcc/config/rs6000/t-linux64
===================================================================
--- gcc/config/rs6000/t-linux64	(revision 177846)
+++ gcc/config/rs6000/t-linux64	(working copy)
@@ -33,5 +33,5 @@
 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:powerpc64-linux-gnu $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib):powerpc-linux-gnu nof
 MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
Index: gcc/config/pa/t-linux
===================================================================
--- gcc/config/pa/t-linux	(revision 177846)
+++ gcc/config/pa/t-linux	(working copy)
@@ -35,3 +35,5 @@
 
 # Compile crtbeginS.o and crtendS.o as PIC.
 CRTSTUFF_T_CFLAGS_S = -fPIC
+
+MULTIARCH_DIRNAME = hppa-linux-gnu
Index: gcc/config/mips/t-linux64
===================================================================
--- gcc/config/mips/t-linux64	(revision 177846)
+++ gcc/config/mips/t-linux64	(working copy)
@@ -22,6 +22,10 @@
 else
 MULTILIB_DIRNAMES = n32 32 64
 endif
-MULTILIB_OSDIRNAMES = ../lib32 ../lib ../lib64
+MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(arch)))),el)
+MULTILIB_OSDIRNAMES = \
+	../lib32:mips64$(MIPS_EL)-linux-gnuabin32 \
+	../lib:mips$(MIPS_EL)-linux-gnu \
+	../lib64:mips64$(MIPS_EL)-linux-gnuabi64
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
@ 2011-08-20 21:16 ` Jakub Jelinek
  2011-08-21  2:22   ` Matthias Klose
  2011-08-20 21:44 ` Joseph S. Myers
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 47+ messages in thread
From: Jakub Jelinek @ 2011-08-20 21:16 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Steve Langasek

On Sat, Aug 20, 2011 at 09:51:33PM +0200, Matthias Klose wrote:
> Tested on non-multilib'd and multilib'd systems, both native and cross builds.
> Ok for the trunk?

I don't think we want to do this unconditionally, we already search way too
many directories by default.  This is a Debian/Ubuntu specific setup, I
don't think many others are going to use such a setup.
So, IMHO you should make it configure time selectable whether those extra
dirs are searched or not.  And by default either don't enable it, or enable
it only on Debian/Ubuntu.

	Jakub

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
  2011-08-20 21:16 ` Jakub Jelinek
@ 2011-08-20 21:44 ` Joseph S. Myers
  2011-08-21  7:55   ` Matthias Klose
  2011-08-21  9:05 ` Matthias Klose
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 47+ messages in thread
From: Joseph S. Myers @ 2011-08-20 21:44 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Steve Langasek

On Sat, 20 Aug 2011, Matthias Klose wrote:

> The multiarch triplets are defined in the target specific tmake files, and
> provided for all known existing multiarch implementations (currently Debian,
> Ubuntu and derivatives).  For non-multilib'd configurations, the triplet is

Is there a specification somewhere of what the various triplets mean?

> defined in MULTIARCH_DIRNAME, for multilib'd configurations each directory in
> MULTILIB_OSDIRNAMES gets an multiarch directory associated, separated by a colon

I don't see any documentation in fragments.texi for this 
(MULTIARCH_DIRNAME is new so certainly needs documenting, even if you get 
away with not adding to the nonexistent documentation for 
MULTILIB_OSDIRNAMES (PR 25508)).

> (e.g. ../lib:x86_64-linux-gnu).  The multiarch names are as used by Debian, the

Does this work with the "gccdir=osdir" and "gccdir=!osdir" cases before 
the colon?

> mips names go back to a discussion from 2006 [3] to match the ones for glibc.

For x86, shouldn't a name be allocated for x32?

For m68k, classic m68k and ColdFire have incompatible ABIs.  So you need 
to define what m68k-linux-gnu means of the two ABIs.  Unfortunately 
building for ColdFire has been broken for some time, since 
<http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01845.html> (this ought to 
have been dependent on the --with-arch configurey).

For 32-bit Power, hard-float and soft-float ABIs are incompatible.  
Furthermore, the soft-float ABI is used at function-calling level for 
e500v1 and e500v2 - but there are differences in the details of the glibc 
symbols exported (and at least the fenv.h ABI is incompatible between 
soft-float and e500).  So actually there are four variants at the glibc 
level.  You need to define what powerpc-linux-gnu means and avoid it being 
used for anything incompatible.

For MIPS, the hard-float and soft-float ABIs are incompatible.  So you 
need twelve triplets, not six.

For ARM, you have a ChangeLog entry with no corresponding patch.  You need 
to distinguish big and little endian; old ABI, EABI soft-float ABI and 
EABI hard-float ABI (six triplets).

Not all of those variants necessarily are configurable in a multilib 
configuration in the FSF tree (the e500 variants can be achieved with 
powerpc-linux-gnuspe triplets, for example, but those don't have other 
multilibs).  So maybe some of the names won't actually appear in the FSF 
sources - but you still need to define the semantics of the names that do 
appear (whether in the manuals, on the GCC wiki or elsewhere) and 
preferably have somewhere to define semantics for the names not used in 
multilib configurations in FSF GCC.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:16 ` Jakub Jelinek
@ 2011-08-21  2:22   ` Matthias Klose
  0 siblings, 0 replies; 47+ messages in thread
From: Matthias Klose @ 2011-08-21  2:22 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Matthias Klose, GCC Patches, Steve Langasek

On 08/20/2011 10:07 PM, Jakub Jelinek wrote:
> On Sat, Aug 20, 2011 at 09:51:33PM +0200, Matthias Klose wrote:
>> Tested on non-multilib'd and multilib'd systems, both native and cross builds.
>> Ok for the trunk?
> 
> I don't think we want to do this unconditionally, we already search way too
> many directories by default.  This is a Debian/Ubuntu specific setup, I
> don't think many others are going to use such a setup.
> So, IMHO you should make it configure time selectable whether those extra
> dirs are searched or not.  And by default either don't enable it, or enable
> it only on Debian/Ubuntu.

Ok, I made it conditional, enabled only if the crti.o file is found in a
multiarch path.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:44 ` Joseph S. Myers
@ 2011-08-21  7:55   ` Matthias Klose
  2011-08-21 10:20     ` Andrew Pinski
  2011-08-21 16:23     ` Joseph S. Myers
  0 siblings, 2 replies; 47+ messages in thread
From: Matthias Klose @ 2011-08-21  7:55 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Matthias Klose, GCC Patches, Steve Langasek

On 08/20/2011 10:39 PM, Joseph S. Myers wrote:
> On Sat, 20 Aug 2011, Matthias Klose wrote:
> 
>> The multiarch triplets are defined in the target specific tmake files, and
>> provided for all known existing multiarch implementations (currently Debian,
>> Ubuntu and derivatives).  For non-multilib'd configurations, the triplet is
> 
> Is there a specification somewhere of what the various triplets mean?

there is
https://lists.linux-foundation.org/pipermail/lsb-discuss/2011-February/006674.html
http://wiki.debian.org/Multiarch/Tuples

but the documentation is not up to date. The tuples in use are:

$ for a in alpha amd64 armel armhf hppa i386 ia64 mips mipsel powerpc powerpcspe
ppc64 s390 s390x sh4 sparc sparc64 kfreebsd-i386 kfreebsd-amd64 hurd-i386; do
dpkg-architecture -a$a -qDEB_HOST_MULTIARCH 2>/dev/null; done
alpha-linux-gnu
x86_64-linux-gnu
arm-linux-gnueabi
arm-linux-gnueabihf
hppa-linux-gnu
i386-linux-gnu
ia64-linux-gnu
mips-linux-gnu
mipsel-linux-gnu
powerpc-linux-gnu
powerpc-linux-gnuspe
powerpc64-linux-gnu
s390-linux-gnu
s390x-linux-gnu
sh4-linux-gnu
sparc-linux-gnu
sparc64-linux-gnu
i386-kfreebsd-gnu
x86_64-kfreebsd-gnu
i386-gnu

>> defined in MULTIARCH_DIRNAME, for multilib'd configurations each directory in
>> MULTILIB_OSDIRNAMES gets an multiarch directory associated, separated by a colon
> 
> I don't see any documentation in fragments.texi for this 
> (MULTIARCH_DIRNAME is new so certainly needs documenting, even if you get 
> away with not adding to the nonexistent documentation for 
> MULTILIB_OSDIRNAMES (PR 25508)).

well, I hope I get away with copying it from genmultilib without closing the
report ;)

>> (e.g. ../lib:x86_64-linux-gnu).  The multiarch names are as used by Debian, the
> 
> Does this work with the "gccdir=osdir" and "gccdir=!osdir" cases before 
> the colon?

amd64 is configured this way, and I don't handle the !osdir case other than for
the multilib osdir.

>> mips names go back to a discussion from 2006 [3] to match thee, ones for glibc.
> 
> For x86, shouldn't a name be allocated for x32?

maybe, but I didn't see a port yet.

> For m68k, classic m68k and ColdFire have incompatible ABIs.  So you need 
> to define what m68k-linux-gnu means of the two ABIs.  Unfortunately 
> building for ColdFire has been broken for some time, since 
> <http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01845.html> (this ought to 
> have been dependent on the --with-arch configurey).

it's the classic m68k. yes, it has to be defined.

> For 32-bit Power, hard-float and soft-float ABIs are incompatible.  
> Furthermore, the soft-float ABI is used at function-calling level for 
> e500v1 and e500v2 - but there are differences in the details of the glibc 
> symbols exported (and at least the fenv.h ABI is incompatible between 
> soft-float and e500).  So actually there are four variants at the glibc 
> level.  You need to define what powerpc-linux-gnu means and avoid it being 
> used for anything incompatible.

same here. powerpc-linux-gnu is the hard-float one. Debian has an e500 port in
development which currently uses powerpc-linux-gnuspe

> For MIPS, the hard-float and soft-float ABIs are incompatible.  So you 
> need twelve triplets, not six.

yes. but I didn't see a soft-float mips port yet.

> For ARM, you have a ChangeLog entry with no corresponding patch.  You need 
> to distinguish big and little endian; old ABI, EABI soft-float ABI and 
> EABI hard-float ABI (six triplets).

ok, added. Debian has little endian ports only. I see that dpkg treats the
obsolete armeb port as armeb-linux-gnu.

> Not all of those variants necessarily are configurable in a multilib 
> configuration in the FSF tree (the e500 variants can be achieved with 
> powerpc-linux-gnuspe triplets, for example, but those don't have other 
> multilibs).  So maybe some of the names won't actually appear in the FSF 
> sources - but you still need to define the semantics of the names that do 
> appear (whether in the manuals, on the GCC wiki or elsewhere) and 
> preferably have somewhere to define semantics for the names not used in 
> multilib configurations in FSF GCC.

For now, the multiarch documentation should be consolidated; I would like to add
a link from the FCC wiki to this documentation mentioned above.

  Matthias



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
  2011-08-20 21:16 ` Jakub Jelinek
  2011-08-20 21:44 ` Joseph S. Myers
@ 2011-08-21  9:05 ` Matthias Klose
  2011-08-22 18:51   ` Toon Moene
                     ` (2 more replies)
  2012-05-08  1:04 ` Matthias Klose
                   ` (2 subsequent siblings)
  5 siblings, 3 replies; 47+ messages in thread
From: Matthias Klose @ 2011-08-21  9:05 UTC (permalink / raw)
  To: GCC Patches; +Cc: Steve Langasek

[-- Attachment #1: Type: text/plain, Size: 411 bytes --]

On 08/20/2011 09:51 PM, 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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
> confused with multiarch in glibc).

attached is an updated patch which includes feedback from Jakub and Joseph.

  Matthias


[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 24153 bytes --]

2011-08-21  Matthias Klose  <doko@ubuntu.com>

	* doc/invoke.texi: Document -print-multiarch.
	* doc/install.texi: Document --enable-multiarch.
	* doc/fragments.texi (MULTILIB_OSDIRNAMES): Document optional
	multiarch name. (MULTIARCH_DIRNAME): Document.
	* configure.ac: New option --enable-multiarch. Substitute with_float.
	* configure: Regenerate.
	* Makefile.in (s-mlib): Pass MULTIARCH_DIRNAME to genmultilib.
	(if_multiarch): Helper macro for use in tmake_files.
	(with_float): Define.
	* genmultilib: Add new option 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/s390/t-linux64: Add multiarch names in MULTILIB_OSDIRNAMES.
	* config/sparc/t-linux64: Likewise.
	* config/powerpc/t-linux64: Likewise.
	* config/i386/t-linux64: Likewise.
	* config/mips/t-linux64: Likewise.
	* config/alpha/t-linux: Define MULTIARCH_DIRNAME.
	* config/arm/t-linux: Likewise.
	* config/i386/t-linux: Likewise.
	* config/pa/t-linux: Likewise.
	* config/sparc/t-linux: Likewise.
	* config/ia64/t-glibc: Define MULTIARCH_DIRNAME for linux target.
	* gcc/config/i386/t-gnu: New, Define MULTIARCH_DIRNAME.
	* gcc/config/i386/t-kfreebsd: New, Define MULTIARCH_DIRNAME and
	MULTILIB_OSDIRNAMES.



Index: gcc/doc/fragments.texi
===================================================================
--- gcc/doc/fragments.texi	(revision 177846)
+++ gcc/doc/fragments.texi	(working copy)
@@ -128,6 +128,33 @@
 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.
+
 @findex NATIVE_SYSTEM_HEADER_DIR
 @item NATIVE_SYSTEM_HEADER_DIR
 If the default location for system headers is not @file{/usr/include},
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 177846)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5937,6 +5937,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 177846)
+++ gcc/doc/install.texi	(working copy)
@@ -1028,6 +1028,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/incpath.c
===================================================================
--- gcc/incpath.c	(revision 177846)
+++ 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);
 		}
 	    }
@@ -195,8 +201,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/gcc.c
===================================================================
--- gcc/gcc.c	(revision 177846)
+++ gcc/gcc.c	(working copy)
@@ -1147,6 +1147,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;
 \f
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) in a compiler or link
@@ -2072,6 +2077,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;
@@ -2089,11 +2095,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;
@@ -2102,6 +2111,8 @@
 	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);
 
@@ -2140,6 +2151,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))
@@ -3238,6 +3259,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:
@@ -4891,6 +4913,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);
@@ -6508,6 +6539,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)
@@ -7483,10 +7523,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;
+
+	      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;
 	    }
 	}
@@ -7548,7 +7604,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/genmultilib
===================================================================
--- gcc/genmultilib	(revision 177846)
+++ 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/configure.ac
===================================================================
--- gcc/configure.ac	(revision 177846)
+++ gcc/configure.ac	(working copy)
@@ -611,6 +611,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 177846)
+++ gcc/cppdefault.c	(working copy)
@@ -64,6 +64,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
@@ -95,6 +96,7 @@
 #endif
 #ifdef STANDARD_INCLUDE_DIR
     /* /usr/include comes dead last.  */
+    { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 2 },
     { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 0 },
 #endif
     { 0, 0, 0, 0, 0, 0 }
Index: gcc/cppdefault.h
===================================================================
--- gcc/cppdefault.h	(revision 177846)
+++ 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[];
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 177846)
+++ 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=)
 
@@ -2231,6 +2234,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
 
@@ -2288,6 +2295,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/config.gcc
===================================================================
--- gcc/config.gcc	(revision 177846)
+++ gcc/config.gcc	(working copy)
@@ -1315,12 +1315,14 @@
 		;;
 	i[34567]86-*-kfreebsd*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kfreebsd-gnu.h i386/kfreebsd-gnu.h"
+		tmake_file="${tmake_file} i386/t-kfreebsd"
 		;;
 	i[34567]86-*-kopensolaris*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kopensolaris-gnu.h i386/kopensolaris-gnu.h"
 		;;
 	i[34567]86-*-gnu*)
 		tm_file="$tm_file i386/gnu-user.h gnu.h i386/gnu.h"
+		tmake_file="${tmake_file} i386/t-gnu"
 		;;
 	esac
 	tmake_file="${tmake_file} i386/t-crtstuff"
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 177846)
+++ 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
 
@@ -1935,10 +1946,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/alpha/t-linux
===================================================================
--- gcc/config/alpha/t-linux	(revision 177846)
+++ gcc/config/alpha/t-linux	(working copy)
@@ -1 +1,3 @@
 SHLIB_MAPFILES += $(srcdir)/config/alpha/libgcc-alpha-ldbl.ver
+
+MULTIARCH_DIRNAME = $(call if_multiarch,alpha-linux-gnu)
Index: gcc/config/s390/t-linux64
===================================================================
--- gcc/config/s390/t-linux64	(revision 177846)
+++ 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/sparc/t-linux64
===================================================================
--- gcc/config/sparc/t-linux64	(revision 177846)
+++ gcc/config/sparc/t-linux64	(working copy)
@@ -26,7 +26,8 @@
 
 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)
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
Index: gcc/config/sparc/t-linux
===================================================================
--- gcc/config/sparc/t-linux	(revision 177846)
+++ gcc/config/sparc/t-linux	(working copy)
@@ -3,3 +3,5 @@
 # Avoid the t-linux version file.
 SHLIB_MAPFILES = $$(libgcc_objdir)/libgcc-std.ver \
 		 $(srcdir)/config/sparc/libgcc-sparc-glibc.ver
+
+MULTIARCH_DIRNAME = $(call if_multiarch,sparc-linux-gnu)
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/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-linux
===================================================================
--- gcc/config/i386/t-linux	(revision 177846)
+++ gcc/config/i386/t-linux	(working copy)
@@ -3,3 +3,5 @@
 # t-slibgcc-elf-ver and t-linux
 SHLIB_MAPFILES = $$(libgcc_objdir)/libgcc-std.ver \
 		 $(srcdir)/config/i386/libgcc-glibc.ver
+
+MULTIARCH_DIRNAME = $(call if_multiarch,i386-linux-gnu)
Index: gcc/config/i386/t-linux64
===================================================================
--- gcc/config/i386/t-linux64	(revision 177846)
+++ gcc/config/i386/t-linux64	(working copy)
@@ -34,8 +34,8 @@
 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
 
 LIBGCC = stmp-multilib
Index: gcc/config/ia64/t-glibc
===================================================================
--- gcc/config/ia64/t-glibc	(revision 177846)
+++ gcc/config/ia64/t-glibc	(working copy)
@@ -1 +1,5 @@
 SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver
+
+ifneq (,$(findstring linux, $(target)))
+MULTIARCH_DIRNAME = $(call if_multiarch,ia64-linux-gnu)
+endif
Index: gcc/config/m68k/t-linux
===================================================================
--- gcc/config/m68k/t-linux	(revision 177846)
+++ gcc/config/m68k/t-linux	(working copy)
@@ -21,6 +21,8 @@
 # Only include multilibs for 680x0 CPUs with an MMU.
 M68K_MLIB_CPU += && (CPU ~ "^m680") && (FLAGS ~ "FL_MMU")
 
+MULTIARCH_DIRNAME = $(call if_multiarch,m68k-linux-gnu)
+
 # This rule uses MULTILIB_MATCHES to generate a definition of
 # SYSROOT_SUFFIX_SPEC.
 sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
Index: gcc/config/rs6000/t-linux64
===================================================================
--- gcc/config/rs6000/t-linux64	(revision 177846)
+++ gcc/config/rs6000/t-linux64	(working copy)
@@ -33,5 +33,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/arm/t-linux-eabi
===================================================================
--- gcc/config/arm/t-linux-eabi	(revision 177846)
+++ gcc/config/arm/t-linux-eabi	(working copy)
@@ -28,6 +28,8 @@
 #MULTILIB_DIRNAMES    += fa606te fa626te fmp626 fa726te
 #MULTILIB_EXCEPTIONS  += *mthumb/*mcpu=fa606te *mthumb/*mcpu=fa626te *mthumb/*mcpu=fmp626 *mthumb/*mcpu=fa726te*
 
+MULTIARCH_DIRNAME = $(call if_multiarch,arm-linux-gnueabi$(if $(filter hard,$(with_float)),hf))
+
 # Use a version of div0 which raises SIGFPE, and a special __clear_cache.
 LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx _clear_cache
 
Index: gcc/config/pa/t-linux
===================================================================
--- gcc/config/pa/t-linux	(revision 177846)
+++ gcc/config/pa/t-linux	(working copy)
@@ -35,3 +35,5 @@
 
 # Compile crtbeginS.o and crtendS.o as PIC.
 CRTSTUFF_T_CFLAGS_S = -fPIC
+
+MULTIARCH_DIRNAME = $(call if_multiarch,hppa-linux-gnu)
Index: gcc/config/mips/t-linux64
===================================================================
--- gcc/config/mips/t-linux64	(revision 177846)
+++ gcc/config/mips/t-linux64	(working copy)
@@ -22,6 +22,10 @@
 else
 MULTILIB_DIRNAMES = n32 32 64
 endif
-MULTILIB_OSDIRNAMES = ../lib32 ../lib ../lib64
+MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(arch)))),el)
+MULTILIB_OSDIRNAMES = \
+	../lib32$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32) \
+	../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu) \
+	../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64)
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-21  7:55   ` Matthias Klose
@ 2011-08-21 10:20     ` Andrew Pinski
  2011-08-21 16:23     ` Joseph S. Myers
  1 sibling, 0 replies; 47+ messages in thread
From: Andrew Pinski @ 2011-08-21 10:20 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Joseph S. Myers, GCC Patches, Steve Langasek

On Sat, Aug 20, 2011 at 5:11 PM, Matthias Klose <doko@ubuntu.com> wrote:
>> For MIPS, the hard-float and soft-float ABIs are incompatible.  So you
>> need twelve triplets, not six.
>
> yes. but I didn't see a soft-float mips port yet.

We at Cavium has a soft-float mips port and in fact use debian as a
base OS for o32 (but hard float) and have our own n32/n64 libraries
which are soft-float.  mips64octeon-linux-gnu is a soft-float port
which can be used right now; I use that triplet right now to build GCC
on this soft-float based port.

Thanks,
Andrew Pinski

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-21  7:55   ` Matthias Klose
  2011-08-21 10:20     ` Andrew Pinski
@ 2011-08-21 16:23     ` Joseph S. Myers
  1 sibling, 0 replies; 47+ messages in thread
From: Joseph S. Myers @ 2011-08-21 16:23 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Steve Langasek

On Sun, 21 Aug 2011, Matthias Klose wrote:

> powerpc-linux-gnuspe

As noted, that's ambiguous; --enable-e500-double determines whether it's 
e500v1 or e500v2, and since those have slightly different symbols exported 
from libc I think they should be considered different here.

> > For MIPS, the hard-float and soft-float ABIs are incompatible.  So you 
> > need twelve triplets, not six.
> 
> yes. but I didn't see a soft-float mips port yet.

You can configure MIPS targets (including multilib MIPS64 ones) using 
--with-float=soft, so need to allow for that.

> > For ARM, you have a ChangeLog entry with no corresponding patch.  You need 
> > to distinguish big and little endian; old ABI, EABI soft-float ABI and 
> > EABI hard-float ABI (six triplets).
> 
> ok, added. Debian has little endian ports only. I see that dpkg treats the
> obsolete armeb port as armeb-linux-gnu.

The arm*-*-linux* config.gcc code has

        arm*b-*)
                tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
                ;;
        esac

so again this should affect whether "eb" goes in the name.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-21  9:05 ` Matthias Klose
@ 2011-08-22 18:51   ` Toon Moene
  2011-09-06  6:57   ` Thomas Schwinge
  2011-11-01 19:48   ` Marc Glisse
  2 siblings, 0 replies; 47+ messages in thread
From: Toon Moene @ 2011-08-22 18:51 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Steve Langasek

On 08/21/2011 02:14 AM, Matthias Klose wrote:

> On 08/20/2011 09:51 PM, 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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
>> confused with multiarch in glibc).
>
> attached is an updated patch which includes feedback from Jakub and Joseph.

Perhaps I could "like" this patch ?  It probably solves

http://gcc.gnu.org/ml/gcc-testresults/2011-08/msg02398.html

[ My system is Debian Testing, updated 20110821 at 12:15 UTC ]

(h/t Mark Glisse).

Thanks in advance,

-- 
Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands
At home: http://moene.org/~toon/; weather: http://moene.org/~hirlam/
Progress of GNU Fortran: http://gcc.gnu.org/wiki/GFortran#news

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-21  9:05 ` Matthias Klose
  2011-08-22 18:51   ` Toon Moene
@ 2011-09-06  6:57   ` Thomas Schwinge
  2011-11-01 19:48   ` Marc Glisse
  2 siblings, 0 replies; 47+ messages in thread
From: Thomas Schwinge @ 2011-09-06  6:57 UTC (permalink / raw)
  To: Matthias Klose, GCC Patches; +Cc: Steve Langasek

[-- Attachment #1: Type: text/plain, Size: 2566 bytes --]

Hi!

On Sun, 21 Aug 2011 02:14:10 +0200, Matthias Klose <doko@ubuntu.com> wrote:
Non-text part: multipart/mixed
> On 08/20/2011 09:51 PM, 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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
> > confused with multiarch in glibc).
> 
> attached is an updated patch which includes feedback from Jakub and Joseph.

I can confirm that this restores out-of-the box GCC bootstrap on Debian
GNU/Linux testing 386 and Debian GNU/Hurd unstable i386.  Thanks!

A hint for the kids trying this patch at home: don't forget to regenerate
gcc/configure...  (Saves you some hours...)  ;-)


Matthias, please put the following patch on top, though.  (For preserving
the order of using i386/t-linux (which should be renamed i386/t-gnu-user,
but that's for another day) and i386/t-{gnu,kfreebsd}.

	* gcc/config.gcc <i[34567]86-*-kfreebsd*-gnu, x86_64-*-kfreebsd*-gnu>
	<i[34567]86-*-gnu*>: Take care to put their configuration files after
	the i386/t-linux one.
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 784ddd7..7d0214f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1317,14 +1317,12 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
 		;;
 	i[34567]86-*-kfreebsd*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kfreebsd-gnu.h i386/kfreebsd-gnu.h"
-		tmake_file="${tmake_file} i386/t-kfreebsd"
 		;;
 	i[34567]86-*-kopensolaris*-gnu)
 		tm_file="${tm_file} i386/gnu-user.h kopensolaris-gnu.h i386/kopensolaris-gnu.h"
 		;;
 	i[34567]86-*-gnu*)
 		tm_file="$tm_file i386/gnu-user.h gnu.h i386/gnu.h"
-		tmake_file="${tmake_file} i386/t-gnu"
 		;;
 	esac
 	tmake_file="${tmake_file} i386/t-crtstuff"
@@ -3587,11 +3585,15 @@ case ${target} in
 
 	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-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*)


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-21  9:05 ` Matthias Klose
  2011-08-22 18:51   ` Toon Moene
  2011-09-06  6:57   ` Thomas Schwinge
@ 2011-11-01 19:48   ` Marc Glisse
  2011-11-02  0:53     ` Joseph S. Myers
  2 siblings, 1 reply; 47+ messages in thread
From: Marc Glisse @ 2011-11-01 19:48 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Steve Langasek

On Sun, 21 Aug 2011, Matthias Klose wrote:

> On 08/20/2011 09:51 PM, 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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
>> confused with multiarch in glibc).
>
> attached is an updated patch which includes feedback from Jakub and Joseph.

Hello,

what is the status of this patch? Is it waiting for a review? Having gcc 
4.7 work out of the box on 2 of the most popular linux distributions seems 
like an important feature...

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-11-01 19:48   ` Marc Glisse
@ 2011-11-02  0:53     ` Joseph S. Myers
  0 siblings, 0 replies; 47+ messages in thread
From: Joseph S. Myers @ 2011-11-02  0:53 UTC (permalink / raw)
  To: GCC Patches; +Cc: Matthias Klose, Steve Langasek

On Tue, 1 Nov 2011, Marc Glisse wrote:

> On Sun, 21 Aug 2011, Matthias Klose wrote:
> 
> > On 08/20/2011 09:51 PM, 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.  The idea and name of multiarch dates back to 2004/2005 [2] (to be
> > > confused with multiarch in glibc).
> > 
> > attached is an updated patch which includes feedback from Jakub and Joseph.
> 
> Hello,
> 
> what is the status of this patch? Is it waiting for a review? Having gcc 4.7
> work out of the box on 2 of the most popular linux distributions seems like an
> important feature...

There were comments of mine that remained unaddressed in the version to 
which you replied and I don't recall a version that addressed them.  So 
there isn't a patch ready for review.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
                   ` (2 preceding siblings ...)
  2011-08-21  9:05 ` Matthias Klose
@ 2012-05-08  1:04 ` Matthias Klose
  2012-05-08 13:21   ` Joseph S. Myers
  2012-06-25 13:23 ` Matthias Klose
  2012-07-08 18:50 ` [patch v2] " Matthias Klose
  5 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-05-08  1:04 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 506 bytes --]

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


[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 27364 bytes --]

gcc/

2012-05-08  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 (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;
 \f
 /* 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[];

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-08  1:04 ` Matthias Klose
@ 2012-05-08 13:21   ` Joseph S. Myers
  2012-05-09  0:38     ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Joseph S. Myers @ 2012-05-08 13:21 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches

On Tue, 8 May 2012, Matthias Klose wrote:

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

This still seems to suffer in some cases the problem of previous versions 
that it does not ensure triplets are never used for non-matching ABIs.  
For example, a compiler for powerpc-linux-gnu can be configured 
--with-float=soft but this patch will still use powerpc-linux-gnu as the 
multiarch triplet.

For MIPS, I see you allowed for soft-float in setting the triplets - but 
the specification you point to doesn't mention the soft-float triplets.  
Likewise you allowed for powerpc-linux-gnuspe being e500v1 or e500v2 but 
haven't documented the e500v1 triplet.  Likewise for big-endian ARM.

I again suggest starting with a patch that does just one architecture - 
but makes sure to cover all the ABIs applicable to that architecture.  
For example, you could start with a patch for x86 (indeed, just x86 
GNU/Linux) - and assign a multiarch triplet for x32 even if you're not 
building an x32 distribution with multiarch.  Then, once the generic 
support has been reviewed by build system maintainers, and the x86 support 
by x86 maintainers and people familiar with all the applicable x86 ABIs, 
send patches for each other architecture (or architecture/OS combination), 
and the relevant architecture experts can review them to make sure the 
relevant ABIs are properly distinguished.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-08 13:21   ` Joseph S. Myers
@ 2012-05-09  0:38     ` Matthias Klose
  2012-05-09 13:37       ` Paolo Bonzini
  2012-05-19 16:05       ` Thomas Schwinge
  0 siblings, 2 replies; 47+ messages in thread
From: Matthias Klose @ 2012-05-09  0:38 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2085 bytes --]

On 08.05.2012 15:20, Joseph S. Myers wrote:
> On Tue, 8 May 2012, Matthias Klose wrote:
> 
>> 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].
> 
> This still seems to suffer in some cases the problem of previous versions 
> that it does not ensure triplets are never used for non-matching ABIs.  
> For example, a compiler for powerpc-linux-gnu can be configured 
> --with-float=soft but this patch will still use powerpc-linux-gnu as the 
> multiarch triplet.
> 
> For MIPS, I see you allowed for soft-float in setting the triplets - but 
> the specification you point to doesn't mention the soft-float triplets.  
> Likewise you allowed for powerpc-linux-gnuspe being e500v1 or e500v2 but 
> haven't documented the e500v1 triplet.  Likewise for big-endian ARM.
> 
> I again suggest starting with a patch that does just one architecture - 
> but makes sure to cover all the ABIs applicable to that architecture.  
> For example, you could start with a patch for x86 (indeed, just x86 
> GNU/Linux) - and assign a multiarch triplet for x32 even if you're not 
> building an x32 distribution with multiarch.  Then, once the generic 
> support has been reviewed by build system maintainers, and the x86 support 
> by x86 maintainers and people familiar with all the applicable x86 ABIs, 
> send patches for each other architecture (or architecture/OS combination), 
> and the relevant architecture experts can review them to make sure the 
> relevant ABIs are properly distinguished.

ok, the attached patch includes just the support for the x86 targets, including
the kfreebsd and the hurd systems. The x32 multiarch tuple isn't yet defined, so
I'd like to keep it out of the first version.

  Matthias

[-- Attachment #2: multiarch-x86.diff --]
[-- Type: text/plain, Size: 19606 bytes --]

gcc/

2012-05-08  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-gnu: Likewise:
	* config/i386/t-linux: Likewise.

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)
@@ -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/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/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;
 \f
 /* 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[];

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09  0:38     ` Matthias Klose
@ 2012-05-09 13:37       ` Paolo Bonzini
  2012-05-09 15:34         ` Matthias Klose
  2012-05-19 16:05       ` Thomas Schwinge
  1 sibling, 1 reply; 47+ messages in thread
From: Paolo Bonzini @ 2012-05-09 13:37 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Joseph S. Myers, GCC Patches

Il 09/05/2012 02:38, Matthias Klose ha scritto:
> 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}.

So -print-multiarch is like --print-multi-os-directory?  What is the
difference, and where is it docuemnted?  Should it fail if multiarch
support is not compiled in?

Paolo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09 13:37       ` Paolo Bonzini
@ 2012-05-09 15:34         ` Matthias Klose
  2012-05-09 16:29           ` Paolo Bonzini
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-05-09 15:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, GCC Patches

On 09.05.2012 15:37, Paolo Bonzini wrote:
> Il 09/05/2012 02:38, Matthias Klose ha scritto:
>> 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}.
> 
> So -print-multiarch is like --print-multi-os-directory?

the former prints the part before the `:' in the MULTILIB_OSDIRNAMES, the latter
the part after the `':', e.g. ../lib32 and i386-linux-gnu.

> What is the difference, and where is it documented?

Not sure how it should be further documented.

> Should it fail if multiarch support is not compiled in?

All the -print options always succeed. I would prefer if it just prints the
empty string if it is not configured (as it does now).

  Matthias

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09 15:34         ` Matthias Klose
@ 2012-05-09 16:29           ` Paolo Bonzini
  2012-05-09 17:19             ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Paolo Bonzini @ 2012-05-09 16:29 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Joseph S. Myers, GCC Patches

Il 09/05/2012 17:34, Matthias Klose ha scritto:
>> > So -print-multiarch is like --print-multi-os-directory?
> the former prints the part before the `:' in the MULTILIB_OSDIRNAMES, the latter
> the part after the `':', e.g. ../lib32 and i386-linux-gnu.

Yes, of course.

>> > What is the difference, and where is it documented?
> Not sure how it should be further documented.

No idea, it is a new concept and people need to understand how it
relates to multilibbing for example, what shortcomings are addressed etc.

I went through the Debian pages (only cursorily, I admit) and I found
nothing of this.

Another question I have is related to usage of the option.  Are you
supposed to look for libraries in the multilib directories too if the
compiler is multiarch-enabled?  Or only in /lib/i386-linux-gnu?  Which
one takes priority, multiarch or multiosdir?

From the patch I can guess the intended search path is
/lib/MULTIARCH:/lib/MULTIOSDIR, but I'm not entirely sure about that and
it needs documentation.

>> > Should it fail if multiarch support is not compiled in?
> All the -print options always succeed. I would prefer if it just prints the
> empty string if it is not configured (as it does now).

Will the empty string be a valid output for a multiarch-enabled
compiler?  For example "gcc --print-multi-os-directory" and "gcc
--print-multi-directory" on a bi-arch x86-64 compiler will never print
the empty string.  Again, I guess the answer is no but I'm not sure.

If the answer is no, returning the empty string is fine.

If the answer is yes, and assuming the search path is
/lib/MULTIARCH:/lib/MULTIOSDIR, then programs need to know whether they
need to omit the /lib/MULTIARCH component of the search path.  A failure
status code is then required.

Paolo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09 16:29           ` Paolo Bonzini
@ 2012-05-09 17:19             ` Matthias Klose
  2012-05-10  6:42               ` Paolo Bonzini
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-05-09 17:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, GCC Patches

On 09.05.2012 18:29, Paolo Bonzini wrote:
> Il 09/05/2012 17:34, Matthias Klose ha scritto:
>>>> So -print-multiarch is like --print-multi-os-directory?
>> the former prints the part before the `:' in the MULTILIB_OSDIRNAMES, the latter
>> the part after the `':', e.g. ../lib32 and i386-linux-gnu.
> 
> Yes, of course.
> 
>>>> What is the difference, and where is it documented?
>> Not sure how it should be further documented.
> 
> No idea, it is a new concept and people need to understand how it
> relates to multilibbing for example, what shortcomings are addressed etc.
> 
> I went through the Debian pages (only cursorily, I admit) and I found
> nothing of this.

these are referenced from the http://wiki.debian.org/Multiarch/Tuples
https://wiki.ubuntu.com/MultiarchSpec#Filesystem_layout
http://err.no/debian/amd64-multiarch-3

http://wiki.debian.org/Multiarch/TheCaseForMultiarch describes use cases for
multiarch, and why Debian thinks that the existing approaches are not sufficient
(having name collisions for different architectures or ad hoc names for new
architectures like libx32).  That may be contentious within the Linux community,
but I would like to avoid this kind of discussion here.

> Another question I have is related to usage of the option.  Are you
> supposed to look for libraries in the multilib directories too if the
> compiler is multiarch-enabled?

Debian/Ubuntu always use /lib for the default MULTIOSDIR, and this needs to be
looked up in the future too. The use of locations like ../lib32 will be faded
out over time, but I don't see any harm not to have looked up as well.

> Or only in /lib/i386-linux-gnu?  Which
> one takes priority, multiarch or multiosdir?
> 
> From the patch I can guess the intended search path is
> /lib/MULTIARCH:/lib/MULTIOSDIR, but I'm not entirely sure about that and
> it needs documentation.

yes, this is the intended search path. I assume such kind of documentation
shouldn't go into invoke.texi.

>>>> Should it fail if multiarch support is not compiled in?
>> All the -print options always succeed. I would prefer if it just prints the
>> empty string if it is not configured (as it does now).
> 
> Will the empty string be a valid output for a multiarch-enabled
> compiler?  For example "gcc --print-multi-os-directory" and "gcc
> --print-multi-directory" on a bi-arch x86-64 compiler will never print
> the empty string.  Again, I guess the answer is no but I'm not sure.
> 
> If the answer is no, returning the empty string is fine.

The answer is no. If multiarch is enabled, then the string is always non-empty
and should return a multiarch tuple as defined in
http://wiki.debian.org/Multiarch/Tuples. Anything else should be considered an
error.

> If the answer is yes, and assuming the search path is
> /lib/MULTIARCH:/lib/MULTIOSDIR, then programs need to know whether they
> need to omit the /lib/MULTIARCH component of the search path.

Unrelated, but why would programs hard code this path and not use something like
this?

gcc -v -E - </dev/null 2>&1 | grep ^LIBRARY_PATH

  Matthias

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09 17:19             ` Matthias Klose
@ 2012-05-10  6:42               ` Paolo Bonzini
  2012-05-11  5:14                 ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Paolo Bonzini @ 2012-05-10  6:42 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Joseph S. Myers, GCC Patches

Il 09/05/2012 19:19, Matthias Klose ha scritto:
> these are referenced from the http://wiki.debian.org/Multiarch/Tuples
> https://wiki.ubuntu.com/MultiarchSpec#Filesystem_layout
> http://err.no/debian/amd64-multiarch-3
> 
> http://wiki.debian.org/Multiarch/TheCaseForMultiarch describes use cases for
> multiarch, and why Debian thinks that the existing approaches are not sufficient
> (having name collisions for different architectures or ad hoc names for new
> architectures like libx32).  That may be contentious within the Linux community,
> but I would like to avoid this kind of discussion here.

I don't care about contentiousness, I just would like this to be
documented somewhere (for example in the internals manual where
MULTILIB_* is documented too).

Paolo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-10  6:42               ` Paolo Bonzini
@ 2012-05-11  5:14                 ` Matthias Klose
  2012-05-11 10:51                   ` Paolo Bonzini
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-05-11  5:14 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1059 bytes --]

On 10.05.2012 08:42, Paolo Bonzini wrote:
> Il 09/05/2012 19:19, Matthias Klose ha scritto:
>> these are referenced from the http://wiki.debian.org/Multiarch/Tuples
>> https://wiki.ubuntu.com/MultiarchSpec#Filesystem_layout
>> http://err.no/debian/amd64-multiarch-3
>>
>> http://wiki.debian.org/Multiarch/TheCaseForMultiarch describes use cases for
>> multiarch, and why Debian thinks that the existing approaches are not sufficient
>> (having name collisions for different architectures or ad hoc names for new
>> architectures like libx32).  That may be contentious within the Linux community,
>> but I would like to avoid this kind of discussion here.
> 
> I don't care about contentiousness, I just would like this to be
> documented somewhere (for example in the internals manual where
> MULTILIB_* is documented too).

ok, I did clarify it in the existing documentation of MULTIARCH_DIRNAME in
fragments.texi, detailing the search order for the files. Should the search
order be mentioned in some user documentation as well? if yes, where?

  Matthias


[-- Attachment #2: fragments.diff --]
[-- Type: text/plain, Size: 2618 bytes --]

Index: doc/fragments.texi
===================================================================
--- doc/fragments.texi	(revision 187337)
+++ doc/fragments.texi	(working copy)
@@ -152,6 +152,52 @@
 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, crt files and system
+header files in additional locations.
+
+Libraries and crt files are searched first in
+@var{prefix}/@var{multiarch} before @var{prefix} for each @var{prefix}
+added by @code{add_prefix} or @code{add_sysrooted_prefix}.
+System header files are searched first in
+@code{LOCAL_INCLUDE_DIR}/@var{multiarch} before
+@code{LOCAL_INCLUDE_DIR}, and in
+@code{NATIVE_SYSTEM_HEADER_DIR}/@var{multiarch} before
+@code{NATIVE_SYSTEM_HEADER_DIR}.
+
+E.g. for a multiarch enabled system compiler
+@file{/lib/@var{multiarch}} is searched before @file{/lib} and
+@file{/usr/lib/@var{multiarch}} before @file{/usr/lib}, and system
+header files are searched in @file{/usr/local/include/@var{multiarch}}
+before @file{/usr/local/include} and in
+@file{/usr/include/@var{multiarch}} before @file{/usr/include}.
+
+@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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-11  5:14                 ` Matthias Klose
@ 2012-05-11 10:51                   ` Paolo Bonzini
  2012-05-11 18:33                     ` Matthias Klose
  2012-05-12 22:09                     ` Jonathan Nieder
  0 siblings, 2 replies; 47+ messages in thread
From: Paolo Bonzini @ 2012-05-11 10:51 UTC (permalink / raw)
  To: Matthias Klose; +Cc: Joseph S. Myers, GCC Patches

Il 11/05/2012 07:13, Matthias Klose ha scritto:
> ok, I did clarify it in the existing documentation of MULTIARCH_DIRNAME in
> fragments.texi, detailing the search order for the files. Should the search
> order be mentioned in some user documentation as well? if yes, where?

Thanks!  I don't think the search order should be mentioned specially,
since anyway *_INCLUDE_PATH and LIBRARY_PATH are mentioned.  However
under MULTILIB_DIRNAMES I would add something like this:

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

> +@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 OS conventions, rather than GCC conventions.

s/OS/operating system/

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

> Use the mapping when there is
> +no one-to-one equivalence between GCC levels and the OS.

I'm not sure what you mean here?


> +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}).

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
> +If @code{MULTIARCH_DIRNAME} is used, this variable specifies the
> +multiarch name for this configuration.
>
> +Libraries and crt files are searched first in
> +@var{prefix}/@var{multiarch} before @var{prefix} for each @var{prefix}
> +added by @code{add_prefix} or @code{add_sysrooted_prefix}.
> +System header files are searched first in
> +@code{LOCAL_INCLUDE_DIR}/@var{multiarch} before
> +@code{LOCAL_INCLUDE_DIR}, and in
> +@code{NATIVE_SYSTEM_HEADER_DIR}/@var{multiarch} before
> +@code{NATIVE_SYSTEM_HEADER_DIR}.
>
> +@code{MULTIARCH_DIRNAME} is not used for multilib enabled
> +configurations, but encoded in @code{MULTILIB_OSDIRNAMES} instead.

This sounds simpler, and doesn't refer to GCC implementation details
such add_prefix/add_sysrooted_prefix:

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.

> +The multiarch tuples are defined
> +in @uref{http://wiki.debian.org/Multiarch/Tuples}.

Is this needed?  Aren't they defined simply by the GCC source code?
Surely if some other OS implements multiarch with different tuples (no
matter how undesirable that would be) Debian would not be an
authoritative source.

Paolo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-11 10:51                   ` Paolo Bonzini
@ 2012-05-11 18:33                     ` Matthias Klose
  2012-05-12 22:09                     ` Jonathan Nieder
  1 sibling, 0 replies; 47+ messages in thread
From: Matthias Klose @ 2012-05-11 18:33 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 5712 bytes --]

On 11.05.2012 12:51, Paolo Bonzini wrote:
> Il 11/05/2012 07:13, Matthias Klose ha scritto:
>> ok, I did clarify it in the existing documentation of MULTIARCH_DIRNAME in
>> fragments.texi, detailing the search order for the files. Should the search
>> order be mentioned in some user documentation as well? if yes, where?
> 
> Thanks!  I don't think the search order should be mentioned specially,
> since anyway *_INCLUDE_PATH and LIBRARY_PATH are mentioned.  However
> under MULTILIB_DIRNAMES I would add something like this:
> 
> @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.

done.

>> +@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 OS conventions, rather than GCC conventions.
> 
> s/OS/operating system/

done.

>> 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.
> 
>> Use the mapping when there is
>> +no one-to-one equivalence between GCC levels and the OS.
> 
> I'm not sure what you mean here?

The whole paragraph was taken from the genmultilib script. I left it out for
this version. I think I'll update the genmultilib script when these docs are
settled.

>> +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}).
> 
> 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}.

done.

>> +@findex MULTIARCH_DIRNAME
>> +@item MULTIARCH_DIRNAME
>> +If @code{MULTIARCH_DIRNAME} is used, this variable specifies the
>> +multiarch name for this configuration.
>>
>> +Libraries and crt files are searched first in
>> +@var{prefix}/@var{multiarch} before @var{prefix} for each @var{prefix}
>> +added by @code{add_prefix} or @code{add_sysrooted_prefix}.
>> +System header files are searched first in
>> +@code{LOCAL_INCLUDE_DIR}/@var{multiarch} before
>> +@code{LOCAL_INCLUDE_DIR}, and in
>> +@code{NATIVE_SYSTEM_HEADER_DIR}/@var{multiarch} before
>> +@code{NATIVE_SYSTEM_HEADER_DIR}.
>>
>> +@code{MULTIARCH_DIRNAME} is not used for multilib enabled
>> +configurations, but encoded in @code{MULTILIB_OSDIRNAMES} instead.
> 
> This sounds simpler, and doesn't refer to GCC implementation details
> such add_prefix/add_sysrooted_prefix:
> 
> 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.

done. thanks for the wording.

>> +The multiarch tuples are defined
>> +in @uref{http://wiki.debian.org/Multiarch/Tuples}.
> 
> Is this needed?  Aren't they defined simply by the GCC source code?
> Surely if some other OS implements multiarch with different tuples (no
> matter how undesirable that would be) Debian would not be an
> authoritative source.

well, Joseph did ask for some kind of authoritative definition before this patch
could get in. If talking about the "definition" is too strong, then maybe
something along the lines "For more information about multiarch, please see
http://wiki.debian.org/Multiarch/Tuples" would be better?

  Matthias

PS: I'll be on vacation mode for the next two weeks, so might not reply immediately.

[-- Attachment #2: fragments.diff --]
[-- Type: text/plain, Size: 3877 bytes --]

Index: gcc/doc/fragments.texi
===================================================================
--- gcc/doc/fragments.texi	(revision 187337)
+++ gcc/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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-11 10:51                   ` Paolo Bonzini
  2012-05-11 18:33                     ` Matthias Klose
@ 2012-05-12 22:09                     ` Jonathan Nieder
  1 sibling, 0 replies; 47+ messages in thread
From: Jonathan Nieder @ 2012-05-12 22:09 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Matthias Klose, Joseph S. Myers, GCC Patches

Paolo Bonzini wrote:
> Il 11/05/2012 07:13, Matthias Klose ha scritto:

>> +The multiarch tuples are defined
>> +in @uref{http://wiki.debian.org/Multiarch/Tuples}.
>
> Is this needed?  Aren't they defined simply by the GCC source code?
> Surely if some other OS implements multiarch with different tuples (no
> matter how undesirable that would be) Debian would not be an
> authoritative source.

Is there some vendor-neutral wiki or other place that would be easy
to update that could be used to define tuples?  I think the table is
currently in that wiki page since that was just the easiest place to
put it.  As soon as there is some place more authoritative the table
could be replaced with a link.

If some other OS implements multiarch with different tuples, that's
no big deal.  An OS implementing multiarch using the same tuples with
incompatible meaning would be more unpleasant.

Jonathan

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-09  0:38     ` Matthias Klose
  2012-05-09 13:37       ` Paolo Bonzini
@ 2012-05-19 16:05       ` Thomas Schwinge
  2012-06-06 14:28         ` Thomas Schwinge
  1 sibling, 1 reply; 47+ messages in thread
From: Thomas Schwinge @ 2012-05-19 16:05 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 3103 bytes --]

Hi!

On Wed, 09 May 2012 02:38:11 +0200, Matthias Klose <doko@ubuntu.com> wrote:
> ok, the attached patch includes just the support for the x86 targets, including
> the kfreebsd and the hurd systems. The x32 multiarch tuple isn't yet defined, so
> I'd like to keep it out of the first version.

I will test this on/for GNU/Hurd next week (hopefully), but here are
already two comments.

> 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

The auto-detection won't work for cases where native_system_header_dir
(as per config.gcc; or command-line argument) is not /usr/include.

> Index: gcc/config.gcc
> ===================================================================
> --- gcc/config.gcc	(revision 187271)
> +++ gcc/config.gcc	(working copy)
> @@ -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"
> +		;;

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

As of 2011-11-02 (a997b0d8a7b720578f40c0f9f7767bac02022e0b, r180767)
there was no i386/t-linux anymore, and you're now re-introducing it, so
you'll need to re-add it for the *-linux* cases cited above, but also
remove it from the other *-gnu* cases.


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-05-19 16:05       ` Thomas Schwinge
@ 2012-06-06 14:28         ` Thomas Schwinge
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Schwinge @ 2012-06-06 14:28 UTC (permalink / raw)
  To: Matthias Klose; +Cc: GCC Patches, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 4690 bytes --]

Hi!

On Sat, 19 May 2012 18:05:30 +0200, I wrote:
> On Wed, 09 May 2012 02:38:11 +0200, Matthias Klose <doko@ubuntu.com> wrote:
> > ok, the attached patch includes just the support for the x86 targets, including
> > the kfreebsd and the hurd systems. The x32 multiarch tuple isn't yet defined, so
> > I'd like to keep it out of the first version.
> 
> I will test this on/for GNU/Hurd next week (hopefully)

I have now completed this testing: the patch does work correctly when
natively building i686-linux-gnu on Debian GNU/Linux as well as i686-gnu
on Debian GNU/Hurd, and also when building a i686-linux-gnu to i686-gnu
cross-compiler which is not using the Debian multiarch arrangement.

> but here are
> already two comments.
> 
> > 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
> 
> The auto-detection won't work for cases where native_system_header_dir
> (as per config.gcc; or command-line argument) is not /usr/include.

This does not really bother me, as my GNU/Hurd configurations also use
/usr/include as opposed to /include, and the auto-detection will work for
that case.

> > Index: gcc/config.gcc
> > ===================================================================
> > --- gcc/config.gcc	(revision 187271)
> > +++ gcc/config.gcc	(working copy)
> > @@ -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"
> > +		;;
> 
> > 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-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))
> 
> As of 2011-11-02 (a997b0d8a7b720578f40c0f9f7767bac02022e0b, r180767)
> there was no i386/t-linux anymore, and you're now re-introducing it, so
> you'll need to re-add it for the *-linux* cases cited above, but also
> remove it from the other *-gnu* cases.

gcc/
	* 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.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7ec184c..39c70f2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3481,9 +3481,14 @@ case ${target} in
 
 	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]*)
 		;;


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
                   ` (3 preceding siblings ...)
  2012-05-08  1:04 ` Matthias Klose
@ 2012-06-25 13:23 ` Matthias Klose
  2012-06-25 14:00   ` Joseph S. Myers
  2012-07-08 18:50 ` [patch v2] " Matthias Klose
  5 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-06-25 13:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Paolo Bonzini, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 315 bytes --]

Please find attached the patch updated for trunk 20120625, 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.

Ok for the trunk?

  Matthias

[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 22663 bytes --]

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.

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;
 \f
 /* 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)
@@ -792,6 +792,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*)
@@ -1004,6 +1005,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
 	;;
@@ -1011,6 +1013,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*)
@@ -1495,7 +1498,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*)
@@ -1981,6 +1984,7 @@
 		;;
 	    *)
 		tm_file="${tm_file} rs6000/linux.h glibc-stdint.h"
+		tmake_file="$tmake_file rs6000/t-linux"
 		;;
 	esac
 	case ${target} in
@@ -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);
 	}

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-06-25 13:23 ` Matthias Klose
@ 2012-06-25 14:00   ` Joseph S. Myers
  2012-06-25 16:26     ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Joseph S. Myers @ 2012-06-25 14:00 UTC (permalink / raw)
  To: Matthias Klose; +Cc: gcc-patches, Paolo Bonzini

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.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-06-25 14:00   ` Joseph S. Myers
@ 2012-06-25 16:26     ` Matthias Klose
  2012-06-28 10:31       ` Thomas Schwinge
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-06-25 16:26 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches, Paolo Bonzini

[-- Attachment #1: Type: text/plain, Size: 485 bytes --]

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.


[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 21338 bytes --]

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.

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;
 \f
 /* 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);
 	}

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-06-25 16:26     ` Matthias Klose
@ 2012-06-28 10:31       ` Thomas Schwinge
  2012-06-28 11:30         ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Thomas Schwinge @ 2012-06-28 10:31 UTC (permalink / raw)
  To: Matthias Klose; +Cc: gcc-patches, Paolo Bonzini, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 2648 bytes --]

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

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-06-28 10:31       ` Thomas Schwinge
@ 2012-06-28 11:30         ` Matthias Klose
  2012-06-28 11:41           ` Thomas Schwinge
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-06-28 11:30 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: gcc-patches, Paolo Bonzini, Joseph S. Myers

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.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] support for multiarch systems
  2012-06-28 11:30         ` Matthias Klose
@ 2012-06-28 11:41           ` Thomas Schwinge
  0 siblings, 0 replies; 47+ messages in thread
From: Thomas Schwinge @ 2012-06-28 11:41 UTC (permalink / raw)
  To: Matthias Klose; +Cc: gcc-patches, Paolo Bonzini, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 3680 bytes --]

Hi!

On Thu, 28 Jun 2012 12:42:23 +0200, Matthias Klose <doko@ubuntu.com> wrote:
> On 28.06.2012 12:01, Thomas Schwinge wrote:
> > 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.
> 
> ?

I'd use:

	* config/i386/t-gnu: New file.
	* config/i386/t-kfreebsd: Likewise.
	* config/i386/t-linux: Likewise.

Plus the following instead of your changes:

gcc/
	* 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.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7ec184c..39c70f2 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3481,9 +3481,14 @@ case ${target} in
 
 	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]*)
 		;;

Otherwise, I can't imagine how that would work.


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch v2] support for multiarch systems
  2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
                   ` (4 preceding siblings ...)
  2012-06-25 13:23 ` Matthias Klose
@ 2012-07-08 18:50 ` Matthias Klose
  2012-07-18 19:00   ` Thomas Schwinge
                     ` (2 more replies)
  5 siblings, 3 replies; 47+ messages in thread
From: Matthias Klose @ 2012-07-08 18:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

[-- Attachment #1: Type: text/plain, Size: 382 bytes --]

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

[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 21412 bytes --]

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.


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;
 \f
 /* 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);
 	}

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch v2] support for multiarch systems
  2012-07-08 18:50 ` [patch v2] " Matthias Klose
@ 2012-07-18 19:00   ` Thomas Schwinge
  2012-07-19  1:12   ` John David Anglin
  2012-08-07 10:33   ` [ping] " Matthias Klose
  2 siblings, 0 replies; 47+ messages in thread
From: Thomas Schwinge @ 2012-07-18 19:00 UTC (permalink / raw)
  To: Matthias Klose, gcc-patches; +Cc: Joseph S. Myers, Paolo Bonzini, Diego Novillo

[-- Attachment #1: Type: text/plain, Size: 2611 bytes --]

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

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch v2] support for multiarch systems
  2012-07-08 18:50 ` [patch v2] " Matthias Klose
  2012-07-18 19:00   ` Thomas Schwinge
@ 2012-07-19  1:12   ` John David Anglin
  2012-07-19  3:19     ` David Miller
  2012-07-19 15:14     ` Joseph S. Myers
  2012-08-07 10:33   ` [ping] " Matthias Klose
  2 siblings, 2 replies; 47+ messages in thread
From: John David Anglin @ 2012-07-19  1:12 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

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
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch v2] support for multiarch systems
  2012-07-19  1:12   ` John David Anglin
@ 2012-07-19  3:19     ` David Miller
  2012-07-19 15:14     ` Joseph S. Myers
  1 sibling, 0 replies; 47+ messages in thread
From: David Miller @ 2012-07-19  3:19 UTC (permalink / raw)
  To: dave.anglin, dave; +Cc: doko, gcc-patches, joseph, bonzini, thomas

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.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch v2] support for multiarch systems
  2012-07-19  1:12   ` John David Anglin
  2012-07-19  3:19     ` David Miller
@ 2012-07-19 15:14     ` Joseph S. Myers
  1 sibling, 0 replies; 47+ messages in thread
From: Joseph S. Myers @ 2012-07-19 15:14 UTC (permalink / raw)
  To: John David Anglin
  Cc: Matthias Klose, gcc-patches, Paolo Bonzini, Thomas Schwinge

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.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [ping] Re: [patch v2] support for multiarch systems
  2012-07-08 18:50 ` [patch v2] " Matthias Klose
  2012-07-18 19:00   ` Thomas Schwinge
  2012-07-19  1:12   ` John David Anglin
@ 2012-08-07 10:33   ` Matthias Klose
  2012-08-07 14:07     ` Ian Lance Taylor
  2012-11-15 11:44     ` Eric Botcazou
  2 siblings, 2 replies; 47+ messages in thread
From: Matthias Klose @ 2012-08-07 10:33 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]

ping?

re-attaching the updated patch with the fixed comment in genmultilib.

  Matthias

On 08.07.2012 20:48, 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.
> 
> 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
> 


[-- Attachment #2: multiarch.diff --]
[-- Type: text/plain, Size: 21412 bytes --]

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.


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 ninth 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;
 \f
 /* 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);
 	}

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-08-07 10:33   ` [ping] " Matthias Klose
@ 2012-08-07 14:07     ` Ian Lance Taylor
  2012-11-02 13:26       ` Matthias Klose
  2012-11-15 11:44     ` Eric Botcazou
  1 sibling, 1 reply; 47+ messages in thread
From: Ian Lance Taylor @ 2012-08-07 14:07 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

On Tue, Aug 7, 2012 at 3:31 AM, Matthias Klose <doko@ubuntu.com> wrote:
> ping?
>
> On 08.07.2012 20:48, 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.

> +[case "${withval}" in
> +yes|no|auto-detect) enable_multiarch=$withval;;
> +*) AC_MSG_ERROR(bad value ${withval} given for --enable-multiarch option) ;;

Please just use "auto", not "auto-detect", as in libgcc/configure.ac.

> +# needed for setting the multiarch name on ARM
> +AC_SUBST(with_float)

This seems like it should be in a different patch.

> +with_float = @with_float@

Likewise.

+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

This is nicely tricky but I don't understand why you are doing this in
such a confusing way.  Why not simply set the names in config.gcc?
What information do you have at make time that you don't have at
configure time?

The auto case is not general.  When cross-compiling without --sysroot,
or when using --native-system-header-dir, the test won't work.
Without --sysroot there may not be much that you can do to auto-detect
multiarch.  And with --sysroot, there should be no need to use
SYSTEM_HEADER_DIR at all; just look in the sysroot.

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

This is quite obscure for anybody who does not already know what multiarch is.

I'm sorry, I have to repeat my extreme annoyance that this scheme
breaks all earlier GCC releases.

Ian

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-08-07 14:07     ` Ian Lance Taylor
@ 2012-11-02 13:26       ` Matthias Klose
  2012-11-02 17:37         ` Ian Lance Taylor
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-11-02 13:26 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

[-- Attachment #1: Type: text/plain, Size: 2973 bytes --]

On 07.08.2012 16:07, Ian Lance Taylor wrote:
> On Tue, Aug 7, 2012 at 3:31 AM, Matthias Klose <doko@ubuntu.com> wrote:
>> ping?
>>
>> On 08.07.2012 20:48, 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.
>
>> +[case "${withval}" in
>> +yes|no|auto-detect) enable_multiarch=$withval;;
>> +*) AC_MSG_ERROR(bad value ${withval} given for --enable-multiarch option) ;;
>
> Please just use "auto", not "auto-detect", as in libgcc/configure.ac.

ok.

>> +# needed for setting the multiarch name on ARM
>> +AC_SUBST(with_float)
>
> This seems like it should be in a different patch.
>
>> +with_float = @with_float@
>
> Likewise.

I was asked to split the ix86 and infrastructure bits from the bits for all
other architectures. I think it does belong here. The with_float macro is then
used for e.g. ARM to distinguish between hard and soft float triplets.

> +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
>
> This is nicely tricky but I don't understand why you are doing this in
> such a confusing way.  Why not simply set the names in config.gcc?
> What information do you have at make time that you don't have at
> configure time?

this is for the auto case. SYSTEM_HEADER_DIR is not accessible/available from
config.gcc. This is the same approach as taken for MULTILIB_OSDDIRNAMES. Also 
setting the names for the multiarch directories in the same place as done for 
for the MULTILIB_OSDIRNAMES seems to be better choice.

> The auto case is not general.  When cross-compiling without --sysroot,
> or when using --native-system-header-dir, the test won't work.
> Without --sysroot there may not be much that you can do to auto-detect
> multiarch.  And with --sysroot, there should be no need to use
> SYSTEM_HEADER_DIR at all; just look in the sysroot.
>
>> +@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.
>
> This is quite obscure for anybody who does not already know what multiarch is.

I did add the pointer to multiarch, which already is in fragments.texi:

   More documentation about multiarch can be found at
   @uref{http://wiki.debian.org/Multiarch}.

The feedback about what and where information about multiarch should be added, 
changes from reviewer to reviewer.

Attaching the updated patch.

> I'm sorry, I have to repeat my extreme annoyance that this scheme
> breaks all earlier GCC releases.

yes, this is mentioned at http://bugs.debian.org/637232 too. I proposed a patch 
to add a libc6-dev-compat binary package which can be installed together with 
the existing libc6-dev packages.

   Matthias

[-- Attachment #2: multiarch.diff --]
[-- Type: text/x-diff, Size: 22359 bytes --]

2012-11-02  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: 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.


Index: gcc/config/i386/t-linux64
===================================================================
--- gcc/config/i386/t-linux64	(revision 193062)
+++ 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+= mx32=../libx32
+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$(call if_multiarch,:x32-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-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-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/incpath.c
===================================================================
--- gcc/incpath.c	(revision 193062)
+++ 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/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 193062)
+++ gcc/Makefile.in	(working copy)
@@ -336,6 +336,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)
+  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
 
@@ -1809,10 +1820,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: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 193062)
+++ gcc/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;
 \f
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) in a compiler or link
@@ -2084,6 +2089,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;
@@ -2101,11 +2107,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;
@@ -2114,16 +2123,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);
 	}
 
@@ -2152,6 +2160,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))
@@ -2980,6 +2998,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\
@@ -3264,6 +3285,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:
@@ -4920,6 +4942,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);
@@ -6589,6 +6620,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)
@@ -7572,10 +7612,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;
 	    }
 	}
@@ -7637,7 +7693,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/common.opt
===================================================================
--- gcc/common.opt	(revision 193062)
+++ gcc/common.opt	(working copy)
@@ -348,6 +348,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=)
 
@@ -2353,6 +2356,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
 
@@ -2409,6 +2416,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/config.gcc
===================================================================
--- gcc/config.gcc	(revision 193062)
+++ gcc/config.gcc	(working copy)
@@ -3640,10 +3640,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: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 193062)
+++ gcc/configure.ac	(working copy)
@@ -778,6 +778,31 @@
 AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
 AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
 
+# 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) enable_multiarch=$withval;;
+*) AC_MSG_ERROR(bad value ${withval} given for --enable-multiarch option) ;;
+esac], [enable_multiarch=auto])
+if test x${enable_multiarch} = xauto; then
+  if test x${with_native_system_header_dir} != x; then
+    AC_MSG_WARN([disabling multiarch auto detection (configured with --native-system-header-dir)])
+    enable_multiarch=no
+  fi
+  if test x$host != x$target && test "x$with_sysroot" = x; then
+    AC_MSG_WARN([disabling multiarch auto detection (cross build configured without --with-sysroot)])
+    enable_multiarch=no
+  fi
+fi
+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)
+
 AC_ARG_WITH(specs,
   [AS_HELP_STRING([--with-specs=SPECS],
                   [add SPECS to driver command-line processing])],
Index: gcc/cppdefault.c
===================================================================
--- gcc/cppdefault.c	(revision 193062)
+++ 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 193062)
+++ 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[];
Index: gcc/doc/install.texi
===================================================================
--- gcc/doc/install.texi	(revision 193062)
+++ gcc/doc/install.texi	(working copy)
@@ -1033,6 +1033,15 @@
 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.  The auto detection is enabled for native builds,
+and for cross builds configured with @option{--with-sysroot}, and without
+@option{--with-native-system-header-dir}.
+More documentation about multiarch can be found at
+@uref{http://wiki.debian.org/Multiarch}.
+
 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 193062)
+++ gcc/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: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 193062)
+++ gcc/doc/invoke.texi	(working copy)
@@ -6309,6 +6309,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/genmultilib
===================================================================
--- gcc/genmultilib	(revision 193062)
+++ gcc/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 ninth 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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-02 13:26       ` Matthias Klose
@ 2012-11-02 17:37         ` Ian Lance Taylor
  2012-11-04 15:45           ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Ian Lance Taylor @ 2012-11-02 17:37 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

On Fri, Nov 2, 2012 at 6:26 AM, Matthias Klose <doko@ubuntu.com> wrote:
>
>> +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
>>
>> This is nicely tricky but I don't understand why you are doing this in
>> such a confusing way.  Why not simply set the names in config.gcc?
>> What information do you have at make time that you don't have at
>> configure time?
>
>
> this is for the auto case. SYSTEM_HEADER_DIR is not accessible/available
> from
> config.gcc. This is the same approach as taken for MULTILIB_OSDDIRNAMES.
> Also setting the names for the multiarch directories in the same place as
> done for for the MULTILIB_OSDIRNAMES seems to be better choice.

SYSTEM_HEADER_DIR is available in gcc/configure.ac, and you could do
the $(if $(wildcard $(shell echo
>> $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o) there.  I can't see any reason to do it at make time rather than configure time.

> +	      if (*q2 == ':')
> +		end = q2;

Don't reuse end here.  Use a new variable.

Please update the comment for set_multilib_dir.  It's not a very good
comment, but it does describe the syntax, and you seem to be changing
the syntax.

> -      if (this_path[0] == '.' && this_path[1] == ':')
> +      if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')

The existing comment here is reasonably clear.  Please update the
comment to show why this change is correct.

> +Specify wether to enable or disable multiarch support.  The default is

s/wether/whether/

> +to detect for glibc start files in a multiarch location, and enable it

s/detect/check/ or something along those lines.

Ian

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-02 17:37         ` Ian Lance Taylor
@ 2012-11-04 15:45           ` Matthias Klose
  2012-11-14 20:44             ` Ian Lance Taylor
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-11-04 15:45 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

[-- Attachment #1: Type: text/plain, Size: 2905 bytes --]

Am 02.11.2012 18:37, schrieb Ian Lance Taylor:
> On Fri, Nov 2, 2012 at 6:26 AM, Matthias Klose <doko@ubuntu.com> wrote:
>>
>>> +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
>>>
>>> This is nicely tricky but I don't understand why you are doing this in
>>> such a confusing way.  Why not simply set the names in config.gcc?
>>> What information do you have at make time that you don't have at
>>> configure time?
>>
>>
>> this is for the auto case. SYSTEM_HEADER_DIR is not accessible/available
>> from
>> config.gcc. This is the same approach as taken for MULTILIB_OSDDIRNAMES.
>> Also setting the names for the multiarch directories in the same place as
>> done for for the MULTILIB_OSDIRNAMES seems to be better choice.
>
> SYSTEM_HEADER_DIR is available in gcc/configure.ac, and you could do
> the $(if $(wildcard $(shell echo
>>> $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o) there.  I can't see any reason to do it at make time rather than configure time.

in the thread starting at 
http://gcc.gnu.org/ml/gcc-patches/2007-09/msg00696.html it was suggested to use 
this construct.

SYSTEM_HEADER_DIR is in Makefile syntax, and cannot be evaluated in 
configure.ac.  Now you could add a SYSTEM_HEADER_DIR_sh variable to track the 
same configuration in shell syntax, but this seems to be error prone to 
maintain. Plus the Makefile has the comment for this macro saying "to be 
overridden by targets".

For now, I added a comment in the Makefile.in, why SYSTEM_HEADER_DIR cannot be 
used in configure.ac.

>> +	      if (*q2 == ':')
>> +		end = q2;
>
> Don't reuse end here.  Use a new variable.

done.

> Please update the comment for set_multilib_dir.  It's not a very good
> comment, but it does describe the syntax, and you seem to be changing
> the syntax.

added:
   A subdirectory name is optionally followed by a colon and the corresponding
   multiarch name.

>> -      if (this_path[0] == '.' && this_path[1] == ':')
>> +      if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
>
> The existing comment here is reasonably clear.  Please update the
> comment to show why this change is correct.

updated comment:
       /* When --disable-multilib was used but target defines
          MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
          with .:: for multiarch configurations) are there just to find
          multilib_os_dir, so skip them from output.  */

>> +Specify wether to enable or disable multiarch support.  The default is
>
> s/wether/whether/
>
>> +to detect for glibc start files in a multiarch location, and enable it
>
> s/detect/check/ or something along those lines.

done.

now testing the attached patch.

   Matthias


[-- Attachment #2: multiarch.diff --]
[-- Type: text/x-diff, Size: 23018 bytes --]

2012-11-04  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: 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.
	* cppdefault.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.


Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 193133)
+++ doc/invoke.texi	(working copy)
@@ -6309,6 +6309,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: doc/install.texi
===================================================================
--- doc/install.texi	(revision 193133)
+++ doc/install.texi	(working copy)
@@ -1033,6 +1033,15 @@
 conventions, etc.@: should not be built.  The default is to build a
 predefined set of them.
 
+@item --enable-multiarch
+Specify whether to enable or disable multiarch support.  The default is
+to check for glibc start files in a multiarch location, and enable it
+if the files are found.  The auto detection is enabled for native builds,
+and for cross builds configured with @option{--with-sysroot}, and without
+@option{--with-native-system-header-dir}.
+More documentation about multiarch can be found at
+@uref{http://wiki.debian.org/Multiarch}.
+
 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 193133)
+++ 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: common.opt
===================================================================
--- common.opt	(revision 193133)
+++ common.opt	(working copy)
@@ -348,6 +348,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=)
 
@@ -2353,6 +2356,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
 
@@ -2409,6 +2416,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: config.gcc
===================================================================
--- config.gcc	(revision 193133)
+++ config.gcc	(working copy)
@@ -3640,10 +3640,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: configure.ac
===================================================================
--- configure.ac	(revision 193133)
+++ configure.ac	(working copy)
@@ -613,6 +613,31 @@
 [], [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) enable_multiarch=$withval;;
+*) AC_MSG_ERROR(bad value ${withval} given for --enable-multiarch option) ;;
+esac], [enable_multiarch=auto])
+if test x${enable_multiarch} = xauto; then
+  if test x${with_native_system_header_dir} != x; then
+    ma_msg_suffix=", disabled auto check (configured with --native-system-header-dir)"
+    enable_multiarch=no
+  fi
+  if test x$host != x$target && test "x$with_sysroot" = x; then
+    ma_msg_suffix=", disabled auto check (cross build configured without --with-sysroot)"
+    enable_multiarch=no
+  fi
+fi
+AC_MSG_CHECKING(for multiarch configuration)
+AC_SUBST(enable_multiarch)
+AC_MSG_RESULT($enable_multiarch$ma_msg_suffix)
+
+# needed for setting the multiarch name for soft-float/hard-float ABIs
+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 193133)
+++ 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 193133)
+++ 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: incpath.c
===================================================================
--- incpath.c	(revision 193133)
+++ 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: Makefile.in
===================================================================
--- Makefile.in	(revision 193133)
+++ Makefile.in	(working copy)
@@ -530,6 +530,18 @@
 extra_opt_files=@extra_opt_files@
 host_hook_obj=@out_host_hook_obj@
 
+# Multiarch support
+enable_multiarch = @enable_multiarch@
+with_float = @with_float@
+ifeq ($(enable_multiarch),yes)
+  if_multiarch = $(1)
+else ifeq ($(enable_multiarch),auto)
+  # SYSTEM_HEADER_DIR is makefile syntax, cannot be evaluated in configure.ac
+  if_multiarch = $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o),$(1))
+else
+  if_multiarch =
+endif
+
 # ------------------------
 # Installation directories
 # ------------------------
@@ -1807,10 +1819,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: 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-linux64
===================================================================
--- config/i386/t-linux64	(revision 193133)
+++ 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+= mx32=../libx32
+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$(call if_multiarch,:x32-linux-gnu)
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: gcc.c
===================================================================
--- gcc.c	(revision 193133)
+++ 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;
 \f
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) in a compiler or link
@@ -2084,6 +2089,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;
@@ -2101,11 +2107,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;
@@ -2114,16 +2123,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);
 	}
 
@@ -2152,6 +2160,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))
@@ -2980,6 +2998,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\
@@ -3264,6 +3285,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:
@@ -4920,6 +4942,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);
@@ -6589,6 +6620,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)
@@ -7360,7 +7400,9 @@
    options are present, then we will ignore this completely. Passing
    that, gcc will consider each multilib_select in turn using the same
    rules for matching the options. If a match is found, that subdirectory
-   will be used.  */
+   will be used.
+   A subdirectory name is optionally followed by a colon and the corresponding
+   multiarch name.  */
 
 static void
 set_multilib_dir (void)
@@ -7572,10 +7614,25 @@
 	    q++;
 	  if (q < end)
 	    {
-	      char *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;
+	      const char *q2 = q + 1, *ml_end = end;
+	      char *new_multilib_os_dir;
+
+	      while (q2 < end && *q2 != ':')
+		q2++;
+	      if (*q2 == ':')
+		ml_end = q2;
+	      new_multilib_os_dir = XNEWVEC (char, ml_end - q);
+	      memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
+	      new_multilib_os_dir[ml_end - q - 1] = '\0';
+	      multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : ".";
+
+	      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;
 	    }
 	}
@@ -7635,9 +7692,10 @@
 	}
 
       /* 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] == ':')
+	 MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
+         with .:: for multiarch configurations) are there just to find
+         multilib_os_dir, so skip them from output.  */
+      if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
 	skip = 1;
 
       /* Check for matches with the multilib_exclusions. We don't bother
Index: genmultilib
===================================================================
--- genmultilib	(revision 193133)
+++ 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 ninth 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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-04 15:45           ` Matthias Klose
@ 2012-11-14 20:44             ` Ian Lance Taylor
  2012-11-21  0:53               ` Matthias Klose
  0 siblings, 1 reply; 47+ messages in thread
From: Ian Lance Taylor @ 2012-11-14 20:44 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

On Sun, Nov 4, 2012 at 7:45 AM, Matthias Klose <doko@ubuntu.com> wrote:
>
> now testing the attached patch.

> +				     when 1 is passed,
> +				   - the multiarch path specified with
> +				     -imultiarch, when 2 is passed.  */

s/when 1 is passed/when set to 1/
Same for 2.

This is OK with that change.

Thanks and sorry for the delay in review.

Ian

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-08-07 10:33   ` [ping] " Matthias Klose
  2012-08-07 14:07     ` Ian Lance Taylor
@ 2012-11-15 11:44     ` Eric Botcazou
  2012-11-15 11:58       ` Matthias Klose
  1 sibling, 1 reply; 47+ messages in thread
From: Eric Botcazou @ 2012-11-15 11:44 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

> re-attaching the updated patch with the fixed comment in genmultilib.

This has introduced:

make[3]: Leaving directory `/red.a/gnatmail/gcc-x/build-red/x86_64-
linux/gnat/obj/libdecnumber'
make[3]: Entering directory `/red.a/gnatmail/gcc-x/build-red/x86_64-
linux/gnat/obj/gcc'
Makefile:538: Extraneous text after `else' directive
Makefile:541: *** only one `else' per conditional.  Stop.


# Multiarch support
enable_multiarch = auto
with_float = 
ifeq ($(enable_multiarch),yes)
  if_multiarch = $(1)
else ifeq ($(enable_multiarch),auto)
  # SYSTEM_HEADER_DIR is makefile syntax, cannot be evaluated in configure.ac
  if_multiarch = $(if $(wildcard $(shell echo 
$(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o),$(1))
else
  if_multiarch =
endif

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-15 11:44     ` Eric Botcazou
@ 2012-11-15 11:58       ` Matthias Klose
  2012-11-15 16:33         ` Eric Botcazou
  0 siblings, 1 reply; 47+ messages in thread
From: Matthias Klose @ 2012-11-15 11:58 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

[-- Attachment #1: Type: text/plain, Size: 545 bytes --]

Am 15.11.2012 12:41, schrieb Eric Botcazou:
>> re-attaching the updated patch with the fixed comment in genmultilib.
> 
> This has introduced:
> 
> make[3]: Leaving directory `/red.a/gnatmail/gcc-x/build-red/x86_64-
> linux/gnat/obj/libdecnumber'
> make[3]: Entering directory `/red.a/gnatmail/gcc-x/build-red/x86_64-
> linux/gnat/obj/gcc'
> Makefile:538: Extraneous text after `else' directive
> Makefile:541: *** only one `else' per conditional.  Stop.

ahh, this is with GNU make 3.80. Checked in the following patch as obvious.

  Matthias


[-- Attachment #2: make.diff --]
[-- Type: text/x-diff, Size: 901 bytes --]

2012-11-15  Matthias Klose  <doko@ubuntu.com>

	* Makefile.in (if_multiarch): Don't use a GNU make 3.81 feature.

Index: Makefile.in
===================================================================
--- Makefile.in	(Revision 193528)
+++ Makefile.in	(Arbeitskopie)
@@ -535,11 +535,13 @@
 with_float = @with_float@
 ifeq ($(enable_multiarch),yes)
   if_multiarch = $(1)
-else ifeq ($(enable_multiarch),auto)
-  # SYSTEM_HEADER_DIR is makefile syntax, cannot be evaluated in configure.ac
-  if_multiarch = $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o),$(1))
 else
-  if_multiarch =
+  ifeq ($(enable_multiarch),auto)
+    # SYSTEM_HEADER_DIR is makefile syntax, cannot be evaluated in configure.ac
+    if_multiarch = $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib/*/crti.o),$(1))
+  else
+    if_multiarch =
+  endif
 endif
 
 # ------------------------

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-15 11:58       ` Matthias Klose
@ 2012-11-15 16:33         ` Eric Botcazou
  0 siblings, 0 replies; 47+ messages in thread
From: Eric Botcazou @ 2012-11-15 16:33 UTC (permalink / raw)
  To: Matthias Klose
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

> ahh, this is with GNU make 3.80. Checked in the following patch as obvious.

Thanks!

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [ping] Re: [patch v2] support for multiarch systems
  2012-11-14 20:44             ` Ian Lance Taylor
@ 2012-11-21  0:53               ` Matthias Klose
  0 siblings, 0 replies; 47+ messages in thread
From: Matthias Klose @ 2012-11-21  0:53 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Thomas Schwinge

Am 14.11.2012 21:44, schrieb Ian Lance Taylor:
> On Sun, Nov 4, 2012 at 7:45 AM, Matthias Klose <doko@ubuntu.com> wrote:
>>
>> now testing the attached patch.
> 
>> +				     when 1 is passed,
>> +				   - the multiarch path specified with
>> +				     -imultiarch, when 2 is passed.  */
> 
> s/when 1 is passed/when set to 1/
> Same for 2.
> 
> This is OK with that change.
> 
> Thanks and sorry for the delay in review.

thanks for finishing the review. I'm checking in the following patch to move out
the multiarch paragraph out of the multilib documentation as obvious.

  Matthias

 2012-11-20  Matthias Klose  <doko@ubuntu.com>

+	* doc/install.texi: Move multiarch paragraph out of multilib
+	documentation.
+
+2012-11-20  Matthias Klose  <doko@ubuntu.com>
+
 	* config/arm/t-linux-eabi: Define MULTIARCH_DIRNAME for linux target.

 2012-11-20  Richard Sandiford  <rdsandiford@googlemail.com>
Index: gcc/doc/install.texi
===================================================================
--- gcc/doc/install.texi	(revision 193684)
+++ gcc/doc/install.texi	(working copy)
@@ -1027,12 +1027,6 @@
 @code{gnu2}, which select between the original GNU dialect and the GNU TLS
 descriptor-based dialect.

-@item --disable-multilib
-Specify that multiple target
-libraries to support different target variants, calling
-conventions, etc.@: should not be built.  The default is to build a
-predefined set of them.
-
 @item --enable-multiarch
 Specify whether to enable or disable multiarch support.  The default is
 to check for glibc start files in a multiarch location, and enable it
@@ -1042,6 +1036,12 @@
 More documentation about multiarch can be found at
 @uref{http://wiki.debian.org/Multiarch}.

+@item --disable-multilib
+Specify that multiple target
+libraries to support different target variants, calling
+conventions, etc.@: should not be built.  The default is to build a
+predefined set of them.
+
 Some targets provide finer-grained control over which multilibs are built
 (e.g., @option{--disable-softfloat}):
 @table @code

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2012-11-21  0:53 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-20 21:07 [patch] support for multiarch systems Matthias Klose
2011-08-20 21:16 ` Jakub Jelinek
2011-08-21  2:22   ` Matthias Klose
2011-08-20 21:44 ` Joseph S. Myers
2011-08-21  7:55   ` Matthias Klose
2011-08-21 10:20     ` Andrew Pinski
2011-08-21 16:23     ` Joseph S. Myers
2011-08-21  9:05 ` Matthias Klose
2011-08-22 18:51   ` Toon Moene
2011-09-06  6:57   ` Thomas Schwinge
2011-11-01 19:48   ` Marc Glisse
2011-11-02  0:53     ` Joseph S. Myers
2012-05-08  1:04 ` Matthias Klose
2012-05-08 13:21   ` Joseph S. Myers
2012-05-09  0:38     ` Matthias Klose
2012-05-09 13:37       ` Paolo Bonzini
2012-05-09 15:34         ` Matthias Klose
2012-05-09 16:29           ` Paolo Bonzini
2012-05-09 17:19             ` Matthias Klose
2012-05-10  6:42               ` Paolo Bonzini
2012-05-11  5:14                 ` Matthias Klose
2012-05-11 10:51                   ` Paolo Bonzini
2012-05-11 18:33                     ` Matthias Klose
2012-05-12 22:09                     ` Jonathan Nieder
2012-05-19 16:05       ` Thomas Schwinge
2012-06-06 14:28         ` Thomas Schwinge
2012-06-25 13:23 ` Matthias Klose
2012-06-25 14:00   ` Joseph S. Myers
2012-06-25 16:26     ` Matthias Klose
2012-06-28 10:31       ` Thomas Schwinge
2012-06-28 11:30         ` Matthias Klose
2012-06-28 11:41           ` Thomas Schwinge
2012-07-08 18:50 ` [patch v2] " Matthias Klose
2012-07-18 19:00   ` Thomas Schwinge
2012-07-19  1:12   ` John David Anglin
2012-07-19  3:19     ` David Miller
2012-07-19 15:14     ` Joseph S. Myers
2012-08-07 10:33   ` [ping] " Matthias Klose
2012-08-07 14:07     ` Ian Lance Taylor
2012-11-02 13:26       ` Matthias Klose
2012-11-02 17:37         ` Ian Lance Taylor
2012-11-04 15:45           ` Matthias Klose
2012-11-14 20:44             ` Ian Lance Taylor
2012-11-21  0:53               ` Matthias Klose
2012-11-15 11:44     ` Eric Botcazou
2012-11-15 11:58       ` Matthias Klose
2012-11-15 16:33         ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).