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