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
[SR-6317] Package Manager's .pc parsing makes it difficult to selectively shadow system libraries #4927
Comments
We already do this for macOS by removing /usr/include and /usr/lib. I wonder if there is a way to ask pkg-config about the system libary paths so we can strip them off. However, that won't work if pkg-config is not installed on the system. |
I don't think we can do that for pkg-config anyway: this seems to be data compiled into the binary and not exposed through any of its interfaces. However, you can use the following dirty hack to work out whether a given package is using the system library path:
That is, you can override the system library path with the empty string. Of course, if we were going to rely on this or something like it then we'd have to ask ourselves why we weren't just shelling out to |
The easiest proposed fix, if you're interested in having it, would just be to defer to The downside of that mechanism is that we will inevitably behave differently on different systems, which can lead to strange and difficult-to-debug issues. Another proposal, then, is to just manually provide these for supported Linux distributions. They can be obtained by grabbing source packages for the supported pkg-config installers and looking in their build scripts. For example, Ubuntu 14.04's
This somewhat opaque string is the result of a build script that basically does this:
For Ubuntu 16.04 this is:
For Ubuntu 16.10 this is:
You'll note these strings are not quite identical: in particular, they contain paths that are versioned by what I presume to be the version of libc on the system. This does lead to the annoyance that we actually have to maintain three of these opaque strings. It gets worse if we want to support different architectures for these distributions, or different distributions: each entry in the arch/distro/version matrix gets its own opaque string. That will get annoying, fast. That makes my vote for fixing this problem go towards just letting |
After some discussion with my colleagues we've come up with an alternative: we can ask clang what it thinks the system library paths are. This will probably work a bit better, because 100% of systems compiling Swift with SwiftPM that require It was even suggested that we might be able to do this at SwiftPM build time, to avoid the overhead of checking each time we run SwiftPM. I'll investigate both these options to see how viable they are. |
Ok, so assuming we're using the regular
So that would make a runtime check possible and fairly straightforward to parse. |
So |
In point of fact, we'd need to replicate cmake's whole logic here, because it's non-trivial:
This probably gets us pretty close to the correct answer in most cases, as well. That said, asking |
Hrm. The downside to "just ask Probably the easiest approach is to ask the linker what its paths are as part of the build script. I'll investigate how tricky this is to do. |
However, swiftc allows you to override the linker in use, which means SwiftPM does too ( If we think |
I suppose while I'm enumerating all the options, we could also parse the output of |
Oh, I should note this problem also affects cflags: PKG_CONFIG similarly checks a |
@swift-ci create |
Environment
Linux 1779df4f8699 4.9.49-moby #1 SMP Wed Sep 27 23:17:17 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Swift version 4.0.2 (swift-4.0.2-RELEASE)
Additional Detail from JIRA
md5: e849c854eac92b5e5de3cdf3e167fa11
Issue Description:
I'm running a Swift project where I want to link mostly against system libraries (e.g. the system copy of icu-uc), but want to selectively shadow one or two other system libraries with different versions. This should be something that can mostly be solved by using pkg-config, as pkg-config allows us to give SwiftPM library search paths. This means, for example, if you're using icu-uc.pc you should expect to see the following flags added:
However, SwiftPM's parsing of .pc files doesn't behave exactly like that. Instead it behaves like pkg-config with the optional
PKG_CONFIG_ALLOW_SYSTEM_LIBS
flags set:This means that if some libraries are being added that shadow system libraries, and some are not, you will get both -L/my/shadow/path and -L/usr/lib/x86_64-linux-gnu in the command line. Depending on the order in which they appear this may mean that the attempt to shadow the system libraries fails, as the system library path may end up first in the search path again.
I'd propose that SwiftPM should behave more like pkg-config without the PKG_CONFIG_ALLOW_SYSTEM_LIBS environment variable set, and refuse to put the system library path in a -L flag.
The text was updated successfully, but these errors were encountered: