Question about LDC and --gc-sections
Joakim
dlang at joakim.fea.st
Fri Oct 26 06:02:51 UTC 2018
On Thursday, 25 October 2018 at 17:19:05 UTC, H. S. Teoh wrote:
> I'm currently working on an Android project that has a
> significant D component, and using LDC to cross-compile to ARM.
> (Much thanks to Joakim, BTW, who wrote detailed instructions on
> the wiki on how to set this up.) Since Android requires a .so
> file, I have to statically link everything into a single .so.
> However, I'm finding that the resulting .so has tons of unused
> symbols that bloat the size to about 5MB (~1.6MB after the
> Android SDK tools compress everything, of which only about
> 100KB is my actual D code).
>
> Since LDC's libdruntime.a and libphobos2.a already have every
> function in its own section, technically the linker *ought* to
> be able to strip out most of the unreferenced sections.
> However, running the linker with --gc-sections doesn't seem to
> reduce the file size significantly, and many unused sections
> are still present. Stripping the file with `strip` afterwards
> still leaves over 10,000 symbols, far too many given the
> current size of my D code, and clearly an indication of a ton
> of stuff in druntime/phobos that I don't actually use. I
> suspect it may be because the target is an .so rather than an
> executable, so the linker may be leaving in all public symbols
> as a precaution.
>
> How do I tell the linker (clang) to drop everything except the
> small handful of entry points required by the Android API?
Apparently this is a problem for C++ too:
https://stackoverflow.com/questions/18115598/how-to-remove-all-unused-symbols-from-a-shared-library
I don't know if D provides some way to change symbol visibility
in object files, not an issue I've looked at.
Btw, are you writing a mostly native app that calls some D code
or a Java app that calls some native code? I ask because I ran
into an issue before depending on how it's set up, though you
won't hit this if you're using D in betterC mode.
The difference is that there are two ways of calling native code
on Android:
1. You can have the Android Java runtime directly call native
code on _startup_ if you provide some standard native functions
that it expects:
https://developer.android.com/ndk/reference/group/native-activity#group___native_activity_1ga02791d0d490839055169f39fdc905c5e
2. You have your Java app call some native functions using JNI.
Both have been tried with D, but the latter may present some
difficulty for initializing the D runtime and GC. When I tried
the latter with a sample app, it seemed to be loading the D
library _every time_ the D functions were called, so I had to add
a call to rt_init every time the function was called:
https://github.com/joakim-noah/android/blob/master/samples/bitmap-plasma/jni/plasma.d#L357
I initially had that call inside the initialization check just
below, and it wouldn't work. I never investigated further though,
as I have no interest in using D that way, I could be completely
off on my guess as to why it didn't work.
For the way I use D and test it, the rt_init is called once on
startup, as noted on the wiki, so everything works:
https://wiki.dlang.org/Build_D_for_Android#Changes_for_Android
Of course, you can always call Java functions through JNI if you
go this route, as the Teapot sample app demonstrates, just
something to consider in how you call D code.
More information about the Digitalmars-d
mailing list