diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2005-02-28 08:45:35 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2005-02-28 08:45:35 +0000 |
commit | 837149c08da7d9015c5dcfa9f62110ce14e5b949 (patch) | |
tree | f65f9293fa934d2ed13523787c5b9abf0fb846ca /tools/gccld/GenerateCode.cpp | |
parent | f8b235dd8f01b0957d69476ee31556d2ec0638b7 (diff) |
Changes to enable creation of native executables directly from gccld and to
ensure that -L paths don't contain both bytecode and native libraries.
This patch contributed by Adam Treat.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20370 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/gccld/GenerateCode.cpp')
-rw-r--r-- | tools/gccld/GenerateCode.cpp | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/tools/gccld/GenerateCode.cpp b/tools/gccld/GenerateCode.cpp index 1d4c5205cf..a75d6f1cd8 100644 --- a/tools/gccld/GenerateCode.cpp +++ b/tools/gccld/GenerateCode.cpp @@ -20,6 +20,7 @@ #include "llvm/Analysis/LoadValueNumbering.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Bytecode/Archive.h" #include "llvm/Bytecode/WriteBytecodePass.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/IPO.h" @@ -127,6 +128,62 @@ static inline void addPass(PassManager &PM, Pass *P) { if (Verify) PM.add(createVerifierPass()); } +static bool isBytecodeLibrary(const sys::Path &FullPath) { + // Check for a bytecode file + if (FullPath.isBytecodeFile()) return true; + // Check for a dynamic library file + if (FullPath.isDynamicLibrary()) return false; + // Check for a true bytecode archive file + if (FullPath.isArchive() ) { + std::string ErrorMessage; + Archive* ar = Archive::OpenAndLoadSymbols( FullPath, &ErrorMessage ); + return ar->isBytecodeArchive(); + } + return false; +} + +static bool isBytecodeLPath(const std::string &LibPath) { + bool isBytecodeLPath = false; + + // Make sure the -L path has a '/' character + // because llvm-g++ passes them without the ending + // '/' char and sys::Path doesn't think it is a + // directory (see: sys::Path::isDirectory) without it + std::string dir = LibPath; + if ( dir[dir.length()-1] != '/' ) + dir.append("/"); + + sys::Path LPath(dir); + + // Grab the contents of the -L path + std::set<sys::Path> Files; + LPath.getDirectoryContents(Files); + + // Iterate over the contents one by one to determine + // if this -L path has any bytecode shared libraries + // or archives + std::set<sys::Path>::iterator File = Files.begin(); + for (; File != Files.end(); ++File) { + + if ( File->isDirectory() ) + continue; + + std::string path = File->toString(); + std::string dllsuffix = sys::Path::GetDLLSuffix(); + + // Check for an ending '.dll,.so' or '.a' suffix as all + // other files are not of interest to us here + if ( path.find(dllsuffix, path.size()-dllsuffix.size()) == std::string::npos + && path.find(".a", path.size()-2) == std::string::npos ) + continue; + + // Finally, check to see if the file is a true bytecode file + if (isBytecodeLibrary(*File)) + isBytecodeLPath = true; + } + return isBytecodeLPath; +} + /// GenerateBytecode - generates a bytecode file from the specified module. /// /// Inputs: @@ -285,8 +342,12 @@ int llvm::GenerateCFile(const std::string &OutputFile, /// int llvm::GenerateNative(const std::string &OutputFilename, const std::string &InputFilename, + const std::vector<std::string> &LibPaths, const std::vector<std::string> &Libraries, - const sys::Path &gcc, char ** const envp) { + const sys::Path &gcc, char ** const envp, + bool Shared, + const std::string &RPath, + const std::string &SOName) { // Remove these environment variables from the environment of the // programs that we will execute. It appears that GCC sets these // environment variables so that the programs it uses can configure @@ -316,7 +377,33 @@ int llvm::GenerateNative(const std::string &OutputFilename, args.push_back("-o"); args.push_back(OutputFilename.c_str()); args.push_back(InputFilename.c_str()); - + + if (Shared) args.push_back("-shared"); + if (!RPath.empty()) { + std::string rp = "-Wl,-rpath," + RPath; + args.push_back(rp.c_str()); + } + if (!SOName.empty()) { + std::string so = "-Wl,-soname," + SOName; + args.push_back(so.c_str()); + } + + // Add in the libpaths to find the libraries. + // + // Note: + // When gccld is called from the llvm-gxx frontends, the -L paths for + // the LLVM cfrontend install paths are appended. We don't want the + // native linker to use these -L paths as they contain bytecode files. + // Further, we don't want any -L paths that contain bytecode shared + // libraries or true bytecode archive files. We omit them in all such + // cases. + for (unsigned index = 0; index < LibPaths.size(); index++) { + if (!isBytecodeLPath( LibPaths[index]) ) { + args.push_back("-L"); + args.push_back(LibPaths[index].c_str()); + } + } + // Add in the libraries to link. for (unsigned index = 0; index < Libraries.size(); index++) { if (Libraries[index] != "crtend") { |