mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-14 11:53:13 +01:00
Link using gcc instead.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
127
gen/linker.cpp
127
gen/linker.cpp
@@ -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())
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user