Am 20.12.2011, 19:14 Uhr, schrieb dsimcha <dsim...@yahoo.com>:
I started poking around and examining the details of how the GNU linker
works, to solve some annoying issues with LDC. In the process I the
following things that may be useful low-hanging fruit for reducing
binary size:
1. If you have an ar library of object files, by default no dead code
elimination is apparently done within an object file, or at least not
nearly as much as one would expect. Each object file in the ar library
either gets pulled in or doesn't.
2. When something is compiled with -lib, DMD writes libraries with one
object file **per function**, to get around this. GDC and LDC don't.
However, if you compile the object files and then manually make an
archive with the ar command (which is common in a lot of build
processes, such as gtkD's), this doesn't apply.
3. The defaults can be overridden if you compile your code with
-ffunction-sections and -fdata-sections (DMD doesn't support this, GDC
and LDC do) and link with --gc-sections. -ffunction-sections and
-fdata-sections cause each function or piece of static data to be
written as its own section in the object file, instead of having one
giant section that's either pulled in or not. --gc-sections garbage
collects unused sections, resulting in much smaller binaries especially
when the sections are fine-grained.
On one project I'm working on, I compiled all the libs I use with GDC
using -ffunction-sections -fdata-sections. The stripped binary is 5.6
MB when I link the app without --gc-sections, or 3.5 MB with
--gc-sections. Quite a difference. The difference would be even larger
if Phobos were compiled w/ -ffunction-sections and -fdata-sections.
(See
https://bitbucket.org/goshawk/gdc/issue/293/ffunction-sections-fdata-sections-for
).
DMD can't compile libraries with -ffunction-sections or -fdata-sections
and due to other details of my build process that are too complicated to
explain here, the results from DMD aren't directly comparable to those
from GDC. However, --gc-sections reduces the DMD binaries from 11 MB to
9 MB.
Bottom line: If we want to reduce D's binary size there are two pieces
of low-hanging fruit:
1. Make -L--gc-sections the default in dmd.conf on Linux and probably
other Posix OS's.
2. Add -ffunction-sections and -fdata-sections or equivalents to DMD
and compile Phobos with these enabled. I have no idea how hard this
would be, but I imagine it would be easy for someone who's already
familiar with object file formats.
Nice of you to start some discussion on these flags. I use them myself
(and a few others that seem to affect code size) in a 'tiny' target inside
the D Makefile I use.
Currently it looks like this:
dmd <sources,directory,bin> -m32 -O -release -noboundscheck -L--strip-all
-L-O1 -L-znodlopen -L-znorelro -L--no-copy-dt-needed-entries -L--relax
-L--sort-common -L--gc-sections -L-lrt -L--as-needed
strip <bin> -R .comment -R .note.ABI-tag -R .gnu.hash -R .gnu.version -R
.jcr -R .got
That's not even funny, I know :D