Skip to content

Don't add dependencies recursively while linking#1545

Merged
jpakkane merged 4 commits intomesonbuild:masterfrom
centricular:dont-link-recursively
Jun 4, 2017
Merged

Don't add dependencies recursively while linking#1545
jpakkane merged 4 commits intomesonbuild:masterfrom
centricular:dont-link-recursively

Conversation

@nirbheek
Copy link
Member

We were doing this on the basis of an old comment, but there was no test for it and I couldn't reproduce the issue with clang on Linux at all.

Let's add a test and see if it breaks anywhere if we stop doing this.

Halves the size of gstreamer's build.ninja from 19M to 8.5M

Closes #1057

@tp-m
Copy link
Member

tp-m commented Mar 31, 2017

It appears that with this patch in the gtk4 meson build, the static gdk backend libs are no longer linked into the static lib libgdk.a now. They were passed to static_library(..., link_with: ...)

@jpakkane
Copy link
Member

jpakkane commented Apr 1, 2017

We really want this in as soon as possible. This may be the last chance to change this before we have too many users.

@jpakkane
Copy link
Member

jpakkane commented Apr 4, 2017

Apparently we don't have a test for exe -> static -> static, only one for exe -> static-> shared. We should add one.

@nirbheek
Copy link
Member Author

nirbheek commented Apr 4, 2017

Yeah, it's on my TODO list for this PR.

@keszybz
Copy link
Contributor

keszybz commented Apr 13, 2017

FWIW, I'm building systemd with meson with this patch, and it seems to work nicely.

@nirbheek
Copy link
Member Author

I should have some time to work on this tomorrow. If we have enough tests for various corner-cases, we could merge this for 0.40, and fix any breakage in a point release?

@jpakkane
Copy link
Member

This message is posted to every outstanding merge request.

We have transitioned from Github wiki to our new documentation system that generates all documentation directly from the Git repo. This means that from now on every merge request must come with corresponding documentation changes.

If your MR requires documentation changes, do the necessary changes to files in docs/markdown.

If your MR adds a new feature, add a description to the release notes in docs/markdown/Release-notes-for-0.41.0.md.

If this commit is just a bugfix with no functional changes, you don't need to do anything.

Thank you

mbiebl added a commit to mbiebl/systemd that referenced this pull request Apr 28, 2017
Linking dynamically against libudev will fail once
mesonbuild/meson#1545 is merged and apparently
already triggers a link failure on s390x.

Make libshared provide by the udev symbols by including libudev_sources
into libshared. This will cause those files to be compiled twice, but it
actually reduces the installed size and is closer to what the autotools
build system is doing.

Closes systemd#5828
mbiebl added a commit to mbiebl/systemd that referenced this pull request Apr 28, 2017
Linking dynamically against libudev will fail once
mesonbuild/meson#1545 is merged and apparently
already triggers a link failure on s390x.

Make libshared provide the udev symbols by including libudev_sources
into libshared. This will cause those files to be compiled twice, but it
actually reduces the installed size and is closer to what the autotools
build system is doing.

Closes systemd#5828
martinpitt pushed a commit to systemd/systemd that referenced this pull request Apr 29, 2017
Linking dynamically against libudev will fail once
mesonbuild/meson#1545 is merged and apparently
already triggers a link failure on s390x.

Make libshared provide the udev symbols by including libudev_sources
into libshared. This will cause those files to be compiled twice, but it
actually reduces the installed size and is closer to what the autotools
build system is doing.

Closes #5828
@jpakkane
Copy link
Member

What's the status of this? Is any help needed?

@nirbheek
Copy link
Member Author

Dropped off my list accidentally, will look into this today!

nirbheek added 3 commits June 2, 2017 05:32
We were doing this on the basis of an old comment, but there was no
test for it and I couldn't reproduce the issue with clang on Linux
at all.

Let's add a (somewhat comprehensive) test and see if it breaks
anywhere if we stop doing this.

Halves the size of gstreamer's build.ninja from 20M to 8.7M

Closes #1057
This significantly reduces the size of build.ninja for GStreamer.
Now we aggressively de-dup the list of libraries used while linking,
and when linking with GNU ld we have to enclose all static libraries
with -Wl,--start-group and -Wl,--end-group to force the linker to
resolve all symbols recursively. This is needed when static libraries
have circular deps on each other (see included test).

The --start/end-group change is also needed for circular dependencies
between static libraries because we no longer recursively list out all
library dependencies.

The size of build.ninja for GStreamer is now down to 6.1M from 20M,
and yields a net reduction in configuration time of 10%
@nirbheek
Copy link
Member Author

nirbheek commented Jun 2, 2017

"Today" came 18 days late, but I have something that works for most cases now. Some people will get build failures because they under-specified the libraries that they need, but gstreamer itself didn't need any such fixes and that makes me think that people are generally disciplined about this.

Anyway, the fix in such cases is easy and is backwards-compatible so I think we shouldn't worry about this too much.

@codecov-io
Copy link

codecov-io commented Jun 2, 2017

Codecov Report

Merging #1545 into master will increase coverage by 0.06%.
The diff coverage is 96.15%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1545      +/-   ##
==========================================
+ Coverage   63.01%   63.07%   +0.06%     
==========================================
  Files          58       58              
  Lines       16882    16900      +18     
  Branches     3456     3464       +8     
==========================================
+ Hits        10638    10660      +22     
+ Misses       5150     5148       -2     
+ Partials     1094     1092       -2
Impacted Files Coverage Δ
mesonbuild/compilers.py 74.92% <100%> (+0.34%) ⬆️
mesonbuild/backend/ninjabackend.py 88.6% <100%> (-0.01%) ⬇️
mesonbuild/backend/backends.py 89.92% <50%> (ø) ⬆️
mesonbuild/interpreter.py 73.93% <0%> (+0.1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6662f36...4b42805. Read the comment docs.

This is more reliable, and more accurate. For instance, this means
arguments in commands aren't surrounded by `'` on Linux unless that
is actually needed by that specific argument.

There is no equivalent helper for Windows, so we keep the old
behaviour for that.

if mesonlib.is_windows():
quote_char = '"'
quote_func = lambda s: '"{}"'.format(s)
Copy link
Member

Choose a reason for hiding this comment

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

[flake8]

  • [E731] do not assign a lambda expression, use a def

quoter = ninja_quote
else:
templ = q_templ
quoter = lambda x: ninja_quote(quote_func(x))
Copy link
Member

Choose a reason for hiding this comment

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

[flake8]

  • [E731] do not assign a lambda expression, use a def

@nirbheek
Copy link
Member Author

nirbheek commented Jun 2, 2017

Also, here's some stats:

glib's build.ninja went from 614KB to 531KB
gst-build's build.ninja went from 20MB to 6.0MB

All this with no significant changes in configure time (gst-build's configure time went down by 10% for me, but likely because of the smaller build.ninja file).

These numbers can be reduced a bunch more by using Ninja rules for each target so that build statements don't have to repeat the cflags over and over for each source file in the target. We could reduce this even more by putting compiler-specific cflags in the compiler rules instead of in each target's build statements.

Interestingly, the "use shlex.quote for quoting" commit in this PR also reduces the build.ninja size considerably: 100KB for gst-build.

@jpakkane
Copy link
Member

jpakkane commented Jun 3, 2017

 executable('circular', 'main.c', link_with : [st1, st2, st3])

I'm surprised that this works on platforms without groupings, mainly MSVC. IIRC it does something saner than LD by looking at past libraries for symbols. So the question is:

  • is MSVC guaranteed to do the right thing
  • do we ever need to support a platform that gets this wrong and does not have static library grouping?

If the latter is true (dunno, maybe Solaris or somesuch works like that) then having the dependencies a a set is problematic because you would need have something like [st1, st2, st3, st1, st2] go through to the link line unaltered.

We could also say that this is too niche and we don't care or will fix it later if the issue really arises.

@nirbheek
Copy link
Member Author

nirbheek commented Jun 4, 2017

I wrote the circular test specifically because I had read that only GNU ld is dumb while resolving symbols and I wanted to add a test for it. macOS and MSVC are saner, fwict.

Perhaps Sun Studio's ld has the same issue as GNU ld, but we've never tested anything with that, so we should deal with that when someone cares about it. I will note that OpenIndiana moved from Sun Studio to GCC last year, so we may not have to care about it ever.

because you would need have something like [st1, st2, st3, st1, st2] go through to the link line unaltered.

Specifying a library multiple times will now be ignored because we de-dup library names in the CompilerArgs class while constructing compiler arguments. This can be turned off for a broken linker in the future if needed.

@nirbheek
Copy link
Member Author

nirbheek commented Jun 4, 2017

Let's list the platforms that we actively support:

  1. Linux (GNU ld)
  2. Windows (MSVC link, GNU ld, Clang lld)
  3. macOS and iOS (Apple ld, Clang lld)
  4. Android (GNU ld)
  5. *BSD (GNU ld, Clang lld(?))

Others:

  1. OpenIndiana (GNU ld)
  2. Haiku OS (GNU ld)

Is there anything else we want to support? I think most edge-platforms actually rely on GCC, so we shouldn't have much to worry about.

@QuLogic
Copy link
Member

QuLogic commented Jun 4, 2017

gold?

@nirbheek
Copy link
Member Author

nirbheek commented Jun 4, 2017

I tested gold, it behaves the same way as bfd at least on Fedora.

@nirbheek nirbheek removed the WIP label Jun 4, 2017
@jpakkane
Copy link
Member

jpakkane commented Jun 4, 2017

🏁 🎉 🎆 🥂

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.

7 participants