@@ -1289,41 +1289,15 @@ 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+ let args = specifier. searchPathFlagsForLd ( )
1296+ if !args. isEmpty { // no search args, fallback to absolute path to library
1297+ return ( args, [ ] )
1298+ }
13251299 }
1326- return ( absPathArgs , [ returnPath ] )
1300+ return ( specifier . absolutePathFlagsForLd ( ) , [ specifier . path ] )
13271301 case . object:
13281302 // Object files are added to linker inputs in the sources task producer.
13291303 return ( [ ] , [ ] )
@@ -1559,35 +1533,44 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
15591533
15601534/// Extensions to `LinkerSpec.LibrarySpecifier` specific to the dynamic linker.
15611535fileprivate extension LinkerSpec . LibrarySpecifier {
1562- func searchPathFlagsForLd( _ name: String ) -> [ String ] {
1536+ func searchPathFlagsForLd( ) -> [ String ] {
1537+ let strippedName : String
1538+ if let prefix = libPrefix, path. basename. hasPrefix ( prefix) {
1539+ strippedName = Path ( path. basename) . withoutSuffix. withoutPrefix ( prefix)
1540+ } else {
1541+ if libPrefix != nil { // we need a prefix for linking with search paths
1542+ return [ ] // this will fallback to using absolute paths
1543+ }
1544+ strippedName = Path ( path. basename) . withoutSuffix
1545+ }
15631546 switch ( kind, mode) {
15641547 case ( . dynamic, . normal) :
1565- return [ " -l " + name ]
1548+ return [ " -l " + strippedName ]
15661549 case ( . dynamic, . reexport) :
1567- return [ " -Xlinker " , " -reexport-l " + name ]
1550+ return [ " -Xlinker " , " -reexport-l " + strippedName ]
15681551 case ( . dynamic, . merge) :
1569- return [ " -Xlinker " , " -merge-l " + name ]
1552+ return [ " -Xlinker " , " -merge-l " + strippedName ]
15701553 case ( . dynamic, . reexport_merge) :
1571- return [ " -Xlinker " , " -no_merge-l " + name ]
1554+ return [ " -Xlinker " , " -no_merge-l " + strippedName ]
15721555 case ( . dynamic, . weak) :
1573- return [ " -weak-l " + name ]
1556+ return [ " -weak-l " + strippedName ]
15741557 case ( . static, . weak) ,
15751558 ( . textBased, . weak) :
1576- return [ " -weak-l " + name ]
1559+ return [ " -weak-l " + strippedName ]
15771560 case ( . static, _) ,
15781561 ( . textBased, _) :
15791562 // Other modes are not supported for these kinds.
1580- return [ " -l " + name ]
1563+ return [ " -l " + strippedName ]
15811564 case ( . framework, . normal) :
1582- return [ " -framework " , name ]
1565+ return [ " -framework " , strippedName ]
15831566 case ( . framework, . reexport) :
1584- return [ " -Xlinker " , " -reexport_framework " , " -Xlinker " , name ]
1567+ return [ " -Xlinker " , " -reexport_framework " , " -Xlinker " , strippedName ]
15851568 case ( . framework, . merge) :
1586- return [ " -Xlinker " , " -merge_framework " , " -Xlinker " , name ]
1569+ return [ " -Xlinker " , " -merge_framework " , " -Xlinker " , strippedName ]
15871570 case ( . framework, . reexport_merge) :
1588- return [ " -Xlinker " , " -no_merge_framework " , " -Xlinker " , name ]
1571+ return [ " -Xlinker " , " -no_merge_framework " , " -Xlinker " , strippedName ]
15891572 case ( . framework, . weak) :
1590- return [ " -weak_framework " , name ]
1573+ return [ " -weak_framework " , strippedName ]
15911574 case ( . object, _) :
15921575 // Object files are added to linker inputs in the sources task producer.
15931576 return [ ]
@@ -1724,15 +1707,17 @@ public final class LibtoolLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @u
17241707 delegate. warning ( " Product \( cbc. output. basename) cannot weak-link \( specifier. kind) \( basename) " )
17251708 }
17261709
1727- if specifier. useSearchPaths, basename . hasPrefix ( " lib " ) , basename . hasSuffix ( " .a " ) {
1710+ if specifier. useSearchPaths {
17281711 // 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 " ) ]
1730- }
1731- else {
1732- // Locate using an absolute path: Add the path as an option and as an input to the task.
1733- inputPaths. append ( specifier. path)
1734- return [ specifier. path. str]
1712+ let basename = specifier. path. basename
1713+ let expectedPrefix = specifier. libPrefix ?? " lib "
1714+ if basename. hasPrefix ( expectedPrefix) {
1715+ return [ " -l " + Path( basename) . withoutSuffix. withoutPrefix ( expectedPrefix) ]
1716+ }
17351717 }
1718+ // Locate using an absolute path: Add the path as an option and as an input to the task.
1719+ inputPaths. append ( specifier. path)
1720+ return [ specifier. path. str]
17361721
17371722 case . object:
17381723 // Object files are added to linker inputs in the sources task producer and so end up in the link-file-list.
0 commit comments