Skip to content
Merged
8 changes: 8 additions & 0 deletions include/swift/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ class ToolChain {
const Driver &getDriver() const { return D; }
const llvm::Triple &getTriple() const { return Triple; }

/// Special handling for passing down '-l' arguments.
///
/// Not all downstream tools (lldb, ld etc.) consistently accept
/// a space between the '-l' flag and its argument, so we remove
/// the extra space if it was present in \c Args.
static void addLinkedLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &FrontendArgs);

/// Construct a Job for the action \p JA, taking the given information into
/// account.
///
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ def libc : Separate<["-"], "libc">, HelpText<"libc runtime library to use">;

def linker_option_Group : OptionGroup<"<linker-specific options>">;

def l : Joined<["-"], "l">, Group<linker_option_Group>,
def l : JoinedOrSeparate<["-"], "l">, Group<linker_option_Group>,
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
HelpText<"Specifies a library which should be linked against">;
def framework : Separate<["-"], "framework">, Group<linker_option_Group>,
Expand Down
4 changes: 3 additions & 1 deletion lib/Driver/DarwinToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,9 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
Arguments.push_back("-no_objc_category_merging");

// These custom arguments should be right before the object file at the end.
context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
context.Args.AddAllArgsExcept(Arguments, {options::OPT_linker_option_Group},
{options::OPT_l});
ToolChain::addLinkedLibArgs(context.Args, Arguments);
context.Args.AddAllArgValues(Arguments, options::OPT_Xlinker);

// This should be the last option, for convenience in checking output.
Expand Down
9 changes: 9 additions & 0 deletions lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ mergeBatchInputs(ArrayRef<const Job *> jobs,
return false;
}

void ToolChain::addLinkedLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &FrontendArgs) {
Args.getLastArg(options::OPT_l);
for (auto Arg : Args.getAllArgValues(options::OPT_l)) {
const std::string lArg("-l" + Arg);
FrontendArgs.push_back(Args.MakeArgString(Twine(lArg)));
}
}

/// Construct a \c BatchJob by merging the constituent \p jobs' CommandOutput,
/// input \c Job and \c Action members. Call through to \c constructInvocation
/// on \p BatchJob, to build the \c InvocationInfo.
Expand Down
8 changes: 5 additions & 3 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static void addLTOArgs(const OutputInfo &OI, ArgStringList &arguments) {
}
}


void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
const CommandOutput &output,
const ArgList &inputArgs,
Expand Down Expand Up @@ -842,7 +843,8 @@ ToolChain::constructInvocation(const InterpretJobAction &job,
Arguments.push_back("-module-name");
Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName));

context.Args.AddAllArgs(Arguments, options::OPT_l, options::OPT_framework);
context.Args.AddAllArgs(Arguments, options::OPT_framework);
ToolChain::addLinkedLibArgs(context.Args, Arguments);

// The immediate arguments must be last.
context.Args.AddLastArg(Arguments, options::OPT__DASH_DASH);
Expand Down Expand Up @@ -1190,8 +1192,8 @@ ToolChain::constructInvocation(const REPLJobAction &job,
addRuntimeLibraryFlags(context.OI, FrontendArgs);

context.Args.AddLastArg(FrontendArgs, options::OPT_import_objc_header);
context.Args.AddAllArgs(FrontendArgs, options::OPT_l, options::OPT_framework,
options::OPT_L);
context.Args.AddAllArgs(FrontendArgs, options::OPT_framework, options::OPT_L);
ToolChain::addLinkedLibArgs(context.Args, FrontendArgs);

if (!useLLDB) {
FrontendArgs.insert(FrontendArgs.begin(), {"-frontend", "-repl"});
Expand Down
4 changes: 3 additions & 1 deletion lib/Driver/UnixToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,9 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
}

// These custom arguments should be right before the object file at the end.
context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
context.Args.AddAllArgsExcept(Arguments, {options::OPT_linker_option_Group},
{options::OPT_l});
ToolChain::addLinkedLibArgs(context.Args, Arguments);
context.Args.AddAllArgs(Arguments, options::OPT_Xlinker);
context.Args.AddAllArgValues(Arguments, options::OPT_Xclang_linker);

Expand Down
4 changes: 3 additions & 1 deletion lib/Driver/WindowsToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
}

context.Args.AddAllArgs(Arguments, options::OPT_Xlinker);
context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
context.Args.AddAllArgsExcept(Arguments, {options::OPT_linker_option_Group},
{options::OPT_l});
ToolChain::addLinkedLibArgs(context.Args, Arguments);
context.Args.AddAllArgValues(Arguments, options::OPT_Xclang_linker);

// Run clang in verbose mode if "-v" is set
Expand Down
18 changes: 18 additions & 0 deletions test/Driver/linker-library-with-space.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target x86_64-unknown-linux-gnu -Ffoo -Fsystem car -F cdr -framework bar -Lbaz -lboo -Xlinker -undefined %s 2>&1 > %t.linux.txt
// RUN: %FileCheck -check-prefix LINUX-lib-flag-space %s < %t.linux.txt

// LINUX-lib-flag-space: swift
// LINUX-lib-flag-space: -o [[OBJECTFILE:.*]]

// LINUX-lib-flag-space: clang{{(\.exe)?"? }}
// LINUX-lib-flag-space-DAG: -pie
// LINUX-lib-flag-space-DAG: [[OBJECTFILE]]
// LINUX-lib-flag-space-DAG: -lswiftCore
// LINUX-lib-flag-space-DAG: -L [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)]]
// LINUX-lib-flag-space-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]]
// LINUX-lib-flag-space-DAG: -F foo -iframework car -F cdr
// LINUX-lib-flag-space-DAG: -framework bar
// LINUX-lib-flag-space-DAG: -L baz
// LINUX-lib-flag-space-DAG: -lboo
// LINUX-lib-flag-space-DAG: -Xlinker -undefined
// LINUX-lib-flag-space: -o main
2 changes: 2 additions & 0 deletions test/Driver/linker.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Must be able to run xcrun-return-self.sh
// REQUIRES: shell
// REQUIRES: rdar65281056
// FIXME: When this is turned on, please move the test from linker-library-with-space.swift
// to this file and remove that file.
// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target x86_64-apple-macosx10.9 %s 2>&1 > %t.simple.txt
// RUN: %FileCheck %s < %t.simple.txt
// RUN: %FileCheck -check-prefix SIMPLE %s < %t.simple.txt
Expand Down
3 changes: 2 additions & 1 deletion test/Driver/options-repl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


// RUN: %swift_driver -sdk "" -lldb-repl -### | %FileCheck -check-prefix=LLDB %s
// RUN: %swift_driver -sdk "" -lldb-repl -D A -DB -D C -DD -L /path/to/libraries -L /path/to/more/libraries -F /path/to/frameworks -lsomelib -framework SomeFramework -sdk / -I "this folder" -module-name Test -target %target-triple -### | %FileCheck -check-prefix=LLDB-OPTS %s
// RUN: %swift_driver -sdk "" -lldb-repl -D A -DB -D C -DD -L /path/to/libraries -L /path/to/more/libraries -F /path/to/frameworks -lsomelib -l otherlib -framework SomeFramework -sdk / -I "this folder" -module-name Test -target %target-triple -### | %FileCheck -check-prefix=LLDB-OPTS %s

// LLDB: lldb{{(\.exe)?"?}} {{"?}}--repl=
// LLDB-NOT: -module-name
Expand All @@ -30,6 +30,7 @@
// LLDB-OPTS-DAG: -L /path/to/more/libraries
// LLDB-OPTS-DAG: -F /path/to/frameworks
// LLDB-OPTS-DAG: -lsomelib
// LLDB-OPTS-DAG: -lotherlib
// LLDB-OPTS-DAG: -framework SomeFramework
// LLDB-OPTS-DAG: -I \"this folder\"
// LLDB-OPTS: "
Expand Down