swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.53k stars 10.35k forks source link

[SR-12909] SwiftPM does not use the default library search path for linking system libraries #55355

Open Lukasa opened 4 years ago

Lukasa commented 4 years ago
Previous ID SR-12909
Radar rdar://problem/63789281
Original Reporter @Lukasa
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 2 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 36b38e09726d2d32e410b2cde5140903

Issue Description:

When using a system library target whose modulemap contains an autolink directive, builds will work but linking will fail. This is appears to be because SwiftPM only searches in the SDK for system library targets, and does not use the linker default search paths. See [this SwiftPM thread| https://forums.swift.org/t/swift-package-manager-linker-flags-and-dependencies/36943] for more details.

Lukasa commented 4 years ago

@swift-ci create

abertelrud commented 4 years ago

On macOS, iOS, etc, the compiler's built-in SDKs are generally relative to the `-isysroot`. But it looks as if the Clang driver does pass `/usr/local/include` to the compiler, and `-L/usr/local/lib` to the linker if those directories exist in the file system. But `swiftc` does not seem to pass `-L/usr/local/lib` to the linker. So if C code, compiled with `clang`, and Swift code, compiled with `swiftc`, are linked together using the `swiftc` driver, that search path will be missing.

It's not ideal to rely on the compiler driver's behavior here, and anyway, the system library can be at a different path. It seems to me that a straightforward option for when a `.pc` file is not being used would be to provide a way for the system library target to impart header and library search paths to any clients by allowing those paths to be specified in the target itself if a `pkg-config` isn't being used.

abertelrud commented 4 years ago

Actually, it's a bit more complicated. Even though the `clang` driver is passing `-L/usr/local/lib`, the fact that it's also passing `-syslibroot` makes that path get prepended by the path of the SDK. So even if SwiftPM passes `-L/usr/local/lib` to a Clang target, it will end up getting redirected to the SDK. The `swiftc` driver also passes `-syslibroot`, so it wouldn't matter whether SwiftPM passes `-L/usr/local/lib` or not, it would end up getting redirected into the SDK if that path exists there.

swift-ci commented 3 years ago

Comment by Lane Schwartz (JIRA)

Some new information: https://forums.swift.org/t/swift-package-manager-linker-flags-and-dependencies/36943/26

TL;DR: On macOS 11.2, if there is a pc file in /usr/local/lib/pkgconfig, swift build can find the library, but XCode still can't.