Skip to content

Commit

Permalink
[Driver][BareMetal] Support --emit-static-lib in BareMetal driver
Browse files Browse the repository at this point in the history
This allows building static libraries with Clang driver.

Differential Revision: https://reviews.llvm.org/D148869
  • Loading branch information
petrhosek committed Jun 26, 2023
1 parent 17aa37d commit 5614d1a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
56 changes: 52 additions & 4 deletions clang/lib/Driver/ToolChains/BareMetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ Tool *BareMetal::buildLinker() const {
return new tools::baremetal::Linker(*this);
}

Tool *BareMetal::buildStaticLibTool() const {
return new tools::baremetal::StaticLibTool(*this);
}

std::string BareMetal::computeSysRoot() const {
return computeBaseSysRoot(getDriver(), getTriple());
}
Expand Down Expand Up @@ -368,6 +372,51 @@ void BareMetal::AddLinkRuntimeLib(const ArgList &Args,
llvm_unreachable("Unhandled RuntimeLibType.");
}

void baremetal::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getDriver();

// Silence warning for "clang -g foo.o -o foo"
Args.ClaimAllArgs(options::OPT_g_Group);
// and "clang -emit-llvm foo.o -o foo"
Args.ClaimAllArgs(options::OPT_emit_llvm);
// and for "clang -w foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);
// Silence warnings when linking C code with a C++ '-stdlib' argument.
Args.ClaimAllArgs(options::OPT_stdlib_EQ);

// ar tool command "llvm-ar <options> <output_file> <input_files>".
ArgStringList CmdArgs;
// Create and insert file members with a deterministic index.
CmdArgs.push_back("rcsD");
CmdArgs.push_back(Output.getFilename());

for (const auto &II : Inputs) {
if (II.isFilename()) {
CmdArgs.push_back(II.getFilename());
}
}

// Delete old output archive file if it already exists before generating a new
// archive file.
const char *OutputFileName = Output.getFilename();
if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) {
if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
return;
}
}

const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
C.addCommand(std::make_unique<Command>(JA, *this,
ResponseFileSupport::AtFileCurCP(),
Exec, CmdArgs, Inputs, Output));
}

void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
Expand Down Expand Up @@ -417,8 +466,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());

C.addCommand(std::make_unique<Command>(JA, *this,
ResponseFileSupport::AtFileCurCP(),
Args.MakeArgString(TC.GetLinkerPath()),
CmdArgs, Inputs, Output));
C.addCommand(std::make_unique<Command>(
JA, *this, ResponseFileSupport::AtFileCurCP(),
Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
}
15 changes: 15 additions & 0 deletions clang/lib/Driver/ToolChains/BareMetal.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain {

protected:
Tool *buildLinker() const override;
Tool *buildStaticLibTool() const override;

public:
bool useIntegratedAs() const override { return true; }
Expand Down Expand Up @@ -83,6 +84,20 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain {
namespace tools {
namespace baremetal {

class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool {
public:
StaticLibTool(const ToolChain &TC)
: Tool("baremetal::StaticLibTool", "llvm-ar", TC) {}

bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }

void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};

class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
Linker(const ToolChain &TC) : Tool("baremetal::Linker", "ld.lld", TC) {}
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Driver/baremetal.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// UNSUPPORTED: system-windows

// RUN: %clang -### %s --target=armv6-none-eabi --emit-static-lib 2>&1 \
// RUN: | FileCheck -check-prefixes=CHECK-STATIC-LIB %s
// CHECK-STATIC-LIB: {{.*}}llvm-ar{{.*}}" "rcsD"

// RUN: %clang %s -### --target=armv6m-none-eabi -o %t.out 2>&1 \
// RUN: -T semihosted.lds \
// RUN: -L some/directory/user/asked/for \
Expand Down

0 comments on commit 5614d1a

Please sign in to comment.