-
Notifications
You must be signed in to change notification settings - Fork 270
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
Link dynamically with system-provided libsecp256k1 instead of bundling #629
Comments
What is a "standard" And I would strongly strongly discourage anybody from trying to link this library against whatever version of libsecp256k1 happens to exist on their system. libsecp256k1 only had a real release for the first time this year, and prior to that, distributions would just bundle random git commits from the repository with no input or approval from the libsecp maintainers. At some point we should do a survey and see if all the major distributions have switched to bundling released versions of the library, and then we could investigate this. But we'd still have to handle the case that the library isn't present (or is the wrong version) which cargo can't affect. |
It should match the base name of the (native) library (without
This is used mainly by package maintainers in Linux distributions. They have control over what version of the library it’s linked with, so it’s not just whatever version.
Well, that’s very inconvenient, but fortunately, it’s in the past; now they do releases and declare SONAME (and hopefully understand ABI compatibility…). BTW, please don’t blame the package maintainers for picking up random commits from the repository when there were no releases for such a long time, so the libsecp maintainers gave them no choice.
You can see it here: https://repology.org/project/libsecp256k1/versions. Alpine Linux already packages released versions of libsecp256k1, so we could link rust-secp256k1 against shared system library instead of bundling it (which is very undesirable, especially in the case of crypto libraries). |
Ok, thanks for explaining. I'd like to figure this out, but it's difficult because crates.io/cargo don't give us a lot of great options.
If we then had two major versions of the bindings, which both linked to the same underlying C code (or at least, two versions with the same soname), then it would be impossible for both to exist in the same cargo tree, breaking compilation for people with certain dependency combinations. (You can see this in the discussion of #189, which you linked, and related issues.) AFAICT preventing this is the point of the
Ah, ok, and I guess here is where it gets frustrating that we have an ad-hoc-looking name in So, unfortunately the crates.io ecosystem, which we are more-or-less forced to support, makes it difficult for use to simultaneously support Debian maintainers. In particular:
From the libsecp maintainers' perspective, libsecp was an internal component of Bitcoin Core (which did, and always will, bundle its own vendored copy), which we discouraged people to use outside of Core. I appreciate that when people did do this nonetheless, package maintainers were put in a difficult position, but it was also an unfair burden on us to need to commit to a well-defined ABI when we were still iterating on major parts of the library internals. |
@jirutka can you describe what you would like to happen? e.g. if we changed the build script to just disable building the bundled library when Knowing what you need would help me figure out how to do it in the least-disruptive way to cargo users. |
Since I recently asked a similar question (#657 ) I went into the rabbit hole of understanding linking in Rust. According to the documentation overriding build scripts should be the right way to link to system libraries. However, cargo/rustc does not provide any protection mechanism to prevent accidental linkage against a wrong version. I'm not sure how bad this is. Also I think I suspect the correct way of doing things would be to compile and statically link the code inside the non-sys crate and only when The Just one thing that annoys me is the inability to prevent Side note: it might be nicer to use bindgen but that would completely disable overriding of build scripts. |
bindgen would produce code that was less readable and yet would require much more careful review because no human was in the loop. As for linking, I'm not quite sure what you're proposing. It sounds like:
We should also do some sort of startup check in the library to check that the correct version of secp256k1 is available at runtime, though (I think) there aren't any non-malicious colliding SONAMEs out there anymore. And of course there's nothing we can do about malicious ones.
In theory we could make the |
It'd require less review because there's no human. Humans make more mistakes than machines.
No such fallback, But I got confused and used "static library" to mean vendored and "dynamic" meaning system library. There's We can't feature gate |
Oh, I see. This sounds good, though it's confusing because the static library is called
This sounds good, though I'm not sure exactly what it would look like. |
The secp256k1 readme says:
The mentioned config option just disables symbols renaming, it doesn’t affect the build script. And the
links
attribute inCargo.toml
defines a non-standard namerustsecp256k1_v0_8_1
. Should I build it with the following in.cargo/config.toml
or how?Related issues and PRs: #380 #189
The text was updated successfully, but these errors were encountered: