edward-jones created this revision. edward-jones added reviewers: asb, simoncook, lenary. Herald added subscribers: cfe-commits, evandro, luismarques, apazos, sameer.abuasal, pzheng, s.egerton, Jim, benna, psnobl, jocewei, PkmX, rkruppe, the_o, brucehoult, MartinMosbeck, rogfer01, zzheng, MaskRay, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, johnrusso, rbar, emaste. Herald added a reviewer: espindola. Herald added a project: clang.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D81946 Files: clang/lib/Driver/ToolChains/Arch/RISCV.cpp clang/lib/Driver/ToolChains/Arch/RISCV.h clang/lib/Driver/ToolChains/Gnu.cpp clang/lib/Driver/ToolChains/RISCVToolchain.cpp clang/lib/Driver/ToolChains/RISCVToolchain.h clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32i/ilp32/clang_rt.crtbegin-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32i/ilp32/clang_rt.crtend-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32i/ilp32/libclang_rt.builtins-riscv32.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32iac/ilp32/clang_rt.crtbegin-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32iac/ilp32/clang_rt.crtend-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32iac/ilp32/libclang_rt.builtins-riscv32.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32im/ilp32/clang_rt.crtbegin-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32im/ilp32/clang_rt.crtend-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32im/ilp32/libclang_rt.builtins-riscv32.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imac/ilp32/clang_rt.crtbegin-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imac/ilp32/clang_rt.crtend-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imac/ilp32/libclang_rt.builtins-riscv32.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imafc/ilp32f/clang_rt.crtbegin-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imafc/ilp32f/clang_rt.crtend-riscv32.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv32imafc/ilp32f/libclang_rt.builtins-riscv32.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imac/lp64/clang_rt.crtbegin-riscv64.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imac/lp64/clang_rt.crtend-riscv64.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imac/lp64/libclang_rt.builtins-riscv64.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imafdc/lp64d/clang_rt.crtbegin-riscv64.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imafdc/lp64d/clang_rt.crtend-riscv64.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/lib/clang/11.0.0/rv64imafdc/lp64d/libclang_rt.builtins-riscv64.a clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv32i/ilp32/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv32iac/ilp32/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv32im/ilp32/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv32imac/ilp32/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv32imafc/ilp32f/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv64imac/lp64/crt0.o clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf/lib/rv64imafdc/lp64d/crt0.o clang/test/Driver/riscv32-toolchain-extra.c clang/test/Driver/riscv64-toolchain-extra.c
Index: clang/test/Driver/riscv64-toolchain-extra.c =================================================================== --- clang/test/Driver/riscv64-toolchain-extra.c +++ clang/test/Driver/riscv64-toolchain-extra.c @@ -30,3 +30,47 @@ // C-RV64-BAREMETAL-LP64-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" // C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}Output/testroot-riscv64-baremetal-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv64.a" // C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}Output/testroot-riscv64-baremetal-nogcc/{{.*}}/lib/clang_rt.crtend-riscv64.o" + +// Setup the directory tree for baremetal multilib with no detected GCC install +// RUN: rm -rf %T/testroot-multilib-riscv64-elf-nogcc +// RUN: mkdir -p %T/testroot-multilib-riscv64-elf-nogcc/bin +// RUN: ln -s %clang %T/testroot-multilib-riscv64-elf-nogcc/bin/clang +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld %T/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf %T/testroot-multilib-riscv64-elf-nogcc/riscv64-unknown-elf +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/lib %T/testroot-multilib-riscv64-elf-nogcc/lib + +// RUN: %T/testroot-multilib-riscv64-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv64-unknown-elf --rtlib=platform \ +// RUN: -march=rv64imac -mabi=lp64 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv64-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC %s + +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-m" "elf64lriscv" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imac/lp64{{/|\\\\}}crt0.o" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}clang_rt.crtbegin-riscv64.o" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imac/lp64" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}libclang_rt.builtins-riscv64.a" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}clang_rt.crtend-riscv64.o" + +// RUN: %T/testroot-multilib-riscv64-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv64-unknown-elf --rtlib=platform \ +// RUN: -march=rv64imafdc -mabi=lp64d \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv64-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC %s + +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-m" "elf64lriscv" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imafdc/lp64d{{/|\\\\}}crt0.o" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}clang_rt.crtbegin-riscv64.o" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imafdc/lp64d" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}libclang_rt.builtins-riscv64.a" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}clang_rt.crtend-riscv64.o" Index: clang/test/Driver/riscv32-toolchain-extra.c =================================================================== --- clang/test/Driver/riscv32-toolchain-extra.c +++ clang/test/Driver/riscv32-toolchain-extra.c @@ -30,3 +30,101 @@ // C-RV32-BAREMETAL-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" // C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}Output/testroot-riscv32-baremetal-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv32.a" // C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}Output/testroot-riscv32-baremetal-nogcc/{{.*}}/lib/clang_rt.crtend-riscv32.o" + +// Setup the directory tree for baremetal multilib with no detected GCC install +// RUN: rm -rf %T/testroot-multilib-riscv32-elf-nogcc +// RUN: mkdir -p %T/testroot-multilib-riscv32-elf-nogcc/bin +// RUN: ln -s %clang %T/testroot-multilib-riscv32-elf-nogcc/bin/clang +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld %T/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf %T/testroot-multilib-riscv32-elf-nogcc/riscv64-unknown-elf +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/lib %T/testroot-multilib-riscv32-elf-nogcc/lib + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32i -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32i/ilp32{{/|\\\\}}crt0.o" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32i/ilp32" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32iac -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32iac/ilp32{{/|\\\\}}crt0.o" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32iac/ilp32" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32im -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32im/ilp32{{/|\\\\}}crt0.o" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32im/ilp32" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32imac -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imac/ilp32{{/|\\\\}}crt0.o" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imac/ilp32" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32imafc -mabi=ilp32f \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC %s + +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-m" "elf32lriscv" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imafc/ilp32f{{/|\\\\}}crt0.o" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imafc/ilp32f" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}clang_rt.crtend-riscv32.o" Index: clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld @@ -0,0 +1 @@ +#!/bin/true Index: clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld @@ -0,0 +1 @@ +#!/bin/true Index: clang/lib/Driver/ToolChains/RISCVToolchain.h =================================================================== --- clang/lib/Driver/ToolChains/RISCVToolchain.h +++ clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -35,6 +35,10 @@ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + std::string getCompilerRT(const llvm::opt::ArgList &Args, + StringRef Component, + FileType Type) const override; + protected: Tool *buildLinker() const override; Index: clang/lib/Driver/ToolChains/RISCVToolchain.cpp =================================================================== --- clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -9,11 +9,13 @@ #include "RISCVToolchain.h" #include "CommonArgs.h" #include "InputInfo.h" +#include "Arch/RISCV.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" using namespace clang::driver; @@ -52,6 +54,20 @@ .str()); PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str()); } else { + riscv::findRISCVMultilibs(D, Triple, D.Dir, Args, Multilibs, + SelectedMultilib, + /*ShouldFilterNonExistent*/false); + + // Add toolchain/multilib specific file paths. + path_list &FilePaths = getFilePaths(); + addMultilibsFilePaths(D, Multilibs, SelectedMultilib, D.ResourceDir, + FilePaths); + // Also add to the library path. This is necessary as the library paths + // are used when searching for compiler-rt and crtbegin/crtend. + path_list &LibPaths = getLibraryPaths(); + addMultilibsFilePaths(D, Multilibs, SelectedMultilib, D.ResourceDir, + LibPaths); + getProgramPaths().push_back(D.Dir); } getFilePaths().push_back(computeSysRoot() + "/lib"); @@ -112,8 +128,31 @@ } else { // Use the triple as provided to the driver. Unlike the parsed triple // this has not been normalized to always contain every field. - llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", - getDriver().getTargetTriple()); + std::string TargetTriple = getDriver().getTargetTriple(); + + SmallString<32> BiarchVariantTriple; + SmallVector<StringRef, 2> TripleParts; + StringRef(TargetTriple).split(TripleParts, '-', 1); + if (TripleParts[0] == "riscv32") { + BiarchVariantTriple = "riscv64"; + } else { + assert (TripleParts[0] == "riscv64"); + BiarchVariantTriple = "riscv32"; + } + if (TripleParts.size() > 1) { + BiarchVariantTriple += '-'; + BiarchVariantTriple += TripleParts[1]; + } + + // First try the triple, if that doesn't exist then try the + // biarch variant - this matches the behaviour of the GCC install + // detector. + llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", TargetTriple); + if (!llvm::sys::fs::exists(SysRootDir)) { + SysRootDir.clear(); + llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", + BiarchVariantTriple); + } } if (!llvm::sys::fs::exists(SysRootDir)) @@ -122,6 +161,23 @@ return std::string(SysRootDir.str()); } +std::string RISCVToolChain::getCompilerRT(const ArgList &Args, + StringRef Component, + FileType Type) const { + std::string CRTBasename = + getCompilerRTBasename(Args, Component, Type, /*AddArch=*/true); + for (const auto &LibPath : getLibraryPaths()) { + SmallString<128> P(LibPath); + llvm::sys::path::append(P, CRTBasename); + if (getVFS().exists(P)) + return std::string(P.str()); + } + + SmallString<128> Path(getCompilerRTPath()); + llvm::sys::path::append(Path, CRTBasename); + return std::string(Path.str()); +} + void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -150,8 +206,8 @@ const char *crtbegin, *crtend; auto RuntimeLib = ToolChain.GetRuntimeLibType(Args); if (RuntimeLib == ToolChain::RLT_Libgcc) { - crtbegin = "crtbegin.o"; - crtend = "crtend.o"; + crtbegin = Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")); + crtend = Args.MakeArgString(ToolChain.GetFilePath("crtend.o")); } else { assert (RuntimeLib == ToolChain::RLT_CompilerRT); crtbegin = ToolChain.getCompilerRTArgString(Args, "crtbegin", @@ -162,7 +218,7 @@ if (WantCRTs) { CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); + CmdArgs.push_back(crtbegin); } Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -187,7 +243,7 @@ } if (WantCRTs) - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); + CmdArgs.push_back(crtend); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -1521,97 +1521,6 @@ return false; } -static void findRISCVBareMetalMultilibs(const Driver &D, - const llvm::Triple &TargetTriple, - StringRef Path, const ArgList &Args, - DetectedMultilibs &Result) { - FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - struct RiscvMultilib { - StringRef march; - StringRef mabi; - }; - // currently only support the set of multilibs like riscv-gnu-toolchain does. - // TODO: support MULTILIB_REUSE - constexpr RiscvMultilib RISCVMultilibSet[] = { - {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, - {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, - {"rv64imafdc", "lp64d"}}; - - std::vector<Multilib> Ms; - for (auto Element : RISCVMultilibSet) { - // multilib path rule is ${march}/${mabi} - Ms.emplace_back( - makeMultilib((Twine(Element.march) + "/" + Twine(Element.mabi)).str()) - .flag(Twine("+march=", Element.march).str()) - .flag(Twine("+mabi=", Element.mabi).str())); - } - MultilibSet RISCVMultilibs = - MultilibSet() - .Either(ArrayRef<Multilib>(Ms)) - .FilterOut(NonExistent) - .setFilePathsCallback([](const Multilib &M) { - return std::vector<std::string>( - {M.gccSuffix(), - "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), - "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); - }); - - - Multilib::flags_list Flags; - llvm::StringSet<> Added_ABIs; - StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); - StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); - for (auto Element : RISCVMultilibSet) { - addMultilibFlag(MArch == Element.march, - Twine("march=", Element.march).str().c_str(), Flags); - if (!Added_ABIs.count(Element.mabi)) { - Added_ABIs.insert(Element.mabi); - addMultilibFlag(ABIName == Element.mabi, - Twine("mabi=", Element.mabi).str().c_str(), Flags); - } - } - - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) - Result.Multilibs = RISCVMultilibs; -} - -static void findRISCVMultilibs(const Driver &D, - const llvm::Triple &TargetTriple, StringRef Path, - const ArgList &Args, DetectedMultilibs &Result) { - if (TargetTriple.getOS() == llvm::Triple::UnknownOS) - return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result); - - FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); - Multilib Ilp32f = - makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f"); - Multilib Ilp32d = - makeMultilib("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d"); - Multilib Lp64 = makeMultilib("lib64/lp64").flag("+m64").flag("+mabi=lp64"); - Multilib Lp64f = makeMultilib("lib64/lp64f").flag("+m64").flag("+mabi=lp64f"); - Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d"); - MultilibSet RISCVMultilibs = - MultilibSet() - .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) - .FilterOut(NonExistent); - - Multilib::flags_list Flags; - bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; - StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); - - addMultilibFlag(!IsRV64, "m32", Flags); - addMultilibFlag(IsRV64, "m64", Flags); - addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags); - addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags); - addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags); - addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags); - addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags); - addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags); - - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) - Result.Multilibs = RISCVMultilibs; -} - static bool findBiarchMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, @@ -2389,7 +2298,10 @@ if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) return false; } else if (TargetTriple.isRISCV()) { - findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); + tools::riscv::findRISCVMultilibs(D, TargetTriple, Path, Args, + Detected.Multilibs, + Detected.SelectedMultilib, + /*ShouldFilterNonExistent*/true); } else if (isMSP430(TargetArch)) { findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); } else if (TargetArch == llvm::Triple::avr) { Index: clang/lib/Driver/ToolChains/Arch/RISCV.h =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.h +++ clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -26,6 +26,17 @@ const llvm::Triple &Triple); StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +void findRISCVBareMetalMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent); +void findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, Multilib &SelectedMultilib, + bool ShouldFilterNonExistent); } // end namespace riscv } // namespace tools } // end namespace driver Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -14,6 +14,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "ToolChains/CommonArgs.h" @@ -28,6 +29,19 @@ StringRef Major; StringRef Minor; }; + +// Filter to remove Multilibs that don't exist as a suffix to Path +class FilterNonExistent { + StringRef Base, File; + llvm::vfs::FileSystem &VFS; + +public: + FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS) + : Base(Base), File(File), VFS(VFS) {} + bool operator()(const Multilib &M) { + return !VFS.exists(Base + M.gccSuffix() + File); + } +}; } // end anonymous namespace static StringRef getExtensionTypeDesc(StringRef Ext) { @@ -655,3 +669,113 @@ return "rv64imafdc"; } } + +static Multilib makeMultilib(StringRef commonSuffix) { + return Multilib(commonSuffix, commonSuffix, commonSuffix); +} + +void riscv::findRISCVBareMetalMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent) { + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + struct RiscvMultilib { + StringRef march; + StringRef mabi; + }; + // currently only support the set of multilibs like riscv-gnu-toolchain does. + // TODO: support MULTILIB_REUSE + constexpr RiscvMultilib RISCVMultilibSet[] = { + {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, + {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, + {"rv64imafdc", "lp64d"}}; + + std::vector<Multilib> Ms; + for (auto Element : RISCVMultilibSet) { + // multilib path rule is ${march}/${mabi} + Ms.emplace_back( + makeMultilib((Twine(Element.march) + "/" + Twine(Element.mabi)).str()) + .flag(Twine("+march=", Element.march).str()) + .flag(Twine("+mabi=", Element.mabi).str())); + } + MultilibSet RISCVMultilibs = + MultilibSet() + .Either(ArrayRef<Multilib>(Ms)); + + if (ShouldFilterNonExistent) + RISCVMultilibs.FilterOut(NonExistent); + + RISCVMultilibs.setFilePathsCallback([](const Multilib &M) { + return std::vector<std::string>( + {M.gccSuffix(), + "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), + "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix(), + // For clang + "/../../../riscv64-unknown-elf/lib" + M.gccSuffix(), + "/../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); + }); + + Multilib::flags_list Flags; + llvm::StringSet<> Added_ABIs; + StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); + StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); + for (auto Element : RISCVMultilibSet) { + addMultilibFlag(MArch == Element.march, + Twine("march=", Element.march).str().c_str(), Flags); + if (!Added_ABIs.count(Element.mabi)) { + Added_ABIs.insert(Element.mabi); + addMultilibFlag(ABIName == Element.mabi, + Twine("mabi=", Element.mabi).str().c_str(), Flags); + } + } + + if (RISCVMultilibs.select(Flags, SelectedMultilib)) + Multilibs = RISCVMultilibs; +} + +void riscv::findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent) { + if (TargetTriple.getOS() == llvm::Triple::UnknownOS) + return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Multilibs, + SelectedMultilib, + ShouldFilterNonExistent); + + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); + Multilib Ilp32f = + makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f"); + Multilib Ilp32d = + makeMultilib("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d"); + Multilib Lp64 = makeMultilib("lib64/lp64").flag("+m64").flag("+mabi=lp64"); + Multilib Lp64f = makeMultilib("lib64/lp64f").flag("+m64").flag("+mabi=lp64f"); + Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d"); + MultilibSet RISCVMultilibs = + MultilibSet() + .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}); + + if (ShouldFilterNonExistent) + RISCVMultilibs.FilterOut(NonExistent); + + Multilib::flags_list Flags; + bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; + StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); + + addMultilibFlag(!IsRV64, "m32", Flags); + addMultilibFlag(IsRV64, "m64", Flags); + addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags); + addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags); + addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags); + addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags); + addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags); + addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags); + + if (RISCVMultilibs.select(Flags, SelectedMultilib)) + Multilibs = RISCVMultilibs; +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits