1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Implement linking.

llvm-svn: 17297
This commit is contained in:
Reid Spencer 2004-10-28 04:05:06 +00:00
parent 9274b7af51
commit ec563c71fd

View File

@ -95,7 +95,13 @@ namespace {
cleanup();
cdp = 0;
LibraryPaths.clear();
IncludePaths.clear();
Defines.clear();
TempDir.clear();
AdditionalArgs.clear();
fOptions.clear();
MOptions.clear();
WOptions.clear();
}
/// @}
@ -183,7 +189,8 @@ namespace {
}
}
sys::Path MakeTempFile(const std::string& basename, const std::string& suffix ) {
sys::Path MakeTempFile(const std::string& basename,
const std::string& suffix ) {
sys::Path result(TempDir);
if (!result.append_file(basename))
throw basename + ": can't use this file name";
@ -231,7 +238,8 @@ namespace {
// Get specific options for each kind of action type
StringVector& addargs = AdditionalArgs[phase];
// Add specific options for each kind of action type
action->args.insert(action->args.end(), addargs.begin(), addargs.end());
action->args.insert(action->args.end(), addargs.begin(),
addargs.end());
}
} else
found = false;
@ -248,10 +256,7 @@ namespace {
found = false;
break;
case 'f':
if (*PI == "%force%") {
if (isSet(FORCE_FLAG))
action->args.push_back("-f");
} else if (*PI == "%fOpts%") {
if (*PI == "%fOpts%") {
action->args.insert(action->args.end(), fOptions.begin(),
fOptions.end());
} else
@ -288,7 +293,8 @@ namespace {
if (!isSet(EMIT_RAW_FLAG)) {
if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
!cd->opts[optLevel].empty())
action->args.insert(action->args.end(), cd->opts[optLevel].begin(),
action->args.insert(action->args.end(),
cd->opts[optLevel].begin(),
cd->opts[optLevel].end());
else
throw std::string("Optimization options for level ") +
@ -365,21 +371,28 @@ namespace {
if (isSet(VERBOSE_FLAG))
WriteAction(action);
if (!isSet(DRY_RUN_FLAG)) {
action->program = sys::Program::FindProgramByName(action->program.get());
if (action->program.is_empty())
throw std::string("Can't find program '") + action->program.get() + "'";
sys::Path progpath = sys::Program::FindProgramByName(
action->program.get());
if (progpath.is_empty())
throw std::string("Can't find program '"+progpath.get()+"'");
else if (progpath.executable())
action->program = progpath;
else
throw std::string("Program '"+progpath.get()+"' is not executable.");
// Invoke the program
if (isSet(TIME_ACTIONS_FLAG)) {
Timer timer(action->program.get());
timer.startTimer();
int resultCode = sys::Program::ExecuteAndWait(action->program,action->args);
int resultCode =
sys::Program::ExecuteAndWait(action->program,action->args);
timer.stopTimer();
timer.print(timer,std::cerr);
return resultCode == 0;
}
else
return 0 == sys::Program::ExecuteAndWait(action->program, action->args);
return 0 ==
sys::Program::ExecuteAndWait(action->program, action->args);
}
return true;
}
@ -441,7 +454,8 @@ namespace {
// If we didn't find the file in any of the library search paths
// so we have to bail. No where else to look.
if (fullpath.is_empty()) {
err = std::string("Can't find linkage item '") + link_item.get() + "'";
err =
std::string("Can't find linkage item '") + link_item.get() + "'";
return false;
}
} else {
@ -473,8 +487,9 @@ namespace {
++LI;
}
} else if (err.empty()) {
err = std::string("The dependent libraries could not be extracted from '")
+ fullpath.get();
err = std::string(
"The dependent libraries could not be extracted from '") +
fullpath.get();
return false;
}
}
@ -497,12 +512,12 @@ namespace {
std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
std::cerr << "ForceOutput = " << isSet(FORCE_FLAG) << "\n";
std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
std::cerr << "OutputMachine = " << machine << "\n";
InputList::const_iterator I = InpList.begin();
while ( I != InpList.end() ) {
std::cerr << "Input: " << I->first.get() << "(" << I->second << ")\n";
std::cerr << "Input: " << I->first.get() << "(" << I->second
<< ")\n";
++I;
}
std::cerr << "Output: " << Output.get() << "\n";
@ -521,8 +536,7 @@ namespace {
// If they are not asking for linking, provided an output file and
// there is more than one input file, its an error
if (finalPhase != LINKING && !Output.is_empty() &&
InpList.size() > 1)
if (finalPhase != LINKING && !Output.is_empty() && InpList.size() > 1)
throw std::string("An output file name cannot be specified ") +
"with more than one input file name when not linking";
@ -533,7 +547,6 @@ namespace {
// for each input item
SetVector<sys::Path> LinkageItems;
std::vector<std::string> LibFiles;
sys::Path OutFile(Output);
InputList::const_iterator I = InpList.begin();
while ( I != InpList.end() ) {
// Get the suffix of the file name
@ -566,8 +579,9 @@ namespace {
if (isSet(DEBUG_FLAG))
DumpConfigData(cd,I->second);
// Initialize the input file
// Initialize the input and output files
sys::Path InFile(I->first);
sys::Path OutFile(I->first.get_basename());
// PRE-PROCESSING PHASE
Action& action = cd->PreProcessor;
@ -576,14 +590,12 @@ namespace {
if (!action.program.is_empty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
if (finalPhase == PREPROCESSING) {
if (OutFile.is_empty()) {
OutFile = I->first;
OutFile.append_suffix("E");
}
actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
} else {
sys::Path TempFile(MakeTempFile(I->first.get(),"E"));
actions.push_back(GetAction(cd,InFile,TempFile,PREPROCESSING));
sys::Path TempFile(MakeTempFile(I->first.get_basename(),"E"));
actions.push_back(GetAction(cd,InFile,TempFile,
PREPROCESSING));
InFile = TempFile;
}
}
@ -594,7 +606,8 @@ namespace {
cd->langName + " files";
}
// Short-circuit remaining actions if all they want is pre-processing
// Short-circuit remaining actions if all they want is
// pre-processing
if (finalPhase == PREPROCESSING) { ++I; continue; };
/// TRANSLATION PHASE
@ -604,13 +617,10 @@ namespace {
if (!action.program.is_empty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
if (finalPhase == TRANSLATION) {
if (OutFile.is_empty()) {
OutFile = I->first;
OutFile.append_suffix("o");
}
actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
} else {
sys::Path TempFile(MakeTempFile(I->first.get(),"trans"));
sys::Path TempFile(MakeTempFile(I->first.get_basename(),"trans"));
actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
InFile = TempFile;
}
@ -646,13 +656,10 @@ namespace {
if (!action.program.is_empty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
if (finalPhase == OPTIMIZATION) {
if (OutFile.is_empty()) {
OutFile = I->first;
OutFile.append_suffix("o");
}
actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
} else {
sys::Path TempFile(MakeTempFile(I->first.get(),"opt"));
sys::Path TempFile(MakeTempFile(I->first.get_basename(),"opt"));
actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
InFile = TempFile;
}
@ -692,10 +699,7 @@ namespace {
action->args.push_back(InFile.get());
action->args.push_back("-f");
action->args.push_back("-o");
if (OutFile.is_empty()) {
OutFile = I->first;
OutFile.append_suffix("s");
}
action->args.push_back(OutFile.get());
} else {
// Just convert back to llvm assembly with llvm-dis
@ -704,6 +708,7 @@ namespace {
action->args.push_back(InFile.get());
action->args.push_back("-f");
action->args.push_back("-o");
OutFile.append_suffix("ll");
action->args.push_back(OutFile.get());
actions.push_back(action);
}
@ -731,11 +736,12 @@ namespace {
/// LINKING PHASE
if (finalPhase == LINKING) {
// Insert the platform-specific system libraries to the path list
LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1());
LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2());
// We're emitting native code so let's build an gccld Action
// Set up the linking action with llvm-ld
Action* link = new Action();
link->program.set_file("llvm-ld");
@ -777,6 +783,11 @@ namespace {
E=LibraryPaths.end(); I != E; ++I)
link->args.push_back( std::string("-L") + I->get());
// Add in the additional linker arguments requested
for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
E=AdditionalArgs[LINKING].end(); I != E; ++I)
link->args.push_back( *I );
// Add in other optional flags
if (isSet(EMIT_NATIVE_FLAG))
link->args.push_back("-native");
@ -795,7 +806,7 @@ namespace {
// Add in mandatory flags
link->args.push_back("-o");
link->args.push_back(OutFile.get());
link->args.push_back(Output.get());
// Execute the link
if (!DoAction(link))