ldc icon indicating copy to clipboard operation
ldc copied to clipboard

core.internal.array.equality causes large, unneeded module to be linked in from library

Open vandys opened this issue 8 months ago • 3 comments

I have a small app, linking against a static library (i.e., a library.a format). It needs only a couple very small things, and yet one of the library's largest members was linking against the app. After much fiddling, I determined that the symbol:

D4core8internal5array8equality__T8__equalsTaTaZQoFNaNbNiNeMxAaMxQeZb

was undefined in my small app (nm shows "U") but was defined in the large library object ("W"). This brought in the whole module, swelling the app executable with the resulting whole chain of dependencies.

This is present in 1.40.1 on x86_64 on Linux. I can easily work around this with a local array compare, but you should ensure that either all uses of this array compare create a local symbol--or none.

I note that curl.o from the supplied library of 1.40.1 has this W symbol, unlike all the other references which are U. Hopefully that can lead you to the cause of this? Otherwise I can make code available, but it's not tiny.

vandys avatar Apr 26 '25 23:04 vandys

The default template emission/culling strategy (try to link to guaranteed-existing instantiation in some imported module) is unpredictable and can cause such unexpected linking baggage. If you don't wanna use LTO to trim down the final size, you can try compiling with -linkonce-templates, which emits templates into every referencing object file (similar to C++).

kinke avatar Apr 27 '25 00:04 kinke

I certainly hope it's a not a long-term plan to accept that any random module can be treated as a dependency of any other random module, without correspondence to anything in the declarations. This isn't just baggage; aren't module initializations going to run? This just seems like a bad idea.

I did try the linkonce-templates (I don't know C++, so its similarity thereof didn't help me understand it), and it did seem to avoid the problem.

vandys avatar Apr 27 '25 21:04 vandys

Well it's been that way for ages, and there are ways to work around it in cases where it's a problem - -allinst to emit all instantiations in one of the object files being compiled for a particular invocation, and LDC-specific -linkonce-templates to emit them recursively into every referencing object file. And of course LTO.

#4258 is another instance of this problem.

kinke avatar Apr 28 '25 10:04 kinke