On Tue, 25 Feb 2025 08:23:27 -0800 (PST), Palmer Dabbelt wrote: > On Fri, 14 Feb 2025 05:04:20 PST (-0800), ji...@linux.alibaba.com wrote: > > 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. > > We were talking about this in the patchwork meeting this morning, and > nobody could figure out why these paths are the desired behavior here.
First, it is important to note that we need the TARGET_COMPUTE_MULTILIB hook to replace the old MULTILIB_REUSE rule. Kito has already provided a reasonable explanation for this when introducing the new hook. Second, we need to ensure that the library search paths during compilation are consistent, regardless of whether the TARGET_COMPUTE_MULTILIB hook is used. Currently, this is clearly not the case. In summary, the purpose of this patch is solely to mitigate the negative effects introduced by the TARGET_COMPUTE_MULTILIB hook. I have not added any new paths :) > Unless I'm reading something wrong, this just adds two new paths: > > > lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/ > sysroot/lib/../lib32/ilp32d/ > > For the first one, if I remove all the ".." that resolves to > "riscv64-unknown-linux-gnu/lib32/ilp32d/". That looks odd to me, as I'd > expect that to be a sysroot-based path. For clarity, I have renumbered the library search paths before and after the patch, according to the order in which they are searched: Library Search Order Before Applying This Patch (Incorrect): a1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/ a2. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/ a3. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/ a4. sysroot/lib32/ilp32d/ a5. sysroot/usr/lib32/ilp32d/ a6. sysroot/lib/ Library Search Order After Applying This Patch: b1. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/lib32/ilp32d/ b2. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/../lib32/ilp32d/ b3. sysroot/lib/../lib32/ilp32d/ b4. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/ b5. lib/gcc/riscv64-unknown-linux-gnu/15.0.1/../../../../riscv64-unknown-linux-gnu/lib/ b6. sysroot/lib32/ilp32d/ b7. sysroot/usr/lib32/ilp32d/ b8. sysroot/lib/ In fact, when searching for library paths, we should first look at all paths related to lib32/ilp32d, such as b1(lib32/ilp32d) -> b2(lib32/ilp32d) -> b3(lib32/ilp32d) -> .... However, the current situation is a1(lib32/ilp32d) -> a2(lib64/lp64d) -> a3(lib64/lp64d) -> .... Clearly, we are traversing the wrong paths before reaching the sysroot. In reality, I discovered this issue because our downstream toolchain encountered an error during linking: "error: adding symbols: file in wrong format." This is due to rv32gc-ilp32d finding and attempting to link the incorrect library from the path a3(lib64/lp64d). Best regards, Jin Ma > For the second one, I get "sysroot/lib32/ilp32d/", which is already in > the list. > > So I'm not quite sure what's going on here. > > > 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