[clang] 3b6e166 - [Driver] Improve linking options for target AVR
Ben Shi via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 13 18:31:07 PDT 2022
Author: Ben Shi
Date: 2022-06-14T01:30:49Z
New Revision: 3b6e166999bb83197c8b70468c2d371c58cf0c25
URL: https://github.com/llvm/llvm-project/commit/3b6e166999bb83197c8b70468c2d371c58cf0c25
DIFF: https://github.com/llvm/llvm-project/commit/3b6e166999bb83197c8b70468c2d371c58cf0c25.diff
LOG: [Driver] Improve linking options for target AVR
1. Support user specified linker (-fuse-ld)
2. Support user specified linker script (-T)
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D126192
Added:
clang/test/Driver/Inputs/basic_avr_tree/usr/bin/ld.lld
Modified:
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/ToolChains/AVR.cpp
clang/test/Driver/avr-toolchain.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 1012551651c5b..e43d17933e80e 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -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">,
diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp
index 466fc3b20569e..0bdbd5c09a5fc 100644
--- a/clang/lib/Driver/ToolChains/AVR.cpp
+++ b/clang/lib/Driver/ToolChains/AVR.cpp
@@ -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,12 @@ 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.
+ std::string Linker = getToolChain().GetLinkerPath(nullptr);
+
ArgStringList CmdArgs;
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
@@ -450,17 +452,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 +469,6 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
LinkStdlib = true;
}
}
-
if (!LinkStdlib)
D.Diag(diag::warn_drv_avr_stdlib_not_linked);
}
@@ -508,11 +503,15 @@ 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.
- CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
+ if (Linker.find("avr-ld") != std::string::npos)
+ CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
}
C.addCommand(std::make_unique<Command>(
diff --git a/clang/test/Driver/Inputs/basic_avr_tree/usr/bin/ld.lld b/clang/test/Driver/Inputs/basic_avr_tree/usr/bin/ld.lld
new file mode 100755
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/avr-toolchain.c b/clang/test/Driver/avr-toolchain.c
index 5bdd644638102..4232811cf19ff 100644
--- a/clang/test/Driver/avr-toolchain.c
+++ b/clang/test/Driver/avr-toolchain.c
@@ -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"
More information about the cfe-commits
mailing list