[lld] r205038 - [ELF] Support response file.

Rui Ueyama ruiu at google.com
Fri Mar 28 12:34:34 PDT 2014


Author: ruiu
Date: Fri Mar 28 14:34:34 2014
New Revision: 205038

URL: http://llvm.org/viewvc/llvm-project?rev=205038&view=rev
Log:
[ELF] Support response file.

Response file is a command line argument in the form of @file. The GNU-
compatible driver expands the file contents, replacing @file argument.

Differential Revision: http://llvm-reviews.chandlerc.com/D3210

Added:
    lld/trunk/test/elf/Inputs/responsefile
    lld/trunk/test/elf/responsefile.test
Modified:
    lld/trunk/lib/Driver/GnuLdDriver.cpp

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=205038&r1=205037&r2=205038&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Fri Mar 28 14:34:34 2014
@@ -32,8 +32,13 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Signals.h"
 
+#include <cstring>
+#include <tuple>
+
 using namespace lld;
 
+using llvm::BumpPtrAllocator;
+
 namespace {
 
 // Create enum with OPT_xxx values for each option in GnuLdOptions.td
@@ -68,8 +73,49 @@ public:
   GnuLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}
 };
 
+class DriverStringSaver : public llvm::cl::StringSaver {
+public:
+  DriverStringSaver(BumpPtrAllocator &alloc) : _alloc(alloc) {}
+
+  const char *SaveString(const char *s) override {
+    char *p = _alloc.Allocate<char>(strlen(s) + 1);
+    strcpy(p, s);
+    return p;
+  }
+
+private:
+  BumpPtrAllocator &_alloc;
+};
+
 } // anonymous namespace
 
+// If a command line option starts with "@", the driver reads its suffix as a
+// file, parse its contents as a list of command line options, and insert them
+// at the original @file position. If file cannot be read, @file is not expanded
+// and left unmodified. @file can appear in a response file, so it's a recursive
+// process.
+static std::tuple<int, const char **>
+maybeExpandResponseFiles(int argc, const char **argv, BumpPtrAllocator &alloc) {
+  // Expand response files.
+  SmallVector<const char *, 256> smallvec;
+  for (int i = 0; i < argc; ++i)
+    smallvec.push_back(argv[i]);
+  DriverStringSaver saver(alloc);
+  llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec);
+
+  // Pack the results to a C-array.
+  argc = smallvec.size();
+  std::vector<const char *> result;
+  for (size_t i = 0, e = smallvec.size(); i < e; ++i)
+    result.push_back(smallvec[i]);
+  result.push_back(nullptr);  // terminate ARGV with NULL
+
+  // Allocate memory for the result and return it.
+  const char **copy = alloc.Allocate<const char *>(argc + 1);
+  std::copy(smallvec.begin(), smallvec.end(), copy);
+  return std::make_tuple(argc, copy);
+}
+
 // Get the Input file magic for creating appropriate InputGraph nodes.
 static error_code getFileMagic(ELFLinkingContext &ctx, StringRef path,
                                llvm::sys::fs::file_magic &magic) {
@@ -118,6 +164,8 @@ std::string ELFFileNode::errStr(error_co
 
 bool GnuLdDriver::linkELF(int argc, const char *argv[],
                           raw_ostream &diagnostics) {
+  BumpPtrAllocator alloc;
+  std::tie(argc, argv) = maybeExpandResponseFiles(argc, argv, alloc);
   std::unique_ptr<ELFLinkingContext> options;
   if (!parse(argc, argv, options, diagnostics))
     return false;
@@ -133,7 +181,6 @@ bool GnuLdDriver::linkELF(int argc, cons
   if (options->allowLinkWithDynamicLibraries())
     options->registry().addSupportELFDynamicSharedObjects(
         options->useShlibUndefines(), options->targetHandler());
-
   return link(*options, diagnostics);
 }
 

Added: lld/trunk/test/elf/Inputs/responsefile
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/responsefile?rev=205038&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/responsefile (added)
+++ lld/trunk/test/elf/Inputs/responsefile Fri Mar 28 14:34:34 2014
@@ -0,0 +1 @@
+--inresponsefile

Added: lld/trunk/test/elf/responsefile.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/responsefile.test?rev=205038&view=auto
==============================================================================
--- lld/trunk/test/elf/responsefile.test (added)
+++ lld/trunk/test/elf/responsefile.test Fri Mar 28 14:34:34 2014
@@ -0,0 +1,6 @@
+# RUN: not lld -flavor gnu --abc @%p/Inputs/responsefile --baz >& %t.log
+# RUN: FileCheck %s < %t.log
+
+CHECK: warning: ignoring unknown argument: --abc
+CHECK: warning: ignoring unknown argument: --inresponsefile
+CHECK: warning: ignoring unknown argument: --baz





More information about the llvm-commits mailing list