[llvm] 4d85444 - [clang-cl] Always interpret the LIB env var as separated with semicolons

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 13:43:25 PDT 2020


Author: Martin Storsjö
Date: 2020-09-21T23:42:59+03:00
New Revision: 4d85444b317a00a3e15da63cdb693d272c99a0cc

URL: https://github.com/llvm/llvm-project/commit/4d85444b317a00a3e15da63cdb693d272c99a0cc
DIFF: https://github.com/llvm/llvm-project/commit/4d85444b317a00a3e15da63cdb693d272c99a0cc.diff

LOG: [clang-cl] Always interpret the LIB env var as separated with semicolons

When cross compiling with clang-cl, clang splits the INCLUDE env
variable around semicolons (clang/lib/Driver/ToolChains/MSVC.cpp,
MSVCToolChain::AddClangSystemIncludeArgs) and lld splits the
LIB variable similarly (lld/COFF/Driver.cpp,
LinkerDriver::addLibSearchPaths). Therefore, the consensus for
cross compilation with clang-cl and lld-link seems to be to use
semicolons, despite path lists normally being separated by colons
on unix and EnvPathSeparator being set to that.

Therefore, handle the LIB variable similarly in Clang, when
handling lib file arguments when driving linking via Clang.

This fixes commands like "clang-cl test.c -Fetest.exe kernel32.lib" in
a cross compilation setting. Normally, most users call (lld-)link
directly, but meson happens to use this command syntax for
has_function() tests.

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

Added: 
    

Modified: 
    clang/lib/Driver/Driver.cpp
    clang/test/Driver/cl-inputs.c
    llvm/include/llvm/Support/Process.h
    llvm/lib/Support/Process.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 65b44597bc16..69336f6f94b6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2085,7 +2085,7 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
 
   if (IsCLMode()) {
     if (!llvm::sys::path::is_absolute(Twine(Value)) &&
-        llvm::sys::Process::FindInEnvPath("LIB", Value))
+        llvm::sys::Process::FindInEnvPath("LIB", Value, ';'))
       return true;
 
     if (Args.hasArg(options::OPT__SLASH_link) && Ty == types::TY_Object) {

diff  --git a/clang/test/Driver/cl-inputs.c b/clang/test/Driver/cl-inputs.c
index c67fc24484ee..59455a0aa5e5 100644
--- a/clang/test/Driver/cl-inputs.c
+++ b/clang/test/Driver/cl-inputs.c
@@ -32,7 +32,9 @@
 // WARN-NOT: note
 
 // MSYS2_ARG_CONV_EXCL tells MSYS2 to skip conversion of the specified argument.
-// RUN: env LIB=%S/Inputs/cl-libs MSYS2_ARG_CONV_EXCL="/TP;/c" %clang_cl /c /TP cl-test.lib -### 2>&1 | FileCheck -check-prefix=TPlib %s
+// Add a dummy "other" entry to the path as well, to check that it's split
+// around semicolons even on unix.
+// RUN: env LIB="other;%S/Inputs/cl-libs" MSYS2_ARG_CONV_EXCL="/TP;/c" %clang_cl /c /TP cl-test.lib -### 2>&1 | FileCheck -check-prefix=TPlib %s
 // TPlib: warning: cl-test.lib: 'linker' input unused
 // TPlib: warning: argument unused during compilation: '/TP'
 // TPlib-NOT: cl-test.lib

diff  --git a/llvm/include/llvm/Support/Process.h b/llvm/include/llvm/Support/Process.h
index 0ba6d58ba287..af5091ab8ff4 100644
--- a/llvm/include/llvm/Support/Process.h
+++ b/llvm/include/llvm/Support/Process.h
@@ -29,6 +29,7 @@
 #include "llvm/Support/Chrono.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/Program.h"
 #include <system_error>
 
 namespace llvm {
@@ -107,10 +108,12 @@ class Process {
   /// considered.
   static Optional<std::string> FindInEnvPath(StringRef EnvName,
                                              StringRef FileName,
-                                             ArrayRef<std::string> IgnoreList);
+                                             ArrayRef<std::string> IgnoreList,
+                                             char Separator = EnvPathSeparator);
 
   static Optional<std::string> FindInEnvPath(StringRef EnvName,
-                                             StringRef FileName);
+                                             StringRef FileName,
+                                             char Separator = EnvPathSeparator);
 
   // This functions ensures that the standard file descriptors (input, output,
   // and error) are properly mapped to a file descriptor before we use any of

diff  --git a/llvm/lib/Support/Process.cpp b/llvm/lib/Support/Process.cpp
index 9e6e233b26ac..9f0b689ce6c8 100644
--- a/llvm/lib/Support/Process.cpp
+++ b/llvm/lib/Support/Process.cpp
@@ -28,21 +28,22 @@ using namespace sys;
 //===          independent code.
 //===----------------------------------------------------------------------===//
 
-Optional<std::string> Process::FindInEnvPath(StringRef EnvName,
-                                             StringRef FileName) {
-  return FindInEnvPath(EnvName, FileName, {});
+Optional<std::string>
+Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
+  return FindInEnvPath(EnvName, FileName, {}, Separator);
 }
 
 Optional<std::string> Process::FindInEnvPath(StringRef EnvName,
                                              StringRef FileName,
-                                             ArrayRef<std::string> IgnoreList) {
+                                             ArrayRef<std::string> IgnoreList,
+                                             char Separator) {
   assert(!path::is_absolute(FileName));
   Optional<std::string> FoundPath;
   Optional<std::string> OptPath = Process::GetEnv(EnvName);
   if (!OptPath.hasValue())
     return FoundPath;
 
-  const char EnvPathSeparatorStr[] = {EnvPathSeparator, '\0'};
+  const char EnvPathSeparatorStr[] = {Separator, '\0'};
   SmallVector<StringRef, 8> Dirs;
   SplitString(OptPath.getValue(), Dirs, EnvPathSeparatorStr);
 


        


More information about the llvm-commits mailing list