Christian Ruppert (idl0r) asked me today whether --as-needed
makes software faster or smaller. I guess this is one of the most confusing points about --as-needed
; focus of tons of hearsay, and with different assertions all around the place. So I’ll do my best to explain this once and for all.
In perfect conditions, that is, if --as-needed
were not doing anything at all, then it wouldn’t be changing anything. The flag is not magical, it does not optimise the output at all. The same exact result you would have if libtool wasn’t pushing all crap down the line, and if all the build systems only requested the correct dependencies.
When it does matter is when overlink is present. To understand what the term overlink refers to check my old post that explains a bit what --as-needed
does, and shows the overlink case, the perfect link case, and what really happens.
Now, of course you’ll find reports of users saying that --as-needed
makes software faster or smaller. Is this true, or false? It’s not easy to answer one straight answer because it depends on what it’s happening with and without the flag. If with the flag there are libraries loaded, directly and indirectly, that are not used (neither directly nor indirectly), then the process spawned from the executable will have less libraries loaded in the address space, and thus both be faster to load (no need to read, map in memory, and relocate those libraries) and smaller in memory (some libraries are “free” in memory, but most will have relocations, especially if immediate bindings (“now” bindings) are used, like happens for setuid executables.
Indeed, the biggest improvements you can have when comparing the with and without cases in a system, or in software, that uses immediate bindings. In that case, all the symbols from shared objects are bound at load, instead than at runtime, so the startup time for the processes are cut down sensibly. This does not only involve hardened systems, or setuid binaries, but also applications using plugins, that may be requesting immediate bindings (to reject the plugin, rather than aborting at runtime, in case of missing symbols).
Thanks Diego for another lesson in understanding the magic world of building a software!I am following you blog for a while now and I really like it. Sometimes hard to read, but most of the time not only some blabla, but something where you can learn from.Thanks.
One benefit that I have seen when I switched tousing –as-needed is the number of thing I neededto rebuild with revdep-rebuild after an upgradedropped dramatically.Just for that, it is worth it as you waste less CPUtime rebuilding stuff on Gentoo.
So in short: software which is built suboptimal can benefit. Well done software should see no change, the few cases where the flags hurt are special enough to ask the autors to add –no-as-needed. This allows setting a default helping with all the badly done software.
Mostly yes, David. The problem is that there is, to my knowledge, no perfect build system out there that gets the proper result without @–as-needed@ and that does not rely on very particular systems. This is probably due to the fact that overlink is very common to allow proper static linking.But yes, the bottom line is the same: @–as-needed@ should be the default and it should be @–no-as-needed@ to be special.
Yes, I didn’t think about the cases where the build system adds to many libraries, sometimes with good reason.Of course, much of the trouble stems from people working with the “let’s see wheter it compiles” approach. That way you’ll end up with libs pulled in indirectly only on your particular configuration and stuff which was required at some point in the past but no longer.