Dealing with multiarch only

Message ID 20260505203114.1903026-1-stefansf@linux.ibm.com
State New
Headers
Series Dealing with multiarch only |

Commit Message

Stefan Schulze Frielinghaus May 5, 2026, 8:31 p.m. UTC
  From: Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org>

While removing multilib support on s390, we still want to maintain a
directory structure where 64-bit libraries end-up in directories named
"lib64" instead of "lib".  In order to do so only make use of

MULTIARCH_DIRNAME = ../lib64$(call if_multiarch,:s390x-linux-gnu)

and remove MULTILIB_{OPTIONS,DIRNAMES,OSDIRNAMES}.  This in turn means
multilib.h is generated by running

genmultilib "" "" "" "" "" "" "" "" "../lib64:s390x-linux-gnu" "" "false" "yes"

Note, the last argument "yes" is due to configure defaulting to enabling
multilib, if it is not explicitly disabled.  Independent on whether
multilib is explicitly disabled or not we end up with

static const char *const multilib_raw[] = {
".::../lib64:s390x-linux-gnu ;",
NULL
};

in the generated file multilib.h.  On Debian/Ubuntu, the two consecutive
colons lead to parsing the wrong multiarch_dir
"../lib64:s390x-linux-gnu" instead of "s390x-linux-gnu" in
set_multilib_dir() from driver gcc.cc.  This is fixed by removing the
superfluous colon

if [ -n "${multiarch}" ]; then
  defaultosdirname=::${multiarch}
fi

from generator genmultilib.  This restores bootstrap.  However, the
driver passes "-imultilib ." to cc1, now, which wasn't the case
previously.  If multilib is not supported, all multilib directories are
encoded by a dot which is why "-imultilib ." looks rather erroneous to
me.  If I'm not mistaken, then add_standard_paths() from incpath.cc
simply appends the argument from -imultilib to a path separated by a
directory separator.  Therefore, in this case it just takes "$some_path"
and returns "$somepath/." which could be filtered out:

  case 'I':
    {
      struct spec_path info;

      if (multilib_dir && strcmp (multilib_dir, ".") != 0)
        {
          do_spec_1 ("-imultilib", 1, NULL);
          /* Make this a separate argument.  */
          do_spec_1 (" ", 0, NULL);
          do_spec_1 (multilib_dir, 1, NULL);
          do_spec_1 (" ", 0, NULL);
        }

in do_spec_1() from gcc.cc.  For non-Unix-like OSs' this might not be
only superfluous but mandatory because a dot might mean something
different and doesn't resolve to the same directory.  Any thoughts about
this?

Currently I'm running bootstrap+regtest for the following
configurations:

{--enable-multilib,--disable-multilib} x {Ubuntu,Fedora} x {s390x-with-m31-removed,s390x-without-m31-removed,x86_64}-linux-gnu

which will take some time to complete.

---
 gcc/gcc.cc      | 2 +-
 gcc/genmultilib | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
  

Comments

Stefan Schulze Frielinghaus May 14, 2026, 5:59 a.m. UTC | #1
On Tue, May 05, 2026 at 10:31:14PM +0200, Stefan Schulze Frielinghaus wrote:
...
> Currently I'm running bootstrap+regtest for the following
> configurations:
> 
> {--enable-multilib,--disable-multilib} x {Ubuntu,Fedora} x {s390x-with-m31-removed,s390x-without-m31-removed,x86_64}-linux-gnu
> 
> which will take some time to complete.

Meanwhile bootstrap+regtest was successful.
  

Patch

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index f3e0004cdb8..acf1bb9a136 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -6588,7 +6588,7 @@  do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 	    {
 	      struct spec_path info;
 
-	      if (multilib_dir)
+	      if (multilib_dir && strcmp (multilib_dir, ".") != 0)
 		{
 		  do_spec_1 ("-imultilib", 1, NULL);
 		  /* Make this a separate argument.  */
diff --git a/gcc/genmultilib b/gcc/genmultilib
index a00d6d88683..43065c6ba85 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -277,7 +277,7 @@  toosdirnames=
 defaultosdirname=
 defaultosdirname2=
 if [ -n "${multiarch}" ]; then
-  defaultosdirname=::${multiarch}
+  defaultosdirname=:${multiarch}
 fi
 if [ -n "${osdirnames}" ]; then
   set x ${osdirnames}