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

Fix niche cases when linking static libs #11742

Merged
merged 6 commits into from
Jul 4, 2023

Conversation

xclaesse
Copy link
Member

Case 1:

  • Prog links to static lib A
  • A link_whole to static lib B
  • B link to static lib C
  • Prog dependencies should be A and C but not B which is already included in A.

Case 2:

  • Same as case 1, but with A being installed.
  • To be useful, A must also include all objects from C that is not installed.
  • Prog only need to link on A.

@xclaesse xclaesse requested a review from jpakkane as a code owner April 26, 2023 21:59
@xclaesse
Copy link
Member Author

Case1 is a pure-C equivalent to this Rust issue: #11723.

@sdroege
Copy link
Contributor

sdroege commented Apr 27, 2023

Does this also solve the the Rust issue if putting the dependencies explicitly into link_whole? And if so, would you mind integrating my test from that other PR here so we can be sure it keeps working? :)

@xclaesse
Copy link
Member Author

@sdroege I'm undecided what to do with Rust yet. As usual, the more I dig the more I realize the problem is bigger than I thought.

For example s1 -> s2 -> r1 -> prog where s1 and s2 are C static lib and r1 is Rust staticlib, the final link of prog fails because it miss symbol from s1. What happens is rustc bundles s2 in r1 but not s1, because ninja backend in generate_rust_target() does not pass all deps to rustc.

using link_whole was a bad idea, which should forbid link_whole of rust targets completely because Meson implement that by passing object files which we don't have access to with rustc.

I leaning toward fixing this in ninja backend, generate_rust_target() does not use target.get_dependencies() correctly maybe... More thinking is needed :P

@xclaesse
Copy link
Member Author

xclaesse commented Apr 27, 2023

Failing CI here is another problematic edge case, the unit test does:

r = static_library('stuff', 'stuff.rs', rust_crate_type : 'staticlib')
l = static_library('clib', 'clib.c', link_with : r, install : true)

That cannot be supported currently, clib is installed so to be usable it needs to bundle stuff. Meson does that by adding all object files from stuff into clib archive but we can't do that with rustc because we don't have access to individual .o files, only the final .a archive.

Before this PR prog was incorrectly linking to stuff which should not be needed because clib is supposed to bundle it. This PR fix that, but since clib does not actually bundle stuff it now fail to link prog. But the thing is, that situation has always been broken because the installed clib does not bundle stuff which is not installed, that means installed clib was not usable which we never tested.

@sdroege
Copy link
Contributor

sdroege commented Apr 27, 2023

That failing case should use link_whole : r in theory, and copying everything into the final .a could be done by first unpacking the libstuff.a or not?

@xclaesse
Copy link
Member Author

One trick we might do is consider rust staticlib just like an external static library (which we cannot link_whole atm) and add code in Meson to extract archives like I did a while ago: #9218

@xclaesse
Copy link
Member Author

That failing case should use link_whole : r in theory, and copying everything into the final .a could be done by first unpacking the libstuff.a or not?

In theory it should get promoted to link_whole implicitely, but Meson is not doing that because it knows it's broken: https://github.com/mesonbuild/meson/blob/master/mesonbuild/build.py#L1391. I think that should be turned into an hard error for now, it is not supported use-case.

@eli-schwartz
Copy link
Member

eli-schwartz commented Apr 27, 2023

That failing case should use link_whole : r in theory,

Installed static library: i
Uninstalled static rust library: rstuff
Uninstalled static C library: cstuff

If i does link_with: cstuff this is supposed to auto-promote to link_whole, which we do by recording ninja rules that build each .o file and another rule that runs ar on the .o.files and emits a libcstuff.a file.

The auto-promotion is not the problem here, we can and should auto-promote rust libraries too. The problem is the unpacking.

EDIT:

In theory it should get promoted to link_whole implicitely, but Meson is not doing that because it knows it's broken

Right, I remember that.

@xclaesse
Copy link
Member Author

I added a PR that does the promotion, but abort later when it tries to extract object files. That has those advantages:

  • Catch if user used link_whole in the first place.
  • Avoid installing unusable static libs, better error out early.
  • Group together with the CustomTarget case which has the same issue and potential fix.

@xclaesse xclaesse force-pushed the link-whole-cases branch 3 times, most recently from c457a5f to 2cb836f Compare April 27, 2023 19:13
@xclaesse xclaesse requested a review from mensinda as a code owner April 27, 2023 19:13
@xclaesse
Copy link
Member Author

xclaesse commented Apr 30, 2023

Ok, CI fails because this PR is also fixing the same issue as described in #10699, but that PR had to be reverted because of #10745 for which we luckily added a unit test. That means we need to find a proper fix now. On the plus side, it means this PR should fix #11165 too.

@eli-schwartz
Copy link
Member

It would be nice to reapply the original commits if we can get it to work...

Is there part of this PR that doesn't depend on that and which we can merge independently?

@xclaesse
Copy link
Member Author

I think I have a proper fix, extract_all_objects() should include the object file for MSVC PCH. Unfortunately I lost access to my Windows machine (VPN seems down) so let's see if CI likes it.

@xclaesse xclaesse force-pushed the link-whole-cases branch 2 times, most recently from 1f12503 to e712910 Compare April 30, 2023 15:20
xclaesse added 6 commits May 1, 2023 12:57
Case 1:
- Prog links to static lib A
- A link_whole to static lib B
- B link to static lib C
- Prog dependencies should be A and C but not B which is already
  included in A.

Case 2:
- Same as case 1, but with A being installed.
- To be useful, A must also include all objects from C that is not
  installed.
- Prog only need to link on A.
It seems to only be used by the Rust module now, and it already does a
copy.
To take good decisions we'll need to know if we are a Rust library which
is only know after processing source files and compilers.

Note that is it not the final list of compilers, some can be added in
process_compilers_late(), but those are compilers for which we don't
have source files any way.
Rustc can do it without needing Meson to extract all objects.
This changes the object file name with ninja backend to match the
name used by vs backend and add it in outputs of the ninja rule.
@xclaesse xclaesse force-pushed the link-whole-cases branch from e712910 to ff86e79 Compare May 1, 2023 16:57
@xclaesse xclaesse requested a review from dcbaker as a code owner May 1, 2023 16:57
@xclaesse
Copy link
Member Author

xclaesse commented May 1, 2023

Got CI to pass now.

@xclaesse xclaesse added this to the 1.2.0 milestone May 3, 2023
@xclaesse
Copy link
Member Author

@eli-schwartz any objection?

@jpakkane
Copy link
Member

jpakkane commented Jul 4, 2023

Anyone still have issues?

@jpakkane jpakkane merged commit d391e52 into mesonbuild:master Jul 4, 2023
@xclaesse xclaesse deleted the link-whole-cases branch July 5, 2023 12:29
xclaesse pushed a commit to xclaesse/meson that referenced this pull request Jul 5, 2023
This is a regression test for:
mesonbuild#11165.

The test was initially merged as part of:
mesonbuild#10628, but had to be reverted.

A second attempt at fixing the root cause also had to be reverted:
mesonbuild#10699.

A 3rd attempt got merged but missed this unit test:
mesonbuild#11742.

Co-authored-by: Dylan Baker <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants