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:
parent
9274b7af51
commit
ec563c71fd
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user