Link using gcc instead.

This commit is contained in:
Christian Kamm
2008-10-11 21:21:21 +02:00
parent 1bfc0316aa
commit ee407e597a
4 changed files with 137 additions and 2 deletions

View File

@@ -1165,7 +1165,7 @@ int main(int argc, char *argv[], char** envp)
{
if (global.params.link)
//status = runLINK();
linkExecutable(global.params.argv0);
linkObjToExecutable(global.params.argv0);
if (global.params.run)
{

View File

@@ -197,6 +197,133 @@ int linkExecutable(const char* argv0)
//////////////////////////////////////////////////////////////////////////////
int linkObjToExecutable(const char* argv0)
{
Logger::println("*** Linking executable ***");
// error string
std::string errstr;
// find gcc for linking
llvm::sys::Path gcc = llvm::sys::Program::FindProgramByName("gcc");
if (gcc.isEmpty())
{
gcc.set("gcc");
}
// build arguments
std::vector<const char*> args;
// first the program name ??
args.push_back("gcc");
// output filename
std::string exestr;
if (global.params.exefile)
{ // explicit
exestr = global.params.exefile;
}
else
{ // inferred
// try root module name
if (Module::rootModule)
exestr = Module::rootModule->toChars();
else
exestr = "a.out";
}
if (global.params.os == OSWindows)
exestr.append(".exe");
args.push_back("-o");
args.push_back(exestr.c_str());
// set the global gExePath
gExePath.set(exestr);
assert(gExePath.isValid());
// create path to exe
llvm::sys::Path exedir(gExePath);
exedir.set(gExePath.getDirname());
if (!exedir.exists())
{
exedir.createDirectoryOnDisk(true, &errstr);
if (!errstr.empty())
{
error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str());
fatal();
}
}
// additional linker switches
for (int i = 0; i < global.params.linkswitches->dim; i++)
{
char *p = (char *)global.params.linkswitches->data[i];
args.push_back(p);
}
// user libs
for (int i = 0; i < global.params.libfiles->dim; i++)
{
char *p = (char *)global.params.libfiles->data[i];
args.push_back(p);
}
// default libs
switch(global.params.os) {
case OSLinux:
case OSMacOSX:
args.push_back("-ldl");
case OSFreeBSD:
args.push_back("-lpthread");
args.push_back("-lm");
break;
case OSWindows:
// FIXME: I'd assume kernel32 etc
break;
}
// object files
for (int i = 0; i < global.params.objfiles->dim; i++)
{
char *p = (char *)global.params.objfiles->data[i];
args.push_back(p);
}
// print link command?
if (!global.params.quiet || global.params.verbose)
{
// Print it
for (int i = 0; i < args.size(); i++)
printf("%s ", args[i]);
printf("\n");
fflush(stdout);
}
Logger::println("Linking with: ");
std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
std::ostream& logstr = Logger::cout();
for (; I != E; ++I)
if (*I)
logstr << "'" << *I << "'" << " ";
logstr << "\n" << std::flush;
// terminate args list
args.push_back(NULL);
// try to call linker!!!
if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr))
{
error("linking failed:\nstatus: %d", status);
if (!errstr.empty())
error("message: %s", errstr.c_str());
fatal();
}
}
//////////////////////////////////////////////////////////////////////////////
void deleteExecutable()
{
if (!gExePath.isEmpty())

View File

@@ -22,6 +22,13 @@ void linkModules(llvm::Module* dst, const std::vector<llvm::Module*>& MV);
*/
int linkExecutable(const char* argv0);
/**
* Link an executable only from object files.
* @param argv0 the argv[0] value as passed to main
* @return 0 on success.
*/
int linkObjToExecutable(const char* argv0);
/**
* Delete the executable that was previously linked with linkExecutable.
*/

View File

@@ -420,7 +420,8 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, ch
args.push_back("-o");
args.push_back(objpath.toString());
//TODO: Add other options, like -fpic
//FIXME: only use this if needed?
args.push_back("-fpic");
// Now that "args" owns all the std::strings for the arguments, call the c_str
// method to get the underlying string array. We do this game so that the