According to the definition in gcc/config/riscv/t-linux, after obtaining
the reused multilib_dir result using TARGET_COMPUTE_MULTILIB, we should
set multilib_os_dir to its parent directory.

For example, when building GCC with the options "--enable-multilib
--with-arch=rv64gc --with-abi=lp64d" and using GCC to compile RV32GC
programs, the current multilib_dir is set to "lib32/ilp32d", and
multilib_os_dir is also "lib32/ilp32d". This results in an inability to
locate the path "lib/lib32/ilp32d" during the linking process(as it does
not exist); the actual path should be "lib/../lib32/ilp32d".

Library Search Order Before Applying This Patch (Incorrect):

1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
2. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
3. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
4. sysroot/lib32/ilp32d/
5. sysroot/usr/lib32/ilp32d/
6. sysroot/lib/

Library Search Order After Applying This Patch:

1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/
2. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/
3. sysroot/lib/../lib32/ilp32d/
4. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/
5. 
lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/
6. sysroot/lib32/ilp32d/
7. sysroot/usr/lib32/ilp32d/
8. sysroot/lib/

Clearly, two valid paths (2 and 3) have been added, which is the correct 
behavior.

gcc/ChangeLog:

        * common/config/riscv/riscv-common.cc (riscv_compute_multilib_os):
        Implement TARGET_COMPUTE_MULTILIB_OS
        (TARGET_COMPUTE_MULTILIB_OS): Defined.
        * config/riscv/linux.h (RISCV_USE_CUSTOMISED_MULTI_LIB_OS): New.
---
 gcc/common/config/riscv/riscv-common.cc | 32 +++++++++++++++++++++++++
 gcc/config/riscv/linux.h                |  1 +
 2 files changed, 33 insertions(+)

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 5038f0eb959..526d1fb9ca2 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -2426,9 +2426,41 @@ riscv_compute_multilib (
     }
 }
 
+#ifndef RISCV_USE_CUSTOMISED_MULTI_LIB_OS
+#define RISCV_USE_CUSTOMISED_MULTI_LIB_OS 0
+#endif
+
+/* Implement TARGET_COMPUTE_MULTILIB_OS.  */
+static const char *
+riscv_compute_multilib_os (
+  const char *multilib_os_dir,
+  const char *multilib_dir)
+{
+  if (!RISCV_USE_CUSTOMISED_MULTI_LIB_OS)
+    return multilib_os_dir;
+
+  /* We don't need to do anything if we don't get multilib_dir.  */
+  if (multilib_dir == NULL)
+    return multilib_os_dir;
+
+  /* If multilib_dir is the default, multilib_os_dir should also be the
+     default.  */
+  if (strcmp (multilib_dir, ".") == 0 || multilib_os_dir != NULL)
+    return multilib_os_dir;
+
+  /* According to the definition in gcc/config/riscv/t-linux, We need to use 
the
+     multilib_dir's upper level directory instead of a simple copy.  In order
+     to maintain the original logic, we need to use the multilib_dir upper
+     level directory.  */
+  return concat ("../", multilib_dir , NULL);
+}
+
 #undef TARGET_COMPUTE_MULTILIB
 #define TARGET_COMPUTE_MULTILIB riscv_compute_multilib
 
+#undef TARGET_COMPUTE_MULTILIB_OS
+#define TARGET_COMPUTE_MULTILIB_OS riscv_compute_multilib_os
+
 vec<const char *>
 riscv_get_valid_option_values (int option_code,
                               const char *prefix ATTRIBUTE_UNUSED)
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 9060c940a44..4ac7477bdf4 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -68,3 +68,4 @@ along with GCC; see the file COPYING3.  If not see
    "/usr/lib/ "
 
 #define RISCV_USE_CUSTOMISED_MULTI_LIB select_by_abi
+#define RISCV_USE_CUSTOMISED_MULTI_LIB_OS 1
-- 
2.25.1

Reply via email to