Skip to content

Commit

Permalink
Add -linker-path frontend option to choose the linker
Browse files Browse the repository at this point in the history
In most Linux distributions, installing a clang package other than the
default unversioned one will not install a symlink from /usr/bin/clang++
-> /usr/bin/clang++-N-M, which can break builds with a not so great
diagnostic (a separate problem).

"ld" and "clang++" are hard-coded in the link job actions, so provide a
frontend flag, -linker-path, as a customization point for these.

rdar://problem/23537079
  • Loading branch information
bitjammer committed Nov 13, 2015
1 parent 4defeb9 commit 58cfa27
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
5 changes: 5 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ def resource_dir : Separate<["-"], "resource-dir">,
MetaVarName<"</usr/lib/swift>">,
HelpText<"The directory that holds the compiler resource files">;

def linker_path : Separate<["-"], "linker-path">,
Flags<[FrontendOption, HelpHidden]>,
MetaVarName<"<arg>">,
HelpText<"The path to the linker or C++ driver to use for linking">;

def target : Separate<["-"], "target">,
Flags<[FrontendOption, ModuleWrapOption]>,
HelpText<"Generate code for the given target">;
Expand Down
10 changes: 8 additions & 2 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,10 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
Arguments.push_back("-o");
Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str());

return std::make_pair("ld", Arguments);
auto Linker = "ld";
if (auto *Arg = context.Args.getLastArg(options::OPT_linker_path))
Linker = Arg->getValue();
return std::make_pair(Linker, Arguments);
}

#if defined(SWIFT_ENABLE_TARGET_LINUX)
Expand Down Expand Up @@ -1043,7 +1046,10 @@ toolchains::Linux::constructInvocation(const LinkJobAction &job,
Arguments.push_back("-o");
Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str());

return std::make_pair("clang++", Arguments);
auto Linker = "clang++";
if (auto *Arg = context.Args.getLastArg(options::OPT_linker_path))
Linker = Arg->getValue();
return std::make_pair(Linker, Arguments);
}

#endif // SWIFT_ENABLE_TARGET_LINUX
Expand Down
15 changes: 15 additions & 0 deletions test/Driver/linker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,21 @@
// RELATIVE_ARCLITE: /DISTINCTIVE-PATH/usr/lib/arc/libarclite_macosx.a
// RELATIVE_ARCLITE: -o {{[^ ]+}}

// RUN: %t/DISTINCTIVE-PATH/usr/bin/swiftc -target x86_64-apple-macosx10.9 %s -### | FileCheck -check-prefix=APPLE-LINKER %s
// APPLE-LINKER: /usr/bin/ld
// APPLE-LINKER-NOT: /path/to/my/linker

// RUN: %t/DISTINCTIVE-PATH/usr/bin/swiftc -linker-path /path/to/my/linker -target x86_64-apple-macosx10.9 %s -### | FileCheck -check-prefix=APPLE-LINKER-OVERRIDE %s
// APPLE-LINKER-OVERRIDE: /path/to/my/linker
// APPLE-LINKER-OVERRIDE-NOT: /usr/bin/ld

// RUN: %t/DISTINCTIVE-PATH/usr/bin/swiftc -target x86_64-unknown-linux-gnu %s -### | FileCheck -check-prefix=LINUX-LINKER %s
// LINUX-LINKER: clang++
// LINUX-LINKER-NOT: /path/to/my/linker

// RUN: %t/DISTINCTIVE-PATH/usr/bin/swiftc -linker-path /path/to/my/linker -target x86_64-unknown-linux-gnu %s -### | FileCheck -check-prefix=LINUX-LINKER-OVERRIDE %s
// LINUX-LINKER-OVERRIDE: /path/to/my/linker
// LINUX-LINKER-OVERRIDE-NOT: clang++

// Clean up the test executable because hard links are expensive.
// RUN: rm -rf %t/DISTINCTIVE-PATH/usr/bin/swiftc
Expand Down

0 comments on commit 58cfa27

Please sign in to comment.