Skip to content

Commit 9636cc0

Browse files
Improve usability of -l flag (#795)
Matching Swift PR: swiftlang/swift#38750
1 parent cba79ca commit 9636cc0

9 files changed

+72
-10
lines changed

Sources/SwiftDriver/Jobs/CommandLineArguments.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,17 @@ extension Array where Element == Job.ArgTemplate {
149149
}
150150
}
151151

152+
/// Append all parsed options from the given groups except from excludeList to this command line.
153+
mutating func appendAllExcept(includeList: [Option.Group], excludeList: [Option], from parsedOptions: inout ParsedOptions) throws {
154+
for group in includeList{
155+
for optGroup in parsedOptions.arguments(in: group){
156+
if !excludeList.contains(where: {$0 == optGroup.option}) {
157+
try append(optGroup)
158+
}
159+
}
160+
}
161+
}
162+
152163
/// Append the last of the given flags that appears in the parsed options,
153164
/// or the flag that corresponds to the default value if neither
154165
/// appears.

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,12 @@ extension DarwinToolchain {
422422

423423
// These custom arguments should be right before the object file at the
424424
// end.
425-
try commandLine.append(
426-
contentsOf: parsedOptions.arguments(in: .linkerOption)
425+
try commandLine.appendAllExcept(
426+
includeList: [.linkerOption],
427+
excludeList: [.l],
428+
from: &parsedOptions
427429
)
430+
addLinkedLibArgs(to: &commandLine, parsedOptions: &parsedOptions)
428431
try commandLine.appendAllArguments(.Xlinker, from: &parsedOptions)
429432
}
430433
}

Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,12 @@ extension GenericUnixToolchain {
274274

275275
// These custom arguments should be right before the object file at the
276276
// end.
277-
try commandLine.append(
278-
contentsOf: parsedOptions.arguments(in: .linkerOption)
277+
try commandLine.appendAllExcept(
278+
includeList: [.linkerOption],
279+
excludeList: [.l],
280+
from: &parsedOptions
279281
)
282+
addLinkedLibArgs(to: &commandLine, parsedOptions: &parsedOptions)
280283
// Because we invoke `clang` as the linker executable, we must still
281284
// use `-Xlinker` for linker-specific arguments.
282285
for linkerOpt in parsedOptions.arguments(for: .Xlinker) {

Sources/SwiftDriver/Jobs/InterpretJob.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ extension Driver {
3131
// FIXME: MSVC runtime flags
3232

3333
try commandLine.appendLast(.parseSil, from: &parsedOptions)
34-
try commandLine.appendAll(.l, .framework, from: &parsedOptions)
34+
toolchain.addLinkedLibArgs(to: &commandLine, parsedOptions: &parsedOptions)
35+
try commandLine.appendAll(.framework, from: &parsedOptions)
3536

3637
// The immediate arguments must be last.
3738
try commandLine.appendLast(.DASHDASH, from: &parsedOptions)

Sources/SwiftDriver/Jobs/ReplJob.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ extension Driver {
1919
// FIXME: MSVC runtime flags
2020

2121
try commandLine.appendLast(.importObjcHeader, from: &parsedOptions)
22-
try commandLine.appendAll(.l, .framework, .L, from: &parsedOptions)
22+
toolchain.addLinkedLibArgs(
23+
to: &commandLine,
24+
parsedOptions: &parsedOptions
25+
)
26+
try commandLine.appendAll(.framework, .L, from: &parsedOptions)
2327

2428
// Squash important frontend options into a single argument for LLDB.
2529
let lldbCommandLine: [Job.ArgTemplate] = [.squashedArgumentList(option: "--repl=", args: commandLine)]

Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ extension Toolchain {
8686
).appending(component: runtimeName)
8787
return try fileSystem.exists(path)
8888
}
89+
90+
func addLinkedLibArgs(
91+
to commandLine: inout [Job.ArgTemplate],
92+
parsedOptions: inout ParsedOptions
93+
) {
94+
for match in parsedOptions.arguments(for: .l) {
95+
commandLine.appendFlag(match.option.spelling + match.argument.asSingle)
96+
}
97+
}
8998
}
9099

91100
// MARK: - Common argument routines

Sources/SwiftDriver/Jobs/WebAssemblyToolchain+LinkerSupport.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,12 @@ extension WebAssemblyToolchain {
139139

140140
// These custom arguments should be right before the object file at the
141141
// end.
142-
try commandLine.append(
143-
contentsOf: parsedOptions.arguments(in: .linkerOption)
142+
try commandLine.appendAllExcept(
143+
includeList: [.linkerOption],
144+
excludeList: [.l],
145+
from: &parsedOptions
144146
)
147+
addLinkedLibArgs(to: &commandLine, parsedOptions: &parsedOptions)
145148
try commandLine.appendAllArguments(.Xlinker, from: &parsedOptions)
146149
try commandLine.appendAllArguments(.XclangLinker, from: &parsedOptions)
147150

Sources/SwiftOptions/Options.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ extension Option {
389389
public static let ltoLibrary: Option = Option("-lto-library", .separate, attributes: [.frontend, .argumentIsPath], metaVar: "<lto-library>", helpText: "Perform LTO with <lto-library>")
390390
public static let lto: Option = Option("-lto=", .joined, attributes: [.frontend, .noInteractive], helpText: "Specify the LTO type to either 'llvm-thin' or 'llvm-full'")
391391
public static let L: Option = Option("-L", .joinedOrSeparate, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], helpText: "Add directory to library link search path", group: .linkerOption)
392-
public static let l: Option = Option("-l", .joined, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Specifies a library which should be linked against", group: .linkerOption)
392+
public static let l: Option = Option("-l", .joinedOrSeparate, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Specifies a library which should be linked against", group: .linkerOption)
393393
public static let mergeModules: Option = Option("-merge-modules", .flag, attributes: [.frontend, .noDriver], helpText: "Merge the input modules without otherwise processing them", group: .modes)
394394
public static let migrateKeepObjcVisibility: Option = Option("-migrate-keep-objc-visibility", .flag, attributes: [.frontend, .noInteractive], helpText: "When migrating, add '@objc' to declarations that would've been implicitly visible in Swift 3")
395395
public static let migratorUpdateSdk: Option = Option("-migrator-update-sdk", .flag, attributes: [.frontend, .noInteractive], helpText: "Does nothing. Temporary compatibility flag for Xcode.")

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ final class SwiftDriverTests: XCTestCase {
10161016
env["SWIFT_DRIVER_DSYMUTIL_EXEC"] = "/garbage/dsymutil"
10171017

10181018
let commonArgs = ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test"]
1019+
10191020
do {
10201021
// macOS target
10211022
var driver = try Driver(args: commonArgs + ["-emit-library", "-target", "x86_64-apple-macosx10.15"], env: env)
@@ -1456,6 +1457,16 @@ final class SwiftDriverTests: XCTestCase {
14561457
XCTAssertFalse(cmd.contains(.flag("-shared")))
14571458
}
14581459
}
1460+
1461+
do {
1462+
// Linker flags with and without space
1463+
var driver = try Driver(args: commonArgs + ["-lsomelib","-l","otherlib"], env: env)
1464+
let plannedJobs = try driver.planBuild()
1465+
let cmd = plannedJobs.last!.commandLine
1466+
XCTAssertTrue(cmd.contains(.flag("-lsomelib")))
1467+
XCTAssertTrue(cmd.contains(.flag("-lotherlib")))
1468+
}
1469+
14591470
}
14601471

14611472
func testWebAssemblyUnsupportedFeatures() throws {
@@ -2346,6 +2357,20 @@ final class SwiftDriverTests: XCTestCase {
23462357
XCTAssertEqual(error as? PlanningError, .replReceivedInput)
23472358
}
23482359
}
2360+
2361+
do {
2362+
// Linked library arguments with space
2363+
var driver = try Driver(args: ["swift", "-repl", "-l", "somelib", "-lotherlib"])
2364+
let plannedJobs = try driver.planBuild()
2365+
XCTAssertEqual(plannedJobs.count, 1)
2366+
let cmd = plannedJobs.first!.commandLine
2367+
guard case let .squashedArgumentList(option: _, args: args) = cmd[0] else {
2368+
XCTFail()
2369+
return
2370+
}
2371+
XCTAssertTrue(args.contains(.flag("-lsomelib")))
2372+
XCTAssertTrue(args.contains(.flag("-lotherlib")))
2373+
}
23492374
}
23502375

23512376
func testInstallAPI() throws {
@@ -2411,7 +2436,7 @@ final class SwiftDriverTests: XCTestCase {
24112436
}
24122437

24132438
do {
2414-
var driver = try Driver(args: ["swift", "-L/path/to/lib", "-F/path/to/framework", "foo.swift"])
2439+
var driver = try Driver(args: ["swift", "-L/path/to/lib", "-F/path/to/framework", "-lsomelib", "-l", "otherlib", "foo.swift"])
24152440
let plannedJobs = try driver.planBuild()
24162441
XCTAssertEqual(plannedJobs.count, 1)
24172442
let job = plannedJobs[0]
@@ -2425,6 +2450,9 @@ final class SwiftDriverTests: XCTestCase {
24252450
if driver.targetTriple.isDarwin {
24262451
XCTAssertTrue(job.extraEnvironment.contains { $0 == "DYLD_FRAMEWORK_PATH" && $1.contains("/path/to/framework") })
24272452
}
2453+
2454+
XCTAssertTrue(job.commandLine.contains(.flag("-lsomelib")))
2455+
XCTAssertTrue(job.commandLine.contains(.flag("-lotherlib")))
24282456
}
24292457
}
24302458

0 commit comments

Comments
 (0)