Skip to content
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

Allow static and dynamic linking #1620

Closed
wants to merge 2 commits into from
Closed

Conversation

jsgf
Copy link
Contributor

@jsgf jsgf commented Sep 16, 2019

Currently bindgen always uses clang-sys with the "runtime" feature -
that is, load libclang at runtime with dlopen (or similar)
at runtime. This PR keeps this default, but also

  • adds "static" to statically link libclang
  • without either "runtime" or "static", link with the shared library

Many distributions don't ship with a static libclang, but linking with the dynamic
library will use normal ld.so mechanisms to define where the .so file should be found.
(Ditto for the Mac and Windows equivalents.)

Fixes #1617

@bors-servo
Copy link

☔ The latest upstream changes (presumably 3062841) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I thought ::is_loaded() and co would not work on statically-linked stuff.

This looks great, do you know if it'd be a lot of work to at least cargo-check the new build configuration? That'd prevent it from breaking in the future.

@jsgf
Copy link
Contributor Author

jsgf commented Sep 17, 2019

Huh, I thought ::is_loaded() and co would not work on statically-linked stuff.

It doesn't - they're all behind #[cfg(feature = "runtime")].

This looks great, do you know if it'd be a lot of work to at least cargo-check the new build configuration? That'd prevent it from breaking in the future.

I'll see what I can do.

@emilio
Copy link
Contributor

emilio commented Sep 17, 2019

Then how does this build?

@jsgf
Copy link
Contributor Author

jsgf commented Sep 17, 2019

Then how does this build?

? I added the necessary #[cfg(...)] conditional build checks to lib.rs.

@emilio
Copy link
Contributor

emilio commented Sep 18, 2019

Sorry, we were talking past each other looks like :)

I was talking about the individual function's is_loaded() checks, like clang_Foo::is_loaded() that we have sprinkled around in the codebase.

But looks like clang-sys stubs them properly: https://github.com/KyleMayes/clang-sys/blob/ad5b1d0c64b19c4bfe00df6dfd661b80203dd161/src/link.rs#L195

@jsgf
Copy link
Contributor Author

jsgf commented Sep 19, 2019

@emilio The checks are failing because this doesn't support libclang <= 4.0 any more - it tries to resolve symbols which don't exist in those versions. It might work with "runtime" because it only dynamically looks up symbols which do exist.

@emilio
Copy link
Contributor

emilio commented Sep 20, 2019

@emilio The checks are failing because this doesn't support libclang <= 4.0 any more - it tries to resolve symbols which don't exist in those versions. It might work with "runtime" because it only dynamically looks up symbols which do exist.

Yeah, that's ~expected, I guess... Can we not test building the static version in those rather than removing the platforms? What's what triggers the static feature?

Alternatively, we need to remove a bunch of tests/expectations/libclang-3.* and same for 4... I can do that as a followup but I'd like to keep at least 4.0 if we can (clang 3 is pretty old anyway at this point).

@jsgf
Copy link
Contributor Author

jsgf commented Sep 20, 2019

It's triggered by non-"runtime". (nothing) is link with whatever is available (static or dynamic), and "static" is specifically statically link. "static" is hard to test because libclang doesn't build static out of the box and I haven't found any prebuilt libclangs available as static. But clang-sys does support static, so presumably someone is using it (well, including me, but we're using a slightly different mechanism).

Are you suggesting:

  1. delete the 3.x tests
  2. make the 4.x tests conditional on "runtime"

?

@bors-servo
Copy link

☔ The latest upstream changes (presumably 807fa1e) made this pull request unmergeable. Please resolve the merge conflicts.

@emilio
Copy link
Contributor

emilio commented Oct 7, 2019

(FWIW, I haven't forgotten about this and still looks good. Will try to figure out a way to test this properly without regressing the dynamic clang support while I address similar CI issues due to the clang 9.0 release, probably over the weekend or on friday)

Thanks again for this!

@emilio
Copy link
Contributor

emilio commented Oct 7, 2019

(And really sorry for the lag replying, I had missed your previous comment)

@jsgf
Copy link
Contributor Author

jsgf commented Oct 9, 2019

Do you need me to rebase it?

@emilio
Copy link
Contributor

emilio commented Oct 10, 2019 via email

@emilio
Copy link
Contributor

emilio commented Oct 11, 2019

#1646 is the version that adds support for libclang 9 on CI. That should allow to test this, and we should be able to avoid testing on other platforms.

jsgf and others added 2 commits October 11, 2019 11:47
We get link-time missing symbols with llvm before 5.x, so don't try to directly link with them.
Currently bindgen always uses clang-sys with the "runtime" feature -
that is, load libclang at runtime with dlopen (or similar)
at runtime.  This PR keeps this default, but also
- adds "static" to statically link libclang
- without either "runtime" or "static", link with the shared library

Many distributions don't ship with a static libclang, but linking with the dynamic
library will use normal ld.so mechanisms to define where the .so file should be found.
(Ditto for the Mac and Windows equivalents.)
@jsgf
Copy link
Contributor Author

jsgf commented Oct 11, 2019

Rebased; fixed trivial conflict

@emilio
Copy link
Contributor

emilio commented Oct 18, 2019

So I put in #1649 my current WIP.

One annoyance of having two separate features is that downstream crates that want to use no-default-features can't get the advantages of the runtime feature, or otherwise they need to specify it, which means that other crates can't specify static.

I think ideally we'd make runtime built into clang-sys, but not sure how easy to do that is...

@jsgf
Copy link
Contributor Author

jsgf commented Oct 18, 2019

I think that's a fundamental problem with using features this way - it isn't intended to support non-cumulative build-time options, and trying to do so breaks things. On the other hand, there's no better suited alternative mechanism.

@emilio
Copy link
Contributor

emilio commented Oct 19, 2019

So I gave a shot at finishing this, but apparently there are no pre-built static libclang versions, so we'd need to build our own which is not great...

Is the plan to build your own libclang.a and distribute it statically linked? Anyhow I guess I can land the patch without the tests if you need it and got it working.

@jsgf
Copy link
Contributor Author

jsgf commented Oct 21, 2019

Yes, the clang build system seems to make generating a static libclang really tricky, and I couldn't find any Linux distro which ships a prebuilt static libclang. However our internal libclang has a static build, so its useful for that.

The non-static, non-runtime bindgen build will link to the shared libclang at build time which is logically identical to static linking from a code perspective - it just has the deployment question of whether the libclang is available at runtime at a path where it can be found.

So I'm not too concerned about not specifically testing static so long as non-runtime also works. This isn't ideal but 🤷‍♂.

@bors-servo
Copy link

☔ The latest upstream changes (presumably c462b63) made this pull request unmergeable. Please resolve the merge conflicts.

@emilio
Copy link
Contributor

emilio commented Oct 21, 2019

Ok, so I landed #1649 with your changes and a slightly different/smaller set of CI tweaks, so that this is tested to the extent possible based on the comment above.

Thanks for the patch!

@lopopolo
Copy link
Contributor

Hi @emilio this fix added a new default feature which wasn't mentioned in the changelog. This made upgrading my dependency with default-features = false tricky because I couldn't track down the errors from clang-sys.

Can we add a note to the changelog when features are added?

@emilio
Copy link
Contributor

emilio commented Feb 11, 2020

Yeah, that's fair, I added a changelog note just now, but I'll keep it in mind for the future too. Thanks :)

emilio added a commit to emilio/lmdb-rs that referenced this pull request Mar 10, 2020
victorporof pushed a commit to mozilla/lmdb-rs that referenced this pull request Mar 10, 2020
* Fix bindings.

PR #74 introduced a manually-generated change to the bindings that I
accidentally broke in #76.

* Specify the "runtime" feature of bindgen.

As it became non-default in rust-lang/rust-bindgen#1620.

* Make binding generation work properly on Windows too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow statically linking libclang
5 participants