Author: Keith Smiley
Date: 2021-09-17T12:11:05-07:00
New Revision: 80d62993d0720bc36523e39e64cc36da6e445e64

URL: 
https://github.com/llvm/llvm-project/commit/80d62993d0720bc36523e39e64cc36da6e445e64
DIFF: 
https://github.com/llvm/llvm-project/commit/80d62993d0720bc36523e39e64cc36da6e445e64.diff

LOG: [clang][darwin] Add support for --emit-static-lib

This uses darwin's default libtool since llvm-ar isn't normally
available.

Differential Revision: https://reviews.llvm.org/D109461

Added: 
    clang/test/Driver/darwin-static-lib.c

Modified: 
    clang/lib/Driver/ToolChain.cpp
    clang/lib/Driver/ToolChains/Darwin.cpp
    clang/lib/Driver/ToolChains/Darwin.h
    clang/test/Driver/bindings.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 6c1b88141c45..7272cc29cc7c 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -618,6 +618,8 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD,
 
 std::string ToolChain::GetStaticLibToolPath() const {
   // TODO: Add support for static lib archiving on Windows
+  if (Triple.isOSDarwin())
+    return GetProgramPath("libtool");
   return GetProgramPath("llvm-ar");
 }
 

diff  --git a/clang/lib/Driver/ToolChains/Darwin.cpp 
b/clang/lib/Driver/ToolChains/Darwin.cpp
index 15c885fa6507..8f3b6336d59d 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -729,6 +729,54 @@ void darwin::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
   C.addCommand(std::move(Cmd));
 }
 
+void darwin::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);
+
+  // libtool <options> <output_file> <input_files>
+  ArgStringList CmdArgs;
+  // Create and insert file members with a deterministic index.
+  CmdArgs.push_back("-static");
+  CmdArgs.push_back("-D");
+  CmdArgs.push_back("-no_warning_for_no_symbols");
+  CmdArgs.push_back("-o");
+  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 auto *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::AtFileUTF8(),
+                                         Exec, CmdArgs, Inputs, Output));
+}
+
 void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
                                 const InputInfo &Output,
                                 const InputInfoList &Inputs,
@@ -982,6 +1030,10 @@ Tool *MachO::getTool(Action::ActionClass AC) const {
 
 Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
 
+Tool *MachO::buildStaticLibTool() const {
+  return new tools::darwin::StaticLibTool(*this);
+}
+
 Tool *MachO::buildAssembler() const {
   return new tools::darwin::Assembler(*this);
 }

diff  --git a/clang/lib/Driver/ToolChains/Darwin.h 
b/clang/lib/Driver/ToolChains/Darwin.h
index 4de122c8d513..e46ff52a23a9 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -78,6 +78,20 @@ class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool {
                     const char *LinkingOutput) const override;
 };
 
+class LLVM_LIBRARY_VISIBILITY StaticLibTool : public MachOTool {
+public:
+  StaticLibTool(const ToolChain &TC)
+      : MachOTool("darwin::StaticLibTool", "static-lib-linker", 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 Lipo : public MachOTool {
 public:
   Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
@@ -125,6 +139,7 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
 protected:
   Tool *buildAssembler() const override;
   Tool *buildLinker() const override;
+  Tool *buildStaticLibTool() const override;
   Tool *getTool(Action::ActionClass AC) const override;
 
 private:

diff  --git a/clang/test/Driver/bindings.c b/clang/test/Driver/bindings.c
index d7f323419d39..93164f4e0026 100644
--- a/clang/test/Driver/bindings.c
+++ b/clang/test/Driver/bindings.c
@@ -27,3 +27,7 @@
 // GNU StaticLibTool binding
 // RUN: %clang -target x86_64-linux-gnu -ccc-print-bindings --emit-static-lib 
%s 2>&1 | FileCheck %s --check-prefix=CHECK15
 // CHECK15: "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: 
["{{.*}}.o"], output: "a.out"
+
+// Darwin StaticLibTool binding
+// RUN: %clang -target i386-apple-darwin9 -ccc-print-bindings 
--emit-static-lib %s 2>&1 | FileCheck %s --check-prefix=CHECK16
+// CHECK16: "i386-apple-darwin9" - "darwin::StaticLibTool", inputs: 
["{{.*}}.o"], output: "a.out"

diff  --git a/clang/test/Driver/darwin-static-lib.c 
b/clang/test/Driver/darwin-static-lib.c
new file mode 100644
index 000000000000..74a010e9656f
--- /dev/null
+++ b/clang/test/Driver/darwin-static-lib.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target i386-apple-darwin9 %s -### --emit-static-lib 2>&1 | 
FileCheck %s
+// CHECK: "{{.*}}libtool" "-static" "-D" "-no_warning_for_no_symbols" "-o" 
"a.out" "{{.*o}}"
+
+// RUN: %clang -target i386-apple-darwin9 %s -### --emit-static-lib -o 
libfoo.a 2>&1 | FileCheck %s --check-prefix=OUTPUT
+// OUTPUT: "{{.*}}libtool" "-static" "-D" "-no_warning_for_no_symbols" "-o" 
"libfoo.a" "{{.*o}}"


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to