[lld] r371852 - lld-link: Add a flag /lldignoreenv that makes lld-link ignore env vars.

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 13 06:13:52 PDT 2019


Author: nico
Date: Fri Sep 13 06:13:52 2019
New Revision: 371852

URL: http://llvm.org/viewvc/llvm-project?rev=371852&view=rev
Log:
lld-link: Add a flag /lldignoreenv that makes lld-link ignore env vars.

This is useful for enforcing that builds are independent of the
environment; it can be used when all system library paths are added
via /libpath: already. It's similar ot cl.exe's /X flag.

Since it should also affect %LINK% (the other caller of
`Process::GetEnv` in lld/COFF), the early-option-parsing needs
to move around a bit. The options are:

- Add a manual loop over the argv ArrayRef and look for "/lldignoreenv".
  This repeats the name of the flag in both Options.td and in
  DriverUtils.cpp.

- Add yet another table.ParseArgs() call just for /lldignoreenv before
  adding %LINK%.

- Use the existing early ParseArgs() that's there for --rsp-quoting and use
  it for /lldignoreenv for %LINK% as well. This means --rsp-quoting
  and /lldignoreenv can't be passed via %LINK%.

I went with the third approach.

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

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/Options.td
    lld/trunk/docs/ReleaseNotes.rst
    lld/trunk/test/COFF/libpath.test
    lld/trunk/test/COFF/linkenv.test

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri Sep 13 06:13:52 2019
@@ -1094,7 +1094,7 @@ void LinkerDriver::link(ArrayRef<const c
 
   // Parse command line options.
   ArgParser parser;
-  opt::InputArgList args = parser.parseLINK(argsArr);
+  opt::InputArgList args = parser.parse(argsArr);
 
   // Parse and evaluate -mllvm options.
   std::vector<const char *> v;
@@ -1162,7 +1162,8 @@ void LinkerDriver::link(ArrayRef<const c
   searchPaths.push_back("");
   for (auto *arg : args.filtered(OPT_libpath))
     searchPaths.push_back(arg->getValue());
-  addLibSearchPaths();
+  if (!args.hasArg(OPT_lldignoreenv))
+    addLibSearchPaths();
 
   // Handle /ignore
   for (auto *arg : args.filtered(OPT_ignore)) {

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Fri Sep 13 06:13:52 2019
@@ -43,8 +43,8 @@ public:
 
 class ArgParser {
 public:
-  // Concatenate LINK environment variable and given arguments and parse them.
-  llvm::opt::InputArgList parseLINK(std::vector<const char *> args);
+  // Parses command line options.
+  llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
 
   // Tokenizes a given string and then parses as command line options.
   llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }
@@ -56,8 +56,8 @@ public:
   parseDirectives(StringRef s);
 
 private:
-  // Parses command line options.
-  llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
+  // Concatenate LINK environment variable.
+  void addLINK(SmallVector<const char *, 256> &argv);
 
   std::vector<const char *> tokenize(StringRef s);
 

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Fri Sep 13 06:13:52 2019
@@ -808,13 +808,17 @@ opt::InputArgList ArgParser::parse(Array
 
   // We need to get the quoting style for response files before parsing all
   // options so we parse here before and ignore all the options but
-  // --rsp-quoting.
+  // --rsp-quoting and /lldignoreenv.
+  // (This means --rsp-quoting can't be added through %LINK%.)
   opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
 
-  // Expand response files (arguments in the form of @<filename>)
-  // and then parse the argument again.
+
+  // Expand response files (arguments in the form of @<filename>) and insert
+  // flags from %LINK% and %_LINK_%, and then parse the argument again.
   SmallVector<const char *, 256> expandedArgv(argv.data(),
                                               argv.data() + argv.size());
+  if (!args.hasArg(OPT_lldignoreenv))
+    addLINK(expandedArgv);
   cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
   args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
                          missingCount);
@@ -884,7 +888,7 @@ ArgParser::parseDirectives(StringRef s)
 // link.exe has an interesting feature. If LINK or _LINK_ environment
 // variables exist, their contents are handled as command line strings.
 // So you can pass extra arguments using them.
-opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
+void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
   // Concatenate LINK env and command line arguments, and then parse them.
   if (Optional<std::string> s = Process::GetEnv("LINK")) {
     std::vector<const char *> v = tokenize(*s);
@@ -894,7 +898,6 @@ opt::InputArgList ArgParser::parseLINK(s
     std::vector<const char *> v = tokenize(*s);
     argv.insert(std::next(argv.begin()), v.begin(), v.end());
   }
-  return parse(argv);
 }
 
 std::vector<const char *> ArgParser::tokenize(StringRef s) {

Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Fri Sep 13 06:13:52 2019
@@ -43,6 +43,8 @@ def lib : F<"lib">,
     HelpText<"Act like lib.exe; must be first argument if present">;
 def libpath : P<"libpath", "Additional library search path">;
 def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">;
+def lldignoreenv : F<"lldignoreenv">,
+    HelpText<"Ignore environment variables like %LIB%">;
 def lldltocache : P<"lldltocache", "Path to ThinLTO cached object file directory">;
 def lldltocachepolicy : P<"lldltocachepolicy", "Pruning policy for the ThinLTO cache">;
 def lldsavetemps : F<"lldsavetemps">,

Modified: lld/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/docs/ReleaseNotes.rst?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/docs/ReleaseNotes.rst (original)
+++ lld/trunk/docs/ReleaseNotes.rst Fri Sep 13 06:13:52 2019
@@ -32,6 +32,8 @@ COFF Improvements
 * /linkrepro: now takes the filename of the tar archive it writes, instead
   of the name of a directory that a file called "repro.tar" is created in,
   matching the behavior of ELF lld.
+* The new `/lldignoreenv` flag makes lld-link ignore environment variables
+  like `%LIB%`.
 * ...
 
 MinGW Improvements

Modified: lld/trunk/test/COFF/libpath.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/libpath.test?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/test/COFF/libpath.test (original)
+++ lld/trunk/test/COFF/libpath.test Fri Sep 13 06:13:52 2019
@@ -24,3 +24,16 @@ CHECK2: a{{[/\\]}}std64.lib
 
 CHECK3:     Reading {{.*}}a/std64.lib
 CHECK3-NOT: Reading {{.*}}b/std64.lib
+
+# RUN: env LIB=%t/a lld-link /out:%t.exe /entry:main /verbose \
+# RUN:   std64.lib /subsystem:console %p/Inputs/hello64.obj \
+# RUN:   2> %t.log
+# RUN: FileCheck -check-prefix=CHECK4 %s < %t.log
+
+CHECK4: a{{[/\\]}}std64.lib
+
+# This should fail because /lldignoreenv should make lld-link
+# ignore the LIB env var.
+# RUN: env LIB=%t/a not lld-link /out:%t.exe /entry:main /verbose \
+# RUN:   std64.lib /subsystem:console %p/Inputs/hello64.obj \
+# RUN:   /lldignoreenv

Modified: lld/trunk/test/COFF/linkenv.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/linkenv.test?rev=371852&r1=371851&r2=371852&view=diff
==============================================================================
--- lld/trunk/test/COFF/linkenv.test (original)
+++ lld/trunk/test/COFF/linkenv.test Fri Sep 13 06:13:52 2019
@@ -2,3 +2,8 @@
 # RUN: env _LINK_=-help lld-link | FileCheck %s
 
 CHECK: OVERVIEW: LLVM Linker
+
+# RUN: env LINK=-help not lld-link /lldignoreenv 2>&1 | \
+# RUN:     FileCheck --check-prefix=ERR %s
+
+ERR: error: no input files




More information about the llvm-commits mailing list