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

linker: Link dylib crates by path #126094

Merged
merged 1 commit into from
Jul 3, 2024
Merged

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Jun 6, 2024

Linkers seem to support linking dynamic libraries by path.
Not sure why the previous scheme with splitting the path into a directory (passed with -L) and a name (passed with -l) was used (upd: likely due to #126094 (comment)).

When we split a library path some/dir/libfoo.so into -L some/dir and -l foo we add some/dir to search directories for all libraries looked up by the linker, not just foo, and foo is also looked up in all search directories not just some/dir.
Technically we may find some unintended libraries this way.
Therefore linking dylibs via a full path is both simpler and more reliable.

It also makes the set of search directories more easily reproducible when we need to lookup some native library manually (like in #123436).

@rustbot
Copy link
Collaborator

rustbot commented Jun 6, 2024

r? @estebank

rustbot has assigned @estebank.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2024
@rust-log-analyzer

This comment has been minimized.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 7, 2024
@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. labels Jun 7, 2024
@rust-log-analyzer

This comment has been minimized.

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jun 7, 2024

Sigh, on Linux if a dynamic library A is linked into a binary B via path, then that entire path gets into B's DT_NEEDED.
Probably need to specify soname for dylib crates to address this.

@rust-log-analyzer

This comment has been minimized.

@petrochenkov petrochenkov force-pushed the libsearch branch 2 times, most recently from 83ba8e5 to 57f5026 Compare June 8, 2024 10:44
@petrochenkov
Copy link
Contributor Author

@bors rollup=never
@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 8, 2024
@petrochenkov
Copy link
Contributor Author

In the meantime let's test on some more targets.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 10, 2024
@rust-log-analyzer

This comment has been minimized.

@petrochenkov petrochenkov force-pushed the libsearch branch 2 times, most recently from 5950f0d to e776337 Compare June 10, 2024 22:14
@petrochenkov
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 10, 2024
@bors

This comment was marked as resolved.

@petrochenkov
Copy link
Contributor Author

@bors r=michaelwoerister

@bors
Copy link
Contributor

bors commented Jul 2, 2024

📌 Commit 565ddfb has been approved by michaelwoerister

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Jul 2, 2024

🌲 The tree is currently closed for pull requests below priority 100. This pull request will be tested once the tree is reopened.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 2, 2024
@bors
Copy link
Contributor

bors commented Jul 3, 2024

⌛ Testing commit 565ddfb with merge 1086aff...

@bors
Copy link
Contributor

bors commented Jul 3, 2024

☀️ Test successful - checks-actions
Approved by: michaelwoerister
Pushing 1086aff to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jul 3, 2024
@bors bors merged commit 1086aff into rust-lang:master Jul 3, 2024
7 checks passed
@rustbot rustbot added this to the 1.81.0 milestone Jul 3, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (1086aff): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results (primary -3.1%, secondary -2.8%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-3.1% [-3.1%, -3.1%] 1
Improvements ✅
(secondary)
-2.8% [-2.8%, -2.8%] 1
All ❌✅ (primary) -3.1% [-3.1%, -3.1%] 1

Cycles

Results (secondary -2.2%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.2% [-2.4%, -2.1%] 2
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 726.158s -> 706.903s (-2.65%)
Artifact size: 327.58 MiB -> 327.56 MiB (-0.01%)

github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jul 4, 2024
linker: Link dylib crates by path

Linkers seem to support linking dynamic libraries by path.
Not sure why the previous scheme with splitting the path into a directory (passed with `-L`) and a name (passed with `-l`) was used (upd: likely due to rust-lang/rust#126094 (comment)).

When we split a library path `some/dir/libfoo.so` into `-L some/dir` and `-l foo` we add `some/dir` to search directories for *all* libraries looked up by the linker, not just `foo`, and `foo` is also looked up in *all* search directories not just `some/dir`.
Technically we may find some unintended libraries this way.
Therefore linking dylibs via a full path is both simpler and more reliable.

It also makes the set of search directories more easily reproducible when we need to lookup some native library manually (like in rust-lang/rust#123436).
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 15, 2024
…-mingw-import-libraries, r=petrochenkov

linker: Allow MSVC to use import libraries following the Meson/MinGW convention

Hi all,

This PR implements support for `MsvcLinker` to use import libraries following Meson and the MinGW toolchain's naming convention. Meson [follows the `libfoo.dll.a` naming convention](https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa) to disambiguate between static and import libraries.

This support already existed for static libraries (see rust-lang#100101), but not for dynamic libraries. The latter case was added by duplicating the logic in `native_libs::find_native_static_library`, but a separate case was added in `link_dylib_by_name` for the Windows CRT libraries which must be handled by the linker itself.

See for prerequisites rust-lang#129366, rust-lang#126094, and rust-lang#128370.

All feedback is appreciated!

Fixes rust-lang#122455

cc `@sdroege` `@nirbheek`
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 16, 2024
…-mingw-import-libraries, r=petrochenkov

linker: Allow MSVC to use import libraries following the Meson/MinGW convention

Hi all,

This PR implements support for `MsvcLinker` to use import libraries following Meson and the MinGW toolchain's naming convention. Meson [follows the `libfoo.dll.a` naming convention](https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa) to disambiguate between static and import libraries.

This support already existed for static libraries (see rust-lang#100101), but not for dynamic libraries. The latter case was added by duplicating the logic in `native_libs::find_native_static_library`, but a separate case was added in `link_dylib_by_name` for the Windows CRT libraries which must be handled by the linker itself.

See for prerequisites rust-lang#129366, rust-lang#126094, and rust-lang#128370.

All feedback is appreciated!

Fixes rust-lang#122455

cc `@sdroege` `@nirbheek`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Sep 16, 2024
…nd-mingw-import-libraries, r=petrochenkov

linker: Allow MSVC to use import libraries following the Meson/MinGW convention

Hi all,

This PR implements support for `MsvcLinker` to use import libraries following Meson and the MinGW toolchain's naming convention. Meson [follows the `libfoo.dll.a` naming convention](https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa) to disambiguate between static and import libraries.

This support already existed for static libraries (see rust-lang#100101), but not for dynamic libraries. The latter case was added by duplicating the logic in `native_libs::find_native_static_library`, but a separate case was added in `link_dylib_by_name` for the Windows CRT libraries which must be handled by the linker itself.

See for prerequisites rust-lang#129366, rust-lang#126094, and rust-lang#128370.

All feedback is appreciated!

Fixes rust-lang#122455

cc `@sdroege` `@nirbheek`
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 16, 2024
Rollup merge of rust-lang#123436 - amyspark:allow-msvc-to-use-meson-and-mingw-import-libraries, r=petrochenkov

linker: Allow MSVC to use import libraries following the Meson/MinGW convention

Hi all,

This PR implements support for `MsvcLinker` to use import libraries following Meson and the MinGW toolchain's naming convention. Meson [follows the `libfoo.dll.a` naming convention](https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa) to disambiguate between static and import libraries.

This support already existed for static libraries (see rust-lang#100101), but not for dynamic libraries. The latter case was added by duplicating the logic in `native_libs::find_native_static_library`, but a separate case was added in `link_dylib_by_name` for the Windows CRT libraries which must be handled by the linker itself.

See for prerequisites rust-lang#129366, rust-lang#126094, and rust-lang#128370.

All feedback is appreciated!

Fixes rust-lang#122455

cc `@sdroege` `@nirbheek`
@cuviper
Copy link
Member

cuviper commented Sep 26, 2024

Dropping a quick reference here, the new "cdylib" SONAME is causing unwanted rpm Provides:
https://bugzilla.redhat.com/show_bug.cgi?id=2314879

I will probably file an issue about this, if nobody beats me to it, although I'm not certain what the resolution should be. On the rpm side, it's also possible to filter out such provides, but it was unexpected that this might be needed.

@nirbheek
Copy link

nirbheek commented Sep 27, 2024

The basic problem is that Cargo doesn't have a way to designate a target as a "module" instead of a "library". It just has "cdylib", which is supposed to be linked. Modules should not be linked (except on Android).

For example, in CMake, you have "shared library" and "module library" as separate concepts. Similarly in Meson you have shared_library() and shared_module().

There are a number of differences between the two, not just SONAME, for example undefined symbols are allowed in
modules. However, cdylib is all that was available, so it was used for modules too. We saw this in the early years of Meson as well, when everyone started using shared_library(), and we had a transition period to shared_module(), which involved people fixing their usage.

Also, answering some suggestions in that bug, I think it is a mistake to pawn-off these duties to build.rs or cargo-c:

build.rs is an anti-pattern, people should not need to use code to build code. 99% of use-cases should be covered by something declarative, and the 1% custom needs should be code. With build.rs right now if you have to interop with C, 99% of cases need code to build code.

cargo-c is a great project, and I want more people to use it, but this problem cannot be solved in cargo-c, we already tried it and the cargo-c maintainer reviewed this PR.

@petrochenkov
Copy link
Contributor Author

Setting soname for cdylibs wasn't strictly necessary for this PR (I asked about this in #126094 (comment)).
We can set it just for Rust dylibs, that would only be a minor nuisance (passing an extra argument around).

@decathorpe
Copy link

The problem is that all uses of cdylib targets built by rustc we have in Fedora are either

  • built with cargo-c or similar tools and already set soname explicitly because they're used as actual shared libraries, or
  • built with maturin / setuptools_rust and expect the soname not to be set because they're "modules", not "libraries".

So the fact that this behaviour was flipped from "not set unless set explicitly" in Rust itself to "set always" breaks the expectations for the second case, and it's apparently not easy to fix "in post" because patchelf apparently doesn't support removing headers, only overriding them, so I don't even think maturin or setuptools_rust could fix this on their side.

@nirbheek
Copy link

@lu-zero what do you think about setting soname here? Should we revert that part of the change?

@lu-zero
Copy link
Contributor

lu-zero commented Sep 27, 2024

For maturin and other systems that generate unversioned modules probably reverting that would be the simplest solution.

Generally would be great to have a simpler mean to set/unset the value and in the long run would be even better to be able to say cdylib and cmod to Cargo.

@cuviper
Copy link
Member

cuviper commented Sep 27, 2024

We can set it just for Rust dylibs, that would only be a minor nuisance (passing an extra argument around).

I've attempted this in #130960.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Sep 28, 2024
Only add an automatic SONAME for Rust dylibs

rust-lang#126094 added an automatic relative `SONAME` to all dynamic libraries, but it was really only needed for Rust `--crate-type="dylib"`. In Fedora, it was a surprise to see `SONAME` on `"cdylib"` libraries like Python modules, especially because that generates an undesirable RPM `Provides`. We can instead add a `SONAME` just for Rust dylibs by passing the crate-type argument farther.

Ref: https://bugzilla.redhat.com/show_bug.cgi?id=2314879
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 28, 2024
Rollup merge of rust-lang#130960 - cuviper:cdylib-soname, r=petrochenkov

Only add an automatic SONAME for Rust dylibs

rust-lang#126094 added an automatic relative `SONAME` to all dynamic libraries, but it was really only needed for Rust `--crate-type="dylib"`. In Fedora, it was a surprise to see `SONAME` on `"cdylib"` libraries like Python modules, especially because that generates an undesirable RPM `Provides`. We can instead add a `SONAME` just for Rust dylibs by passing the crate-type argument farther.

Ref: https://bugzilla.redhat.com/show_bug.cgi?id=2314879
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.