[llvm-commits] CVS: llvm/tools/gccld/gccld.cpp

John Criswell criswell at cs.uiuc.edu
Tue Sep 16 16:28:01 PDT 2003


Changes in directory llvm/tools/gccld:

gccld.cpp updated: 1.45 -> 1.46

---
Log message:

Added the -native option.
With this option, gccld links the program into LLVM bytecode and a native code
binary.  This allows llvmgcc to correctly tell GNU configure scripts when
things aren't defined properly (because the native link will fail).


---
Diffs of the changes:

Index: llvm/tools/gccld/gccld.cpp
diff -u llvm/tools/gccld/gccld.cpp:1.45 llvm/tools/gccld/gccld.cpp:1.46
--- llvm/tools/gccld/gccld.cpp:1.45	Fri Sep  5 14:23:03 2003
+++ llvm/tools/gccld/gccld.cpp	Tue Sep 16 16:27:35 2003
@@ -30,6 +30,9 @@
 #include <set>
 #include <algorithm>
 
+// This is the environment given to the program.
+extern char ** environ;
+
 namespace {
   cl::list<std::string> 
   InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
@@ -64,6 +67,9 @@
   LinkAsLibrary("link-as-library", cl::desc("Link the .bc files together as a"
                                             " library, not an executable"));
 
+  cl::opt<bool>    
+  Native("native", cl::desc("Generate a native binary instead of a shell script"));
+  
   // Compatibility options that are ignored, but support by LD
   cl::opt<std::string>
   CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
@@ -313,6 +319,69 @@
   return 1;
 }
 
+//
+// Function: remove_env()
+//
+// Description:
+//	Remove the specified environment variable from the environment array.
+//
+// Inputs:
+//	name - The name of the variable to remove.  It cannot be NULL.
+//	envp - The array of environment variables.  It cannot be NULL.
+//
+// Outputs:
+//	envp - The pointer to the specified variable name is removed.
+//
+// Return value:
+//	None.
+//
+// Notes:
+//  This is mainly done because functions to remove items from the environment
+//  are not available across all platforms.  In particular, Solaris does not
+//  seem to have an unsetenv() function or a setenv() function (or they are
+//  undocumented if they do exist).
+//
+static void
+remove_env (const char * name, char ** envp)
+{
+  // Pointer for scanning arrays
+  register char * p;
+
+  // Index for selecting elements of the environment array
+  register int index;
+
+  for (index=0; envp[index] != NULL; index++)
+  {
+    //
+    // Find the first equals sign in the array and make it an EOS character.
+    //
+    p = strchr (envp[index], '=');
+    if (p == NULL)
+    {
+      continue;
+    }
+    else
+    {
+      *p = '\0';
+    }
+
+    //
+    // Compare the two strings.  If they are equal, zap this string.
+    // Otherwise, restore it.
+    //
+    if (!strcmp (name, envp[index]))
+    {
+      envp[index] = NULL;
+    }
+    else
+    {
+      *p = '=';
+    }
+  }
+
+  return;
+}
+
 
 int main(int argc, char **argv) {
   cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");
@@ -432,13 +501,62 @@
   Out.close();
 
   if (!LinkAsLibrary) {
-    // Output the script to start the program...
-    std::ofstream Out2(OutputFilename.c_str());
-    if (!Out2.good())
-      return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
-                                     "' for writing!");
-    Out2 << "#!/bin/sh\nlli -q $0.bc $*\n";
-    Out2.close();
+    //
+    // 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 output assembly file
+      std::string AssemblyFile = OutputFilename + ".s";
+
+      // Name of the command to execute
+      std::string cmd;
+
+      //
+      // Create an executable file from the bytecode file.
+      //
+      remove_env ("LIBRARY_PATH", environ);
+      remove_env ("COLLECT_GCC_OPTIONS", environ);
+      remove_env ("GCC_EXEC_PREFIX", environ);
+      remove_env ("COMPILER_PATH", environ);
+      remove_env ("COLLECT_GCC", environ);
+
+      //
+      // Run LLC to convert the bytecode file into assembly code.
+      //
+      cmd = "llc -f -o " + AssemblyFile + " " + RealBytecodeOutput;
+      if ((system (cmd.c_str())) == -1)
+      {
+        return PrintAndReturn (argv[0], "Failed to compile bytecode");
+      }
+
+      //
+      // Run GCC to assemble and link the program into native code.
+      //
+      // Note:
+      //  We can't just assemble and link the file with the system assembler
+      //  and linker because we don't know where to put the _start symbol.
+      //  GCC mysteriously knows how to do it.
+      //
+      cmd = "gcc -o " + OutputFilename + " " + AssemblyFile;
+      if ((system (cmd.c_str())) == -1)
+      {
+        return PrintAndReturn (argv[0], "Failed to link native code file");
+      }
+    }
+    else
+    {
+      // Output the script to start the program...
+      std::ofstream Out2(OutputFilename.c_str());
+      if (!Out2.good())
+        return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
+                                       "' for writing!");
+      Out2 << "#!/bin/sh\nlli -q $0.bc $*\n";
+      Out2.close();
+    }
   
     // Make the script executable...
     MakeFileExecutable (OutputFilename);





More information about the llvm-commits mailing list