Skip to content

Improve usability of -l flag #38750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 27, 2021
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