[PECOFF] Move files with ".lib" extension to the end of the input file list.

It's allowed to specify library files *before* object files in the command
line. Object files seems to be processed first, and then their undefined
symbols are resolved from the libraries. This patch implements the compatible
behavior.

llvm-svn: 195295
This commit is contained in:
Rui Ueyama 2013-11-21 01:08:53 +00:00
parent 5383e81a7f
commit dae2ef47f1
2 changed files with 30 additions and 2 deletions

View File

@ -13,6 +13,7 @@
///
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <cctype>
#include <sstream>
#include <map>
@ -600,6 +601,8 @@ WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
defaultLibs.push_back((*it)->getValue());
}
std::vector<StringRef> inputFiles;
// Process all the arguments and create Input Elements
for (auto inputArg : *parsedArgs) {
switch (inputArg->getOption().getID()) {
@ -850,8 +853,7 @@ WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
break;
case OPT_INPUT:
inputElements.push_back(std::unique_ptr<InputElement>(
new PECOFFFileNode(ctx, ctx.allocate(inputArg->getValue()))));
inputFiles.push_back(ctx.allocate(inputArg->getValue()));
break;
#define DEFINE_BOOLEAN_FLAG(name, setter) \
@ -877,6 +879,17 @@ WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
}
}
// Move files with ".lib" extension at the end of the input file list. Say
// foo.obj depends on bar.lib. The linker needs to accept both "bar.lib
// foo.obj" and "foo.obj bar.lib".
auto compfn = [](StringRef a, StringRef b) {
return !a.endswith_lower(".lib") && b.endswith_lower(".lib");
};
std::stable_sort(inputFiles.begin(), inputFiles.end(), compfn);
for (StringRef path : inputFiles)
inputElements.push_back(std::unique_ptr<InputElement>(
new PECOFFFileNode(ctx, path)));
// Use the default entry name if /entry option is not given.
if (ctx.entrySymbolName().empty())
ctx.setEntrySymbolName(getDefaultEntrySymbolName(ctx));

View File

@ -130,6 +130,21 @@ TEST_F(WinLinkParserTest, Libpath) {
EXPECT_EQ("dir2", paths[1]);
}
//
// Tests for input file order
//
TEST_F(WinLinkParserTest, InputOrder) {
EXPECT_TRUE(parse("link.exe", "b.lib", "b.obj", "c.obj", "a.lib", "a.obj",
nullptr));
EXPECT_EQ(5, inputFileCount());
EXPECT_EQ("b.obj", inputFile(0));
EXPECT_EQ("c.obj", inputFile(1));
EXPECT_EQ("a.obj", inputFile(2));
EXPECT_EQ("b.lib", inputFile(3));
EXPECT_EQ("a.lib", inputFile(4));
}
//
// Tests for command line options that take values.
//