gccld.cpp:

Fix typo in header.
 Add IsArchive static method.
 Roll LoadLibraryFromDirectory() into LoadLibrary(), and factor
  LoadLibraryExactName() out of the result. Instead of treating the current
  directory specially, just insert it into LibPaths in the beginning of
  main().
 Make LoadLibrary() take a "search" flag that says whether to search for the
  correct library, or just trust that LibName is right.
 Make LinkLibrary() take a "search" flag, and pass it to LoadLibrary().
 Change the for-loop over InputFilenames to detect ar archives and link them
  in as libraries without searching.
 Change the for-loop over Libraries to explicitly turn on the "search" flag
  to LinkLibrary() that makes LoadLibrary() search for the correct library
  (i.e., when processing -lNAME options.)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6316 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Brian Gaeke 2003-05-23 20:27:07 +00:00
parent 02ec5ede6c
commit 69a79600cb

View File

@ -9,7 +9,7 @@
//
// Note that if someone (or a script) deletes the executable program generated,
// the .bc file will be left around. Considering that this is a temporary hack,
// I'm not to worried about this.
// I'm not too worried about this.
//
//===----------------------------------------------------------------------===//
@ -117,70 +117,80 @@ static Module *LoadSingleLibraryObject(const std::string &Filename) {
return M.release();
}
// IsArchive - Returns true iff FILENAME appears to be the name of an ar
// archive file. It determines this by checking the magic string at the
// beginning of the file.
static bool IsArchive (const std::string &filename) {
static const std::string ArchiveMagic ("!<arch>\012");
char buf[1 + ArchiveMagic.size ()];
std::ifstream f (filename.c_str ());
f.read (buf, ArchiveMagic.size ());
buf[ArchiveMagic.size ()] = '\0';
return (ArchiveMagic == buf);
}
// LoadLibraryFromDirectory - This looks for a .a, .so, or .bc file in a
// particular directory. It returns true if no library is found, otherwise it
// puts the loaded modules into the Objects list, and sets isArchive to true if
// a .a file was loaded.
//
static inline bool LoadLibraryFromDirectory(const std::string &LibName,
const std::string &Directory,
std::vector<Module*> &Objects,
bool &isArchive) {
if (FileExists(Directory + "lib" + LibName + ".a")) {
// LoadLibraryExactName - This looks for a file with a known name and tries to
// load it, similarly to LoadLibraryFromDirectory().
static inline bool LoadLibraryExactName (const std::string &FileName,
std::vector<Module*> &Objects, bool &isArchive) {
if (Verbose) std::cerr << " Considering '" << FileName << "'\n";
if (FileExists(FileName)) {
if (IsArchive (FileName)) {
std::string ErrorMessage;
if (Verbose) std::cerr << " Loading '" << Directory << "lib"
<< LibName << ".a'\n";
if (!ReadArchiveFile(Directory + "lib" + LibName + ".a", Objects,
&ErrorMessage)) { // Read the archive file
if (Verbose) std::cerr << " Loading '" << FileName << "'\n";
if (!ReadArchiveFile(FileName, Objects, &ErrorMessage)) {
isArchive = true;
return false; // Success!
}
if (Verbose) {
std::cerr << " Error loading archive '" + Directory +"lib"+LibName+".a'";
std::cerr << " Error loading archive '" + FileName + "'";
if (!ErrorMessage.empty()) std::cerr << ": " << ErrorMessage;
std::cerr << "\n";
}
}
if (FileExists(Directory + "lib" + LibName + ".so"))
if (Module *M = LoadSingleLibraryObject(Directory + "lib" + LibName+".so")){
} else {
if (Module *M = LoadSingleLibraryObject(FileName)) {
isArchive = false;
Objects.push_back(M);
return false;
}
if (FileExists(Directory + "lib" + LibName + ".bc"))
if (Module *M = LoadSingleLibraryObject(Directory + "lib" + LibName+".bc")){
isArchive = false;
Objects.push_back(M);
return false;
}
}
return true;
}
// LoadLibrary - This searches for a .a, .so, or .bc file which provides the
// LLVM bytecode for the library. It returns true if no library is found,
// otherwise it puts the loaded modules into the Objects list, and sets
// isArchive to true if a .a file was loaded.
// LoadLibrary - Try to load a library named LIBNAME that contains
// LLVM bytecode. If SEARCH is true, then search for a file named
// libLIBNAME.{a,so,bc} in the current library search path. Otherwise,
// assume LIBNAME is the real name of the library file. This method puts
// the loaded modules into the Objects list, and sets isArchive to true if
// a .a file was loaded. It returns true if no library is found or if an
// error occurs; otherwise it returns false.
//
static inline bool LoadLibrary(const std::string &LibName,
std::vector<Module*> &Objects, bool &isArchive,
std::string &ErrorMessage) {
std::string Directory;
unsigned NextLibPathIdx = 0;
while (1) {
// Try loading from the current directory...
if (Verbose) std::cerr << " Looking in directory '" << Directory << "'\n";
if (!LoadLibraryFromDirectory(LibName, Directory, Objects, isArchive))
bool search, std::string &ErrorMessage) {
if (search) {
// First, try the current directory. Then, iterate over the
// directories in LibPaths, looking for a suitable match for LibName
// in each one.
for (unsigned NextLibPathIdx = 0; NextLibPathIdx != LibPaths.size();
++NextLibPathIdx) {
std::string Directory = LibPaths[NextLibPathIdx] + "/";
if (!LoadLibraryExactName(Directory + "lib" + LibName + ".a",
Objects, isArchive))
return false;
if (!LoadLibraryExactName(Directory + "lib" + LibName + ".so",
Objects, isArchive))
return false;
if (!LoadLibraryExactName(Directory + "lib" + LibName + ".bc",
Objects, isArchive))
return false;
}
} else {
// If they said no searching, then assume LibName is the real name.
if (!LoadLibraryExactName(LibName, Objects, isArchive))
return false;
if (NextLibPathIdx == LibPaths.size()) break;
Directory = LibPaths[NextLibPathIdx++]+"/";
}
ErrorMessage = "error linking library '-l" + LibName+ "': library not found!";
return true;
}
@ -231,7 +241,7 @@ static void GetAllUndefinedSymbols(Module *M,
static bool LinkLibrary(Module *M, const std::string &LibName,
std::string &ErrorMessage) {
bool search, std::string &ErrorMessage) {
std::set<std::string> UndefinedSymbols;
GetAllUndefinedSymbols(M, UndefinedSymbols);
if (UndefinedSymbols.empty()) {
@ -241,7 +251,8 @@ static bool LinkLibrary(Module *M, const std::string &LibName,
std::vector<Module*> Objects;
bool isArchive;
if (LoadLibrary(LibName, Objects, isArchive, ErrorMessage)) return true;
if (LoadLibrary(LibName, Objects, isArchive, search, ErrorMessage))
return true;
// Figure out which symbols are defined by all of the modules in the .a file
std::vector<std::set<std::string> > DefinedSymbols;
@ -307,11 +318,25 @@ int main(int argc, char **argv) {
if (Composite.get() == 0)
return PrintAndReturn(argv[0], ErrorMessage);
// We always look first in the current directory when searching for libraries.
LibPaths.insert(LibPaths.begin(), ".");
// If the user specied an extra search path in their environment, respect it.
if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
LibPaths.push_back(SearchPath);
for (unsigned i = 1; i < InputFilenames.size(); ++i) {
// A user may specify an ar archive without -l, perhaps because it
// is not installed as a library. Detect that and link the library.
if (IsArchive (InputFilenames[i])) {
if (Verbose) std::cerr << "Linking archive '" << InputFilenames[i]
<< "'\n";
if (LinkLibrary (Composite.get(), InputFilenames[i], false, ErrorMessage))
return PrintAndReturn(argv[0], ErrorMessage,
": error linking in '" + InputFilenames[i] + "'");
continue;
}
std::auto_ptr<Module> M(LoadObject(InputFilenames[i], ErrorMessage));
if (M.get() == 0)
return PrintAndReturn(argv[0], ErrorMessage);
@ -330,7 +355,7 @@ int main(int argc, char **argv) {
// Link in all of the libraries next...
for (unsigned i = 0; i != Libraries.size(); ++i) {
if (Verbose) std::cerr << "Linking in library: -l" << Libraries[i] << "\n";
if (LinkLibrary(Composite.get(), Libraries[i], ErrorMessage))
if (LinkLibrary(Composite.get(), Libraries[i], true, ErrorMessage))
return PrintAndReturn(argv[0], ErrorMessage);
}