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

@ -284,11 +284,13 @@ cl::list<std::string> transitions(
"Help with language change identified by <idents>, use ? for list"),
cl::value_desc("idents"), cl::CommaSeparated);
static StringsAdapter linkSwitchStore("L", global.params.linkswitches);
static cl::list<std::string, StringsAdapter>
linkerSwitches("L", cl::desc("Pass <linkerflag> to the linker"),
cl::value_desc("linkerflag"), cl::location(linkSwitchStore),
cl::Prefix);
cl::list<std::string> linkerSwitches("L",
cl::desc("Pass <linkerflag> to the linker"),
cl::value_desc("linkerflag"), cl::Prefix);
cl::list<std::string> ccSwitches("Xcc", cl::CommaSeparated,
cl::desc("Pass <ccflag> to GCC/Clang for linking"),
cl::value_desc("ccflag"));
cl::opt<std::string>
moduleDeps("deps",

View file

@ -66,6 +66,8 @@ extern cl::list<std::string> versions;
extern cl::list<std::string> transitions;
extern cl::opt<std::string> moduleDeps;
extern cl::opt<std::string> cacheDir;
extern cl::list<std::string> linkerSwitches;
extern cl::list<std::string> ccSwitches;
extern cl::opt<std::string> mArch;
extern cl::opt<bool> m32bits;

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

View file

@ -0,0 +1,13 @@
// Test if global order of flags passed with -Xcc, -L and pragma(lib) is preserved
// UNSUPPORTED: Windows
// RUN: /bin/sh -c '%ldc %s -of=%t -Xcc -DOPT1,-DOPT2 -L-L/usr/lib -L--defsym -Lfoo=5 -Xcc -DOPT3 -v 2>/dev/null || true' | FileCheck %s
// CHECK: -DOPT1 -DOPT2 -L/usr/lib -Xlinker --defsym -Xlinker foo=5 -DOPT3 {{.*}}-lpthread
pragma(lib, "pthread");
void main()
{
}