[llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp gccld.cpp gccld.h
Reid Spencer
reid at x10sys.com
Mon Feb 28 00:45:46 PST 2005
Changes in directory llvm/tools/gccld:
GenerateCode.cpp updated: 1.43 -> 1.44
gccld.cpp updated: 1.96 -> 1.97
gccld.h updated: 1.12 -> 1.13
---
Log message:
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.
---
Diffs of the changes: (+182 -73)
GenerateCode.cpp | 91 ++++++++++++++++++++++++++++++++
gccld.cpp | 152 ++++++++++++++++++++++++++++++-------------------------
gccld.h | 12 +++-
3 files changed, 182 insertions(+), 73 deletions(-)
Index: llvm/tools/gccld/GenerateCode.cpp
diff -u llvm/tools/gccld/GenerateCode.cpp:1.43 llvm/tools/gccld/GenerateCode.cpp:1.44
--- llvm/tools/gccld/GenerateCode.cpp:1.43 Sun Feb 13 17:02:34 2005
+++ llvm/tools/gccld/GenerateCode.cpp Mon Feb 28 02:45:35 2005
@@ -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 @@
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::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 @@
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") {
Index: llvm/tools/gccld/gccld.cpp
diff -u llvm/tools/gccld/gccld.cpp:1.96 llvm/tools/gccld/gccld.cpp:1.97
--- llvm/tools/gccld/gccld.cpp:1.96 Sun Feb 13 17:02:34 2005
+++ llvm/tools/gccld/gccld.cpp Mon Feb 28 02:45:35 2005
@@ -83,11 +83,21 @@
cl::opt<bool>
NativeCBE("native-cbe",
cl::desc("Generate a native binary with the C backend and GCC"));
+
+ cl::opt<std::string>
+ RPath("rpath",
+ cl::desc("Set runtime shared library search path (requires -native or"
+ " -native-cbe)"),
+ cl::Prefix, cl::value_desc("directory"));
+
+ cl::opt<std::string>
+ SOName("soname",
+ cl::desc("Set internal name of shared library (requires -native or"
+ " -native-cbe)"),
+ cl::Prefix, cl::value_desc("name"));
// Compatibility options that are ignored but supported by LD
cl::opt<std::string>
- CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
- cl::opt<std::string>
CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
cl::opt<bool>
CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
@@ -237,7 +247,7 @@
// Create the output file.
std::string RealBytecodeOutput = OutputFilename;
- if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
+ if (!LinkAsLibrary || Native || NativeCBE) RealBytecodeOutput += ".bc";
std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
std::ios::binary;
std::ofstream Out(RealBytecodeOutput.c_str(), io_mode);
@@ -266,77 +276,83 @@
// Close the bytecode file.
Out.close();
- // If we are not linking a library, generate either a native executable
- // or a JIT shell script, depending upon what the user wants.
- if (!LinkAsLibrary) {
- // If the user wants to generate a native executable, compile it from the
- // bytecode file.
- //
- // Otherwise, create a script that will run the bytecode through the JIT.
- if (Native) {
- // Name of the Assembly Language output file
- sys::Path AssemblyFile ( OutputFilename);
- AssemblyFile.appendSuffix("s");
-
- // Mark the output files for removal if we get an interrupt.
- sys::RemoveFileOnSignal(AssemblyFile);
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
- // Determine the locations of the llc and gcc programs.
- sys::Path llc = FindExecutable("llc", argv[0]);
- if (llc.isEmpty())
- return PrintAndReturn(argv[0], "Failed to find llc");
-
- sys::Path gcc = FindExecutable("gcc", argv[0]);
- if (gcc.isEmpty())
- return PrintAndReturn(argv[0], "Failed to find gcc");
-
- // Generate an assembly language file for the bytecode.
- if (Verbose) std::cout << "Generating Assembly Code\n";
- GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput, llc);
- if (Verbose) std::cout << "Generating Native Code\n";
- GenerateNative(OutputFilename, AssemblyFile.toString(),
- Libraries, gcc, envp );
-
- // Remove the assembly language file.
- AssemblyFile.destroyFile();
- } else if (NativeCBE) {
- sys::Path CFile (OutputFilename);
- CFile.appendSuffix("cbe.c");
-
- // Mark the output files for removal if we get an interrupt.
- sys::RemoveFileOnSignal(CFile);
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
- // Determine the locations of the llc and gcc programs.
- sys::Path llc = FindExecutable("llc", argv[0]);
- if (llc.isEmpty())
- return PrintAndReturn(argv[0], "Failed to find llc");
-
- sys::Path gcc = FindExecutable("gcc", argv[0]);
- if (gcc.isEmpty())
- return PrintAndReturn(argv[0], "Failed to find gcc");
-
- // Generate an assembly language file for the bytecode.
- if (Verbose) std::cout << "Generating Assembly Code\n";
- GenerateCFile(CFile.toString(), RealBytecodeOutput, llc);
- if (Verbose) std::cout << "Generating Native Code\n";
- GenerateNative(OutputFilename, CFile.toString(), Libraries, gcc, envp );
-
- // Remove the assembly language file.
- CFile.destroyFile();
+ // Generate either a native file or a JIT shell script. If the user wants
+ // to generate a native file, compile it from the bytecode file. Otherwise,
+ // if the target is not a library, create a script that will run the
+ // bytecode through the JIT.
+ if (Native) {
+ // Name of the Assembly Language output file
+ sys::Path AssemblyFile (OutputFilename);
+ AssemblyFile.appendSuffix("s");
+
+ // Mark the output files for removal if we get an interrupt.
+ sys::RemoveFileOnSignal(AssemblyFile);
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ // Determine the locations of the llc and gcc programs.
+ sys::Path llc = FindExecutable("llc", argv[0]);
+ if (llc.isEmpty())
+ return PrintAndReturn(argv[0], "Failed to find llc");
+
+ sys::Path gcc = FindExecutable("gcc", argv[0]);
+ if (gcc.isEmpty())
+ return PrintAndReturn(argv[0], "Failed to find gcc");
+
+ // Generate an assembly language file for the bytecode.
+ if (Verbose) std::cout << "Generating Assembly Code\n";
+ GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput, llc);
+ if (Verbose) std::cout << "Generating Native Code\n";
+ GenerateNative(OutputFilename, AssemblyFile.toString(),
+ LibPaths, Libraries, gcc, envp, LinkAsLibrary, RPath,
+ SOName );
+
+ // Remove the assembly language file.
+ AssemblyFile.destroyFile();
+ // Remove the bytecode language file.
+ sys::Path(RealBytecodeOutput).destroyFile();
+
+ } else if (NativeCBE) {
+ sys::Path CFile (OutputFilename);
+ CFile.appendSuffix("cbe.c");
+
+ // Mark the output files for removal if we get an interrupt.
+ sys::RemoveFileOnSignal(CFile);
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ // Determine the locations of the llc and gcc programs.
+ sys::Path llc = FindExecutable("llc", argv[0]);
+ if (llc.isEmpty())
+ return PrintAndReturn(argv[0], "Failed to find llc");
+
+ sys::Path gcc = FindExecutable("gcc", argv[0]);
+ if (gcc.isEmpty())
+ return PrintAndReturn(argv[0], "Failed to find gcc");
+
+ // Generate an assembly language file for the bytecode.
+ if (Verbose) std::cout << "Generating Assembly Code\n";
+ GenerateCFile(CFile.toString(), RealBytecodeOutput, llc);
+ if (Verbose) std::cout << "Generating Native Code\n";
+ GenerateNative(OutputFilename, CFile.toString(),
+ LibPaths, Libraries, gcc, envp, LinkAsLibrary, RPath,
+ SOName );
- } else {
- EmitShellScript(argv);
- }
+ // Remove the assembly language file.
+ CFile.destroyFile();
- // Make the script executable...
- sys::Path(OutputFilename).makeExecutable();
+ // Remove the bytecode language file.
+ sys::Path(RealBytecodeOutput).destroyFile();
- // Make the bytecode file readable and directly executable in LLEE as well
+ } else if (!LinkAsLibrary) {
+ EmitShellScript(argv);
+
+ // Make the bytecode file readable and directly executable in LLEE
sys::Path(RealBytecodeOutput).makeExecutable();
sys::Path(RealBytecodeOutput).makeReadable();
}
+
+ // Make the output, whether native or script, executable as well...
+ sys::Path(OutputFilename).makeExecutable();
+
} catch (const char*msg) {
std::cerr << argv[0] << ": " << msg << "\n";
exitCode = 1;
Index: llvm/tools/gccld/gccld.h
diff -u llvm/tools/gccld/gccld.h:1.12 llvm/tools/gccld/gccld.h:1.13
--- llvm/tools/gccld/gccld.h:1.12 Mon Dec 13 22:20:07 2004
+++ llvm/tools/gccld/gccld.h Mon Feb 28 02:45:35 2005
@@ -31,13 +31,19 @@
const std::string & InputFilename,
const sys::Path & llc);
-int GenerateCFile(const std::string &OutputFile, const std::string &InputFile,
- const sys::Path &llc);
+int
+GenerateCFile (const std::string &OutputFile,
+ const std::string &InputFile,
+ const sys::Path &llc);
int
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);
+ char ** const envp,
+ bool Shared,
+ const std::string & RPath,
+ const std::string & SOName);
} // End llvm namespace
More information about the llvm-commits
mailing list