[lld] r238678 - COFF: Refactor functions to find files from search paths.
Rui Ueyama
ruiu at google.com
Sun May 31 12:17:12 PDT 2015
Author: ruiu
Date: Sun May 31 14:17:12 2015
New Revision: 238678
URL: http://llvm.org/viewvc/llvm-project?rev=238678&view=rev
Log:
COFF: Refactor functions to find files from search paths.
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/COFF/DriverUtils.cpp
lld/trunk/COFF/Memory.h
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238678&r1=238677&r2=238678&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun May 31 14:17:12 2015
@@ -23,6 +23,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
@@ -30,6 +31,7 @@ using namespace llvm;
using llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI;
using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI;
+using llvm::sys::Process;
namespace lld {
namespace coff {
@@ -94,7 +96,7 @@ LinkerDriver::parseDirectives(StringRef
std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
for (auto *Arg : Args->filtered(OPT_defaultlib)) {
- std::string Path = findLib(Arg->getValue());
+ StringRef Path = findLib(Arg->getValue());
if (!insertFile(Path))
continue;
Res->push_back(llvm::make_unique<ArchiveFile>(Path));
@@ -102,6 +104,56 @@ LinkerDriver::parseDirectives(StringRef
return std::error_code();
}
+// Find file from search paths. You can omit ".obj", this function takes
+// care of that. Note that the returned path is not guaranteed to exist.
+StringRef LinkerDriver::findFile(StringRef Filename) {
+ bool hasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
+ if (hasPathSep)
+ return Filename;
+ bool hasExt = (Filename.find('.') != StringRef::npos);
+ for (StringRef Dir : SearchPaths) {
+ SmallString<128> Path = Dir;
+ llvm::sys::path::append(Path, Filename);
+ if (llvm::sys::fs::exists(Path.str()))
+ return Alloc.save(Path.str());
+ if (!hasExt) {
+ Path.append(".obj");
+ if (llvm::sys::fs::exists(Path.str()))
+ return Alloc.save(Path.str());
+ }
+ }
+ return Filename;
+}
+
+StringRef LinkerDriver::findLib(StringRef Filename) {
+ StringRef S = addExtOpt(Filename, ".lib");
+ return findFile(S);
+}
+
+// Add Ext to Filename if Filename has no file extension.
+StringRef LinkerDriver::addExtOpt(StringRef Filename, StringRef Ext) {
+ bool hasExt = (Filename.find('.') != StringRef::npos);
+ if (hasExt)
+ return Filename;
+ return Alloc.save(Filename + Ext);
+}
+
+// Parses LIB environment which contains a list of search paths.
+std::vector<StringRef> LinkerDriver::getSearchPaths() {
+ std::vector<StringRef> Ret;
+ Ret.push_back(".");
+ Optional<std::string> EnvOpt = Process::GetEnv("LIB");
+ if (!EnvOpt.hasValue())
+ return Ret;
+ StringRef Env = Alloc.save(*EnvOpt);
+ while (!Env.empty()) {
+ StringRef Path;
+ std::tie(Path, Env) = Env.split(';');
+ Ret.push_back(Path);
+ }
+ return Ret;
+}
+
bool LinkerDriver::link(int Argc, const char *Argv[]) {
// Parse command line options.
auto ArgsOrErr = parseArgs(Argc, Argv);
@@ -187,7 +239,7 @@ bool LinkerDriver::link(int Argc, const
// The symbol table will take care of name resolution.
SymbolTable Symtab;
for (auto *Arg : Args->filtered(OPT_INPUT)) {
- std::string Path = findFile(Arg->getValue());
+ StringRef Path = findFile(Arg->getValue());
if (!insertFile(Path))
continue;
if (auto EC = Symtab.addFile(createFile(Path))) {
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=238678&r1=238677&r2=238678&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Sun May 31 14:17:12 2015
@@ -35,6 +35,7 @@ bool link(int Argc, const char *Argv[]);
class LinkerDriver {
public:
+ LinkerDriver() : SearchPaths(getSearchPaths()) {}
bool link(int Argc, const char *Argv[]);
// Used by the resolver to parse .drectve section contents.
@@ -45,6 +46,16 @@ private:
// Returns false if a given file has already been read.
bool insertFile(StringRef Path);
+ // Searches a file from search paths.
+ StringRef findFile(StringRef Filename);
+ StringRef findLib(StringRef Filename);
+ StringRef addExtOpt(StringRef Filename, StringRef Ext);
+
+ // Parses LIB environment which contains a list of search paths.
+ // The returned list always contains "." as the first element.
+ std::vector<StringRef> getSearchPaths();
+
+ std::vector<StringRef> SearchPaths;
std::set<std::string> VisitedFiles;
StringAllocator Alloc;
};
@@ -56,10 +67,6 @@ parseArgs(int Argc, const char *Argv[]);
void printHelp(const char *Argv0);
-// "ENV" environment variable-aware file finders.
-std::string findLib(StringRef Filename);
-std::string findFile(StringRef Filename);
-
// For /machine option.
ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args);
Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=238678&r1=238677&r2=238678&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Sun May 31 14:17:12 2015
@@ -39,54 +39,6 @@ using llvm::sys::fs::identify_magic;
namespace lld {
namespace coff {
-// Split the given string with the path separator.
-static std::vector<StringRef> splitPathList(StringRef str) {
- std::vector<StringRef> ret;
- while (!str.empty()) {
- StringRef path;
- std::tie(path, str) = str.split(';');
- ret.push_back(path);
- }
- return ret;
-}
-
-std::string findLib(StringRef Filename) {
- if (llvm::sys::fs::exists(Filename))
- return Filename;
- std::string Name;
- if (Filename.endswith_lower(".lib")) {
- Name = Filename;
- } else {
- Name = (Filename + ".lib").str();
- }
-
- Optional<std::string> Env = Process::GetEnv("LIB");
- if (!Env.hasValue())
- return Filename;
- for (StringRef Dir : splitPathList(*Env)) {
- SmallString<128> Path = Dir;
- llvm::sys::path::append(Path, Name);
- if (llvm::sys::fs::exists(Path.str()))
- return Path.str();
- }
- return Filename;
-}
-
-std::string findFile(StringRef Filename) {
- if (llvm::sys::fs::exists(Filename))
- return Filename;
- Optional<std::string> Env = Process::GetEnv("LIB");
- if (!Env.hasValue())
- return Filename;
- for (StringRef Dir : splitPathList(*Env)) {
- SmallString<128> Path = Dir;
- llvm::sys::path::append(Path, Filename);
- if (llvm::sys::fs::exists(Path.str()))
- return Path.str();
- }
- return Filename;
-}
-
// Returns /machine's value.
ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args) {
if (auto *Arg = Args->getLastArg(OPT_machine)) {
Modified: lld/trunk/COFF/Memory.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Memory.h?rev=238678&r1=238677&r2=238678&view=diff
==============================================================================
--- lld/trunk/COFF/Memory.h (original)
+++ lld/trunk/COFF/Memory.h Sun May 31 14:17:12 2015
@@ -31,6 +31,7 @@ public:
StringRef save(Twine S) { return save(StringRef(S.str())); }
StringRef save(const char *S) { return save(StringRef(S)); }
+ StringRef save(std::string &S) { return save(StringRef(S)); }
private:
llvm::BumpPtrAllocator Alloc;
More information about the llvm-commits
mailing list