summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-09-13 13:13:52 +0000
committerNico Weber <nicolasweber@gmx.de>2019-09-13 13:13:52 +0000
commitd48ea5da94165dbaba14b1281b74994fe970a7e0 (patch)
tree0f6a7804b6c93c6a00939ef6feb34b713ab1d9e8
parent67503ba556cd4008179491db6d024ec0f9d9c9cd (diff)
downloadbcm5719-llvm-d48ea5da94165dbaba14b1281b74994fe970a7e0.tar.gz
bcm5719-llvm-d48ea5da94165dbaba14b1281b74994fe970a7e0.zip
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 llvm-svn: 371852
-rw-r--r--lld/COFF/Driver.cpp5
-rw-r--r--lld/COFF/Driver.h8
-rw-r--r--lld/COFF/DriverUtils.cpp13
-rw-r--r--lld/COFF/Options.td2
-rw-r--r--lld/docs/ReleaseNotes.rst2
-rw-r--r--lld/test/COFF/libpath.test13
-rw-r--r--lld/test/COFF/linkenv.test5
7 files changed, 37 insertions, 11 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index b4457333eb5..b0214ce4c7c 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1094,7 +1094,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
// 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 char *> argsArr) {
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)) {
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 0fd61759540..cc2f25a6f95 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -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);
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index b525ffdae9c..e08b855740a 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -808,13 +808,17 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
// 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(std::vector<const char *> argv) {
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) {
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 59e69ea5439..6b6555bc030 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -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">,
diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index e63f75bef90..9c91a64127c 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -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
diff --git a/lld/test/COFF/libpath.test b/lld/test/COFF/libpath.test
index 77b4c546c99..baa8c2f2d50 100644
--- a/lld/test/COFF/libpath.test
+++ b/lld/test/COFF/libpath.test
@@ -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
diff --git a/lld/test/COFF/linkenv.test b/lld/test/COFF/linkenv.test
index 6033094d6db..78d11fd5d0a 100644
--- a/lld/test/COFF/linkenv.test
+++ b/lld/test/COFF/linkenv.test
@@ -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
OpenPOWER on IntegriCloud