Page MenuHomePhabricator

[WIP][RISCV] Enable multilib support even without a detected GCC install
Needs ReviewPublic

Authored by edward-jones on Jun 16 2020, 9:42 AM.

Details

Summary

Previously the driver would only report multilibs which already exist. This has been relaxed so that when there is no detected GCC installation the multilibs will be reported anyway.

In the absence of a GCC installation, the driver will look for libraries starting from the resource directory:

<prefix>/lib/clang/<version>

This is slightly different to the path in the case where a GCC install is detected. in that case the resource directory includes the triple:

<prefix>/lib/gcc/<triple>/<version>

In addition to the resource directory the driver will also look for libraries not installed alongside the compiler in the following directories:

In the absence of a detected GCC installation:

<prefix>/lib/clang/<version>/../../../<triple>/lib

With a GCC installation:

<prefix>/lib/gcc/<triple>/<version>/../../../../<triple>/lib

The calculation of the sysroot has also been updated. If a sysroot was not provided to the driver then the driver would try to derive it from the detected GCC installation. If this was not possible then it would be derived from the directory of the driver "<prefix>/bin/clang" as follows:

<prefix>/bin/../<triple>

This uses the original triple as provided to the compiler, however this isn't ideal as the presence of multilibs means that riscv32 libraries/headers/tools may be installed under "<prefix>/riscv64-unknown-elf" instead of "<prefix>/riscv32-unknown-elf". The GCC installation detector already handles this by trying both the original triple *and* the triple of the biarch variant using the first directory with exists. This behaviour has been copied so the same occurs even without a gcc installation.

Diff Detail

Event Timeline

edward-jones created this revision.Jun 16 2020, 9:42 AM

Thanks for this Ed. I've tried building a toolchain with it and noticed a couple of things:

  1. Printing the set of multilibs doesn't provide a default, I think that should still be defined and printed with -print-multi-libs
  2. There's a slight path finding issue if I build compiler-rt with an option like -DCMAKE_INSTALL_PREFIX=$(clang -print-resource-dir)/${CRT_MULTILIB_DIR} (the latter being the multilib dir printed by -print-multi-libs).

The build system installs crtbegin/crtend/clang_rt into ${CMAKE_INSTALL_PREFIX}/lib (if I set the OS to ""), but clang searches for the multilib variants in a folder without /lib at the end.

Looking at compiler-rt's CMake that seems to be down to:

if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
  set(COMPILER_RT_LIBRARY_OUTPUT_DIR
    ${COMPILER_RT_OUTPUT_DIR})
  set(COMPILER_RT_LIBRARY_INSTALL_DIR
    ${COMPILER_RT_INSTALL_PATH})
else(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
  set(COMPILER_RT_LIBRARY_OUTPUT_DIR
    ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
  set(COMPILER_RT_LIBRARY_INSTALL_DIR
    ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
endif()

I can work around this by setting COMPILER_RT_OS_DIR to "..", but I'm wondering whether it makes more sense to allow "lib" to be replaced with a multilib directory name, preserving "lib" for the default multilib?

Other than that, a first bit of testing this is working great, it's nice having native bare metal RISC-V multilibs for Clang.