Author: Ben Shi Date: 2022-08-16T09:22:50+08:00 New Revision: f45d89d73d3fcf4fd105a4d31c40eee9f0aa7fa1
URL: https://github.com/llvm/llvm-project/commit/f45d89d73d3fcf4fd105a4d31c40eee9f0aa7fa1 DIFF: https://github.com/llvm/llvm-project/commit/f45d89d73d3fcf4fd105a4d31c40eee9f0aa7fa1.diff LOG: [Driver] Support linking to compiler-rt for target AVR Reviewed By: aykevl Differential Revision: https://reviews.llvm.org/D128133 Added: clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/avr/libclang_rt.builtins.a Modified: clang/lib/Driver/ToolChains/AVR.cpp clang/lib/Driver/ToolChains/AVR.h clang/test/Driver/avr-ld.c clang/test/Driver/avr-toolchain.c Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 89d408823270a..35faa6d2199a5 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/SubtargetFeature.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" using namespace clang::driver; using namespace clang::driver::toolchains; @@ -369,8 +370,7 @@ AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, : Generic_ELF(D, Triple, Args) { GCCInstallation.init(Triple, Args); - std::string CPU = getCPUName(D, Args, Triple); - if (CPU.empty()) + if (getCPUName(D, Args, Triple).empty()) D.Diag(diag::warn_drv_avr_mcu_not_specified); // Only add default libraries if the user hasn't explicitly opted out. @@ -418,6 +418,23 @@ Tool *AVRToolChain::buildLinker() const { return new tools::AVR::Linker(getTriple(), *this); } +std::string +AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const { + assert(Type == ToolChain::FT_Static && "AVR only supports static libraries"); + // Since AVR can never be a host environment, its compiler-rt library files + // should always have ".a" suffix, even on windows. + SmallString<32> File("/libclang_rt."); + File += Component.str(); + File += ".a"; + // Return the default compiler-rt path appended with + // "avr/libclang_rt.$COMPONENT.a". + SmallString<256> Path(ToolChain::getCompilerRTPath()); + llvm::sys::path::append(Path, "avr"); + llvm::sys::path::append(Path, File.str()); + return std::string(Path.str()); +} + void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -448,6 +465,12 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); + // Currently we only support libgcc and compiler-rt. + auto RtLib = TC.GetRuntimeLibType(Args); + assert( + (RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) && + "unknown runtime library"); + // Only add default libraries if the user hasn't explicitly opted out. bool LinkStdlib = false; if (!Args.hasArg(options::OPT_nostdlib) && @@ -463,10 +486,12 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(diag::warn_drv_avr_libc_not_found); } else { std::string SubPath = GetMCUSubPath(CPU); + // Add path of avr-libc. CmdArgs.push_back( Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath)); - CmdArgs.push_back( - Args.MakeArgString("-L" + TC.getGCCInstallPath() + "/" + SubPath)); + if (RtLib == ToolChain::RLT_Libgcc) + CmdArgs.push_back(Args.MakeArgString("-L" + TC.getGCCInstallPath() + + "/" + SubPath)); LinkStdlib = true; } } @@ -495,14 +520,29 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o"); CmdArgs.push_back(Args.MakeArgString(CrtFileName)); - CmdArgs.push_back("-lgcc"); + // Link to libgcc. + if (RtLib == ToolChain::RLT_Libgcc) + CmdArgs.push_back("-lgcc"); + + // Link to generic libraries of avr-libc. CmdArgs.push_back("-lm"); CmdArgs.push_back("-lc"); // Add the link library specific to the MCU. CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU)); + // Add the relocatable inputs. AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + // We directly use libclang_rt.builtins.a as input file, instead of using + // '-lclang_rt.builtins'. + if (RtLib == ToolChain::RLT_CompilerRT) { + std::string RtLib = + getToolChain().getCompilerRT(Args, "builtins", ToolChain::FT_Static); + if (llvm::sys::fs::exists(RtLib)) + CmdArgs.push_back(Args.MakeArgString(RtLib)); + } + CmdArgs.push_back("--end-group"); // Add user specified linker script. diff --git a/clang/lib/Driver/ToolChains/AVR.h b/clang/lib/Driver/ToolChains/AVR.h index ab147d852ad7c..cd2bbee9efd66 100644 --- a/clang/lib/Driver/ToolChains/AVR.h +++ b/clang/lib/Driver/ToolChains/AVR.h @@ -33,6 +33,8 @@ class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF { llvm::Optional<std::string> findAVRLibcInstallation() const; StringRef getGCCInstallPath() const { return GCCInstallPath; } + std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type) const override; protected: Tool *buildLinker() const override; diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/avr/libclang_rt.builtins.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/avr/libclang_rt.builtins.a new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/avr-ld.c b/clang/test/Driver/avr-ld.c index cc98805c7ec27..9dcbf6ab42d55 100644 --- a/clang/test/Driver/avr-ld.c +++ b/clang/test/Driver/avr-ld.c @@ -1,44 +1,44 @@ -// RUN: %clang -### --target=avr -mmcu=at90s2313 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKA %s +// RUN: %clang -### --target=avr -mmcu=at90s2313 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKA %s // LINKA: {{".*ld.*"}} {{.*}} {{"-L.*tiny-stack"}} {{.*}} "-Tdata=0x800060" "--start-group" {{.*}} "-lat90s2313" {{.*}} "--end-group" "-mavr2" -// RUN: %clang -### --target=avr -mmcu=at90s8515 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKB %s +// RUN: %clang -### --target=avr -mmcu=at90s8515 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKB %s // LINKB: {{".*ld.*"}} {{.*}} "-Tdata=0x800060" "--start-group" {{.*}} "-lat90s8515" {{.*}} "--end-group" "-mavr2" -// RUN: %clang -### --target=avr -mmcu=attiny13 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKC %s +// RUN: %clang -### --target=avr -mmcu=attiny13 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKC %s // LINKC: {{".*ld.*"}} {{.*}} {{"-L.*avr25/tiny-stack"}} {{.*}} "-Tdata=0x800060" "--start-group" {{.*}} "-lattiny13" {{.*}} "--end-group" "-mavr25" -// RUN: %clang -### --target=avr -mmcu=attiny44 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKD %s +// RUN: %clang -### --target=avr -mmcu=attiny44 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKD %s // LINKD: {{".*ld.*"}} {{.*}} {{"-L.*avr25"}} {{.*}} "-Tdata=0x800060" "--start-group" {{.*}} "-lattiny44" {{.*}} "--end-group" "-mavr25" -// RUN: %clang -### --target=avr -mmcu=atmega103 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKE %s +// RUN: %clang -### --target=avr -mmcu=atmega103 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKE %s // LINKE: {{".*ld.*"}} {{.*}} {{"-L.*avr31"}} {{.*}} "-Tdata=0x800060" "--start-group" {{.*}} "-latmega103" {{.*}} "--end-group" "-mavr31" -// RUN: %clang -### --target=avr -mmcu=atmega8u2 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKF %s +// RUN: %clang -### --target=avr -mmcu=atmega8u2 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKF %s // LINKF: {{".*ld.*"}} {{.*}} {{"-L.*avr35"}} {{.*}} "-Tdata=0x800100" "--start-group" {{.*}} "-latmega8u2" {{.*}} "--end-group" "-mavr35" -// RUN: %clang -### --target=avr -mmcu=atmega48pa --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKG %s +// RUN: %clang -### --target=avr -mmcu=atmega48pa --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKG %s // LINKG: {{".*ld.*"}} {{.*}} {{"-L.*avr4"}} {{.*}} "-Tdata=0x800100" "--start-group" {{.*}} "-latmega48pa" {{.*}} "--end-group" "-mavr4" -// RUN: %clang -### --target=avr -mmcu=atmega328 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKH %s +// RUN: %clang -### --target=avr -mmcu=atmega328 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKH %s // LINKH: {{".*ld.*"}} {{.*}} {{"-L.*avr5"}} {{.*}} "-Tdata=0x800100" "--start-group" {{.*}} "-latmega328" {{.*}} "--end-group" "-mavr5" -// RUN: %clang -### --target=avr -mmcu=atmega1281 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKI %s +// RUN: %clang -### --target=avr -mmcu=atmega1281 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKI %s // LINKI: {{".*ld.*"}} {{.*}} {{"-L.*avr51"}} {{.*}} "-Tdata=0x800200" "--start-group" {{.*}} "-latmega1281" {{.*}} "--end-group" "-mavr51" -// RUN: %clang -### --target=avr -mmcu=atmega2560 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKJ %s +// RUN: %clang -### --target=avr -mmcu=atmega2560 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKJ %s // LINKJ: {{".*ld.*"}} {{.*}} {{"-L.*avr6"}} {{.*}} "-Tdata=0x800200" "--start-group" {{.*}} "-latmega2560" {{.*}} "--end-group" "-mavr6" -// RUN: %clang -### --target=avr -mmcu=attiny10 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKK %s +// RUN: %clang -### --target=avr -mmcu=attiny10 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKK %s // LINKK: {{".*ld.*"}} {{.*}} {{"-L.*avrtiny"}} {{.*}} "-Tdata=0x800040" "--start-group" {{.*}} "-lattiny10" {{.*}} "--end-group" "-mavrtiny" -// RUN: %clang -### --target=avr -mmcu=atxmega16a4 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKL %s +// RUN: %clang -### --target=avr -mmcu=atxmega16a4 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKL %s // LINKL: {{".*ld.*"}} {{.*}} {{"-L.*avrxmega2"}} {{.*}} "-Tdata=0x802000" "--start-group" {{.*}} "-latxmega16a4" {{.*}} "--end-group" "-mavrxmega2" -// RUN: %clang -### --target=avr -mmcu=atxmega64b3 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKM %s +// RUN: %clang -### --target=avr -mmcu=atxmega64b3 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKM %s // LINKM: {{".*ld.*"}} {{.*}} {{"-L.*avrxmega4"}} {{.*}} "-Tdata=0x802000" "--start-group" {{.*}} "-latxmega64b3" {{.*}} "--end-group" "-mavrxmega4" -// RUN: %clang -### --target=avr -mmcu=atxmega128a3u --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKN %s +// RUN: %clang -### --target=avr -mmcu=atxmega128a3u --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKN %s // LINKN: {{".*ld.*"}} {{.*}} {{"-L.*avrxmega6"}} {{.*}} "-Tdata=0x802000" "--start-group" {{.*}} "-latxmega128a3u" {{.*}} "--end-group" "-mavrxmega6" -// RUN: %clang -### --target=avr -mmcu=atxmega128a1 --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKO %s +// RUN: %clang -### --target=avr -mmcu=atxmega128a1 --rtlib=libgcc --sysroot %S/Inputs/basic_avr_tree %s 2>&1 | FileCheck -check-prefix LINKO %s // LINKO: {{".*ld.*"}} {{.*}} {{"-L.*avrxmega7"}} {{.*}} "-Tdata=0x802000" "--start-group" {{.*}} "-latxmega128a1" {{.*}} "--end-group" "-mavrxmega7" diff --git a/clang/test/Driver/avr-toolchain.c b/clang/test/Driver/avr-toolchain.c index 4232811cf19ff..d32fe7fe931e6 100644 --- a/clang/test/Driver/avr-toolchain.c +++ b/clang/test/Driver/avr-toolchain.c @@ -72,3 +72,16 @@ // RUN: %clang -### --target=avr --sysroot=%S/Inputs/basic_avr_tree -mmcu=atmega328 %s -fuse-ld=%S/Inputs/basic_avr_tree/usr/bin/ld.lld -T avr.lds 2>&1 | FileCheck --check-prefix=LDS1 %s // LDS1: "-T" "avr.lds" // LDS1-NOT: "-mavr5" + +// RUN: %clang %s -### --target=avr -mmcu=atmega328 --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=libgcc 2>&1 | FileCheck --check-prefix=LIBGCC %s +// LIBGCC: "-lgcc" +// LIBGCC-NOT: libclang_rt + +// RUN: %clang %s -### --target=avr -mmcu=atmega328 --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=compiler-rt 2>&1 | FileCheck --check-prefix=COMRT %s +// COMRT: avr/libclang_rt.builtins.a +// COMRT-NOT: "-lgcc" + +// RUN: %clang %s -### --target=avr --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=compiler-rt 2>&1 | FileCheck --check-prefix=NOMCU %s +// RUN: %clang %s -### --target=avr --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=libgcc 2>&1 | FileCheck --check-prefix=NOMCU %s +// NOMCU-NOT: libclang_rt +// NOMCU-NOT: "-lgcc" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits