Skip to content

Commit 19b9514

Browse files
committed
Change how libraries are specified to the linker
- remove the platform specifics from computeLibraryArgs, we now just use LIBRARY_PREFIX and remove any suffix for searchPathFlagsForLD, and moved this into the LinkerSpec.LibrarySpecifier extension, this allows for proper searching of libraries, and linking of dynamic libraries on Windows.
1 parent 469349f commit 19b9514

File tree

20 files changed

+101
-175
lines changed

20 files changed

+101
-175
lines changed

Sources/SWBCore/Settings/BuiltinMacros.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ public final class BuiltinMacros {
685685
public static let EXECUTABLE_DEBUG_DYLIB_MAPPED_PLATFORM = BuiltinMacros.declareStringMacro("EXECUTABLE_DEBUG_DYLIB_MAPPED_PLATFORM")
686686
public static let EXECUTABLE_BLANK_INJECTION_DYLIB_PATH = BuiltinMacros.declareStringMacro("EXECUTABLE_BLANK_INJECTION_DYLIB_PATH")
687687

688+
public static let EXECUTABLE_PREFIX = BuiltinMacros.declareStringMacro("EXECUTABLE_PREFIX")
688689
public static let EXECUTABLE_SUFFIX = BuiltinMacros.declareStringMacro("EXECUTABLE_SUFFIX")
689690
public static let EXECUTABLE_VARIANT_SUFFIX = BuiltinMacros.declareStringMacro("EXECUTABLE_VARIANT_SUFFIX")
690691
public static let EXPORTED_SYMBOLS_FILE = BuiltinMacros.declarePathMacro("EXPORTED_SYMBOLS_FILE")
@@ -1764,6 +1765,7 @@ public final class BuiltinMacros {
17641765
EXECUTABLE_DEBUG_DYLIB_MAPPED_INSTALL_NAME,
17651766
EXECUTABLE_DEBUG_DYLIB_MAPPED_PLATFORM,
17661767
EXECUTABLE_BLANK_INJECTION_DYLIB_PATH,
1768+
EXECUTABLE_PREFIX,
17671769
EXECUTABLE_SUFFIX,
17681770
EXECUTABLE_VARIANT_SUFFIX,
17691771
EXCLUDED_ARCHS,

Sources/SWBCore/SpecImplementations/LinkerSpec.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ open class LinkerSpec : CommandLineToolSpec, @unchecked Sendable {
8989
/// The path to the privacy file, if one exists.
9090
public let privacyFile: Path?
9191

92-
public init(kind: Kind, path: Path, mode: Mode, useSearchPaths: Bool, swiftModulePaths: [String: Path], swiftModuleAdditionalLinkerArgResponseFilePaths: [String: Path], explicitDependencies: [Path] = [], topLevelItemPath: Path? = nil, dsymPath: Path? = nil, xcframeworkSourcePath: Path? = nil, privacyFile: Path? = nil) {
92+
public let libPrefix: String
93+
94+
public init(kind: Kind, path: Path, mode: Mode, useSearchPaths: Bool, swiftModulePaths: [String: Path], swiftModuleAdditionalLinkerArgResponseFilePaths: [String: Path], refSettings: Settings? = nil, explicitDependencies: [Path] = [], topLevelItemPath: Path? = nil, dsymPath: Path? = nil, xcframeworkSourcePath: Path? = nil, privacyFile: Path? = nil) {
9395
self.kind = kind
9496
self.path = path
9597
self.mode = mode
@@ -101,6 +103,13 @@ open class LinkerSpec : CommandLineToolSpec, @unchecked Sendable {
101103
self.dsymPath = dsymPath
102104
self.xcframeworkSourcePath = xcframeworkSourcePath
103105
self.privacyFile = privacyFile
106+
let prefix = refSettings?.globalScope.evaluate(BuiltinMacros.EXECUTABLE_PREFIX) ?? ""
107+
#if os(Windows)
108+
let default_prefix = ""
109+
#else
110+
let default_prefix = "lib"
111+
#endif
112+
self.libPrefix = prefix == "" ? default_prefix : prefix
104113
}
105114
}
106115

Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,41 +1289,12 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
12891289
private static func computeLibraryArgs(_ libraries: [LibrarySpecifier], scope: MacroEvaluationScope) -> (args: [String], inputs: [Path]) {
12901290
// Construct the library arguments.
12911291
return libraries.compactMap { specifier -> (args: [String], inputs: [Path]) in
1292-
let basename = specifier.path.basename
1293-
1294-
// FIXME: This isn't a good system, we need to redesign how we talk to the linker w.r.t. search paths and our notion of paths.
12951292
switch specifier.kind {
1296-
case .static:
1297-
if specifier.useSearchPaths, basename.hasPrefix("lib"), basename.hasSuffix(".a") {
1298-
return (specifier.searchPathFlagsForLd(basename.withoutPrefix("lib").withoutSuffix(".a")), [])
1299-
}
1300-
return (specifier.absolutePathFlagsForLd(), [specifier.path])
1301-
case .dynamic:
1302-
let suffix = ".\(scope.evaluate(BuiltinMacros.DYNAMIC_LIBRARY_EXTENSION))"
1303-
if specifier.useSearchPaths, basename.hasPrefix("lib"), basename.hasSuffix(suffix) {
1304-
return (specifier.searchPathFlagsForLd(basename.withoutPrefix("lib").withoutSuffix(suffix)), [])
1305-
}
1306-
return (specifier.absolutePathFlagsForLd(), [specifier.path])
1307-
case .textBased:
1308-
if specifier.useSearchPaths, basename.hasPrefix("lib"), basename.hasSuffix(".tbd") {
1309-
// .merge and .reexport are not supported for text-based libraries.
1310-
return (specifier.searchPathFlagsForLd(basename.withoutPrefix("lib").withoutSuffix(".tbd")), [])
1311-
}
1312-
return (specifier.absolutePathFlagsForLd(), [specifier.path])
1313-
case .framework:
1314-
let frameworkName = Path(basename).withoutSuffix
1293+
case .static, .dynamic, .textBased, .framework:
13151294
if specifier.useSearchPaths {
1316-
return (specifier.searchPathFlagsForLd(frameworkName), [])
1317-
}
1318-
let absPathArgs = specifier.absolutePathFlagsForLd()
1319-
let returnPath: Path
1320-
if let pathArg = absPathArgs.last, Path(pathArg).basename == frameworkName {
1321-
returnPath = Path(pathArg)
1322-
}
1323-
else {
1324-
returnPath = specifier.path
1295+
return (specifier.searchPathFlagsForLd(), [])
13251296
}
1326-
return (absPathArgs, [returnPath])
1297+
return (specifier.absolutePathFlagsForLd(), [specifier.path])
13271298
case .object:
13281299
// Object files are added to linker inputs in the sources task producer.
13291300
return ([], [])
@@ -1559,35 +1530,41 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
15591530

15601531
/// Extensions to `LinkerSpec.LibrarySpecifier` specific to the dynamic linker.
15611532
fileprivate extension LinkerSpec.LibrarySpecifier {
1562-
func searchPathFlagsForLd(_ name: String) -> [String] {
1533+
func searchPathFlagsForLd() -> [String] {
1534+
let strippedName: String
1535+
if path.basename.hasPrefix(libPrefix) {
1536+
strippedName = Path(path.basename).withoutSuffix.withoutPrefix(libPrefix)
1537+
} else {
1538+
strippedName = Path(path.basename).withoutSuffix
1539+
}
15631540
switch (kind, mode) {
15641541
case (.dynamic, .normal):
1565-
return ["-l" + name]
1542+
return ["-l" + strippedName]
15661543
case (.dynamic, .reexport):
1567-
return ["-Xlinker", "-reexport-l" + name]
1544+
return ["-Xlinker", "-reexport-l" + strippedName]
15681545
case (.dynamic, .merge):
1569-
return ["-Xlinker", "-merge-l" + name]
1546+
return ["-Xlinker", "-merge-l" + strippedName]
15701547
case (.dynamic, .reexport_merge):
1571-
return ["-Xlinker", "-no_merge-l" + name]
1548+
return ["-Xlinker", "-no_merge-l" + strippedName]
15721549
case (.dynamic, .weak):
1573-
return ["-weak-l" + name]
1550+
return ["-weak-l" + strippedName]
15741551
case (.static, .weak),
15751552
(.textBased, .weak):
1576-
return ["-weak-l" + name]
1553+
return ["-weak-l" + strippedName]
15771554
case (.static, _),
15781555
(.textBased, _):
15791556
// Other modes are not supported for these kinds.
1580-
return ["-l" + name]
1557+
return ["-l" + strippedName]
15811558
case (.framework, .normal):
1582-
return ["-framework", name]
1559+
return ["-framework", strippedName]
15831560
case (.framework, .reexport):
1584-
return ["-Xlinker", "-reexport_framework", "-Xlinker", name]
1561+
return ["-Xlinker", "-reexport_framework", "-Xlinker", strippedName]
15851562
case (.framework, .merge):
1586-
return ["-Xlinker", "-merge_framework", "-Xlinker", name]
1563+
return ["-Xlinker", "-merge_framework", "-Xlinker", strippedName]
15871564
case (.framework, .reexport_merge):
1588-
return ["-Xlinker", "-no_merge_framework", "-Xlinker", name]
1565+
return ["-Xlinker", "-no_merge_framework", "-Xlinker", strippedName]
15891566
case (.framework, .weak):
1590-
return ["-weak_framework", name]
1567+
return ["-weak_framework", strippedName]
15911568
case (.object, _):
15921569
// Object files are added to linker inputs in the sources task producer.
15931570
return []
@@ -1724,9 +1701,9 @@ public final class LibtoolLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @u
17241701
delegate.warning("Product \(cbc.output.basename) cannot weak-link \(specifier.kind) \(basename)")
17251702
}
17261703

1727-
if specifier.useSearchPaths, basename.hasPrefix("lib"), basename.hasSuffix(".a") {
1704+
if specifier.useSearchPaths {
17281705
// Locate using search paths: Add a -l option and *don't* add the path to the library as an input to the task.
1729-
return ["-l" + basename.withoutPrefix("lib").withoutSuffix(".a")]
1706+
return specifier.searchPathFlagsForLd()
17301707
}
17311708
else {
17321709
// Locate using an absolute path: Add the path as an option and as an input to the task.

Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/SourcesTaskProducer.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
506506
useSearchPaths: useSearchPaths,
507507
swiftModulePaths: swiftModulePaths,
508508
swiftModuleAdditionalLinkerArgResponseFilePaths: swiftModuleAdditionalLinkerArgResponseFilePaths,
509+
refSettings: settingsForRef,
509510
privacyFile: privacyFile
510511
)
511512
} else if fileType.conformsTo(context.lookupFileType(identifier: "compiled.mach-o.dylib")!) {
@@ -516,6 +517,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
516517
useSearchPaths: useSearchPaths,
517518
swiftModulePaths: [:],
518519
swiftModuleAdditionalLinkerArgResponseFilePaths: [:],
520+
refSettings: settingsForRef,
519521
privacyFile: privacyFile
520522
)
521523
} else if fileType.conformsTo(context.lookupFileType(identifier: "sourcecode.text-based-dylib-definition")!) {
@@ -526,6 +528,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
526528
useSearchPaths: useSearchPaths,
527529
swiftModulePaths: [:],
528530
swiftModuleAdditionalLinkerArgResponseFilePaths: [:],
531+
refSettings: settingsForRef,
529532
privacyFile: privacyFile
530533
)
531534
} else if fileType.conformsTo(context.lookupFileType(identifier: "wrapper.framework")!) {
@@ -571,6 +574,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
571574
useSearchPaths: useSearchPaths,
572575
swiftModulePaths: [:],
573576
swiftModuleAdditionalLinkerArgResponseFilePaths: [:],
577+
refSettings: settingsForRef,
574578
topLevelItemPath: topLevelItemPath,
575579
dsymPath: dsymPath,
576580
privacyFile: privacyFile
@@ -580,7 +584,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
580584
kind: .object,
581585
path: absolutePath,
582586
mode: buildFile.shouldLinkWeakly ? .weak : .normal,
583-
useSearchPaths: useSearchPaths,
587+
useSearchPaths: false,
584588
swiftModulePaths: swiftModulePaths,
585589
swiftModuleAdditionalLinkerArgResponseFilePaths: swiftModuleAdditionalLinkerArgResponseFilePaths,
586590
privacyFile: privacyFile

Sources/SWBUniversalPlatform/Specs/ProductTypes.xcspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
8383
MACH_O_TYPE = "mh_dylib";
8484
REZ_EXECUTABLE = YES;
85+
EXECUTABLE_PREFIX = "lib";
8586
EXECUTABLE_SUFFIX = ".$(EXECUTABLE_EXTENSION)";
8687
EXECUTABLE_EXTENSION = "$(DYNAMIC_LIBRARY_EXTENSION:default=dylib)";
8788
PUBLIC_HEADERS_FOLDER_PATH = "/usr/local/include";

Sources/SWBWindowsPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ struct WindowsSDKRegistryExtension: SDKRegistryExtension {
170170
"GENERATE_INTERMEDIATE_TEXT_BASED_STUBS": "NO",
171171

172172
"LIBRARY_SEARCH_PATHS": "$(inherited) $(SDKROOT)/usr/lib/swift/windows/$(CURRENT_ARCH)",
173-
"TEST_LIBRARY_SEARCH_PATHS": .plString("\(testingLibraryPath.strWithPosixSlashes)/Testing-$(SWIFT_TESTING_VERSION)/usr/lib/swift/windows/$(CURRENT_ARCH) \(testingLibraryPath.strWithPosixSlashes)/XCTest-$(XCTEST_VERSION)/usr/lib/swift/windows/$(CURRENT_ARCH)"),
173+
"TEST_LIBRARY_SEARCH_PATHS": .plString("\(testingLibraryPath.strWithPosixSlashes)/Testing-$(SWIFT_TESTING_VERSION)/usr/lib/swift/windows/ \(testingLibraryPath.strWithPosixSlashes)/Testing-$(SWIFT_TESTING_VERSION)/usr/lib/swift/windows/$(CURRENT_ARCH) \(testingLibraryPath.strWithPosixSlashes)/XCTest-$(XCTEST_VERSION)/usr/lib/swift/windows/$(CURRENT_ARCH) \(testingLibraryPath.strWithPosixSlashes)/XCTest-$(XCTEST_VERSION)/usr/lib/swift/windows"),
174174
"OTHER_SWIFT_FLAGS": "$(inherited) -libc $(DEFAULT_USE_RUNTIME)",
175175

176176
"DEFAULT_USE_RUNTIME": "MD",

0 commit comments

Comments
 (0)