forked from OSchip/llvm-project
[Driver] Improve linking options for target AVR
1. Support user specified linker (-fuse-ld) 2. Support user specified linker script (-T) Reviewed By: MaskRay, haowei Differential Revision: https://reviews.llvm.org/D126192
This commit is contained in:
parent
5965878d4d
commit
753b915167
|
@ -36,10 +36,6 @@ def warn_drv_avr_mcu_not_specified : Warning<
|
|||
"no target microcontroller specified on command line, cannot "
|
||||
"link standard libraries, please pass -mmcu=<mcu name>">,
|
||||
InGroup<AVRRtlibLinkingQuirks>;
|
||||
def warn_drv_avr_gcc_not_found: Warning<
|
||||
"no avr-gcc installation can be found on the system, "
|
||||
"cannot link standard libraries">,
|
||||
InGroup<AVRRtlibLinkingQuirks>;
|
||||
def warn_drv_avr_libc_not_found: Warning<
|
||||
"no avr-libc installation can be found on the system, "
|
||||
"cannot link standard libraries">,
|
||||
|
|
|
@ -375,8 +375,7 @@ AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
|
|||
|
||||
// Only add default libraries if the user hasn't explicitly opted out.
|
||||
if (!Args.hasArg(options::OPT_nostdlib) &&
|
||||
!Args.hasArg(options::OPT_nodefaultlibs) &&
|
||||
GCCInstallation.isValid()) {
|
||||
!Args.hasArg(options::OPT_nodefaultlibs) && GCCInstallation.isValid()) {
|
||||
GCCInstallPath = GCCInstallation.getInstallPath();
|
||||
std::string GCCParentPath(GCCInstallation.getParentLibPath());
|
||||
getProgramPaths().push_back(GCCParentPath + "/../bin");
|
||||
|
@ -429,9 +428,14 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
// Compute information about the target AVR.
|
||||
std::string CPU = getCPUName(D, Args, getToolChain().getTriple());
|
||||
llvm::Optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
|
||||
llvm::Optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();
|
||||
llvm::Optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU);
|
||||
|
||||
std::string Linker = getToolChain().GetProgramPath(getShortName());
|
||||
// Compute the linker program path, and use GNU "avr-ld" as default.
|
||||
const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
|
||||
std::string Linker = A ? getToolChain().GetLinkerPath(nullptr)
|
||||
: getToolChain().GetProgramPath(getShortName());
|
||||
|
||||
ArgStringList CmdArgs;
|
||||
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
|
||||
|
||||
|
@ -450,17 +454,11 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
if (!Args.hasArg(options::OPT_nostdlib) &&
|
||||
!Args.hasArg(options::OPT_nodefaultlibs)) {
|
||||
if (!CPU.empty()) {
|
||||
Optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
|
||||
Optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();
|
||||
|
||||
if (!FamilyName) {
|
||||
// We do not have an entry for this CPU in the family
|
||||
// mapping table yet.
|
||||
D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented)
|
||||
<< CPU;
|
||||
} else if (TC.getGCCInstallPath().empty()) {
|
||||
// We can not link since there is no avr-ld.
|
||||
D.Diag(diag::warn_drv_avr_gcc_not_found);
|
||||
} else if (!AVRLibcRoot) {
|
||||
// No avr-libc found and so no runtime linked.
|
||||
D.Diag(diag::warn_drv_avr_libc_not_found);
|
||||
|
@ -473,7 +471,6 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
LinkStdlib = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!LinkStdlib)
|
||||
D.Diag(diag::warn_drv_avr_stdlib_not_linked);
|
||||
}
|
||||
|
@ -508,10 +505,14 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
|
||||
CmdArgs.push_back("--end-group");
|
||||
|
||||
// Add user specified linker script.
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_T);
|
||||
|
||||
// Specify the family name as the emulation mode to use.
|
||||
// This is almost always required because otherwise avr-ld
|
||||
// will assume 'avr2' and warn about the program being larger
|
||||
// than the bare minimum supports.
|
||||
if (Linker.find("avr-ld") != std::string::npos)
|
||||
CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,22 @@
|
|||
// LINKA-NOT: warning: {{.*}} data section address
|
||||
|
||||
// RUN: %clang -### --target=avr --sysroot=%S/Inputs/ -mmcu=atmega328 %s 2>&1 | FileCheck --check-prefixes=NOGCC %s
|
||||
// NOGCC: warning: no avr-gcc installation can be found on the system, cannot link standard libraries
|
||||
// NOGCC: warning: standard library not linked and so no interrupt vector table or compiler runtime routines will be linked
|
||||
// NOGCC-NOT: warning: {{.*}} microcontroller
|
||||
// NOGCC-NOT: warning: {{.*}} avr-libc
|
||||
// NOGCC-NOT: warning: {{.*}} data section address
|
||||
|
||||
// RUN: %clang -### --target=avr --sysroot=%S/Inputs/basic_avr_tree -mmcu=atmega328 %s -fuse-ld=avrld 2>&1 | FileCheck --check-prefix=NOLD %s
|
||||
// NOLD: error: invalid linker
|
||||
|
||||
// RUN: %clang -### --target=avr --sysroot=%S/Inputs/basic_avr_tree -mmcu=atmega328 %s -fuse-ld=%S/Inputs/basic_avr_tree/usr/bin/ld.lld 2>&1 | FileCheck --check-prefix=LLD %s
|
||||
// LLD: {{".*lld"}}
|
||||
// LLD-NOT: "avr-ld"
|
||||
// LLD-NOT: "-mavr5"
|
||||
|
||||
// RUN: %clang -### --target=avr --sysroot=%S/Inputs/basic_avr_tree -mmcu=atmega328 %s -T avr.lds 2>&1 | FileCheck --check-prefix=LDS0 %s
|
||||
// LDS0: "-T" "avr.lds" "-mavr5"
|
||||
|
||||
// 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"
|
||||
|
|
Loading…
Reference in New Issue