Add switch '-Xcc <ccflag>'. Fix #2093. (#2104)

This commit is contained in:
Adrian Matoga 2017-05-16 20:23:02 +02:00 committed by kinke
parent 3d7e4c0036
commit aafd6541c7
4 changed files with 67 additions and 21 deletions

View file

@ -355,21 +355,38 @@ static int linkObjToBinaryGcc(bool sharedLib) {
if (opts::isUsingLTO())
addLTOLinkFlags(args);
// additional linker switches
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
const char *p = (*global.params.linkswitches)[i];
// Don't push -l and -L switches using -Xlinker, but pass them indirectly
// via GCC. This makes sure user-defined paths take precedence over
// GCC's builtin LIBRARY_PATHs.
// Options starting with `-Wl,`, -shared or -static are not handled by
// the linker and must be passed to the driver.
auto str = llvm::StringRef(p);
if (!(str.startswith("-l") || str.startswith("-L") ||
str.startswith("-Wl,") ||
str.startswith("-shared") || str.startswith("-static"))) {
args.push_back("-Xlinker");
// additional linker and cc switches (preserve order across both lists)
for (unsigned ilink = 0, icc = 0;;) {
unsigned linkpos = ilink < opts::linkerSwitches.size()
? opts::linkerSwitches.getPosition(ilink)
: std::numeric_limits<unsigned>::max();
unsigned ccpos = icc < opts::ccSwitches.size()
? opts::ccSwitches.getPosition(icc)
: std::numeric_limits<unsigned>::max();
if (linkpos < ccpos) {
const std::string& p = opts::linkerSwitches[ilink++];
// Don't push -l and -L switches using -Xlinker, but pass them indirectly
// via GCC. This makes sure user-defined paths take precedence over
// GCC's builtin LIBRARY_PATHs.
// Options starting with `-Wl,`, -shared or -static are not handled by
// the linker and must be passed to the driver.
auto str = llvm::StringRef(p);
if (!(str.startswith("-l") || str.startswith("-L") ||
str.startswith("-Wl,") ||
str.startswith("-shared") || str.startswith("-static"))) {
args.push_back("-Xlinker");
}
args.push_back(p);
} else if (ccpos < linkpos) {
args.push_back(opts::ccSwitches[icc++]);
} else {
break;
}
args.push_back(p);
}
// libs added via pragma(lib, libname)
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
args.push_back((*global.params.linkswitches)[i]);
}
// default libs
@ -518,6 +535,11 @@ static void addMscrtLibs(std::vector<std::string> &args) {
static int linkObjToBinaryMSVC(bool sharedLib) {
Logger::println("*** Linking executable ***");
if (!opts::ccSwitches.empty()) {
error(Loc(), "-Xcc is not supported for MSVC");
fatal();
}
#ifdef _WIN32
windows::setupMsvcEnvironment();
#endif
@ -584,8 +606,7 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
CreateDirectoryOnDisk(gExePath);
// additional linker switches
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
std::string str = global.params.linkswitches->data[i];
auto addSwitch = [&](std::string str) {
if (str.length() > 2) {
// rewrite common -L and -l switches
if (str[0] == '-' && str[1] == 'L') {
@ -595,6 +616,14 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
}
}
args.push_back(str);
};
for (const auto& str : opts::linkerSwitches) {
addSwitch(str);
}
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) {
addSwitch(global.params.linkswitches->data[i]);
}
// default libs