I need to optimize the size of my executable severely (ARM
development) and
I noticed that in my current build scheme (gcc
+ ld
) unused symbols are not getting stripped.
The usage of the arm-strip --strip-unneeded
for the resulting executables / libraries doesn't change the output size of the executable (I have no idea why, maybe it simply can't).
What would be the way (if it exists) to modify my building pipeline, so that the unused symbols are stripped from the resulting file?
I wouldn't even think of this, but my current embedded environment isn't very "powerful" and
saving even 500K
out of 2M
results in a very nice loading performance boost.
Update:
Unfortunately the current gcc
version I use doesn't have the -dead-strip
option and the -ffunction-sections... + --gc-sections
for ld
doesn't give any significant difference for the resulting output.
I'm shocked that this even became a problem, because I was sure that gcc + ld
should automatically strip unused symbols (why do they even have to keep them?).
While not strictly about symbols, if going for size - always compile with
-Os
and-s
flags.-Os
optimizes the resulting code for minimum executable size and-s
removes the symbol table and relocation information from the executable.Sometimes - if small size is desired - playing around with different optimization flags may - or may not - have significance. For example toggling
-ffast-math
and/or-fomit-frame-pointer
may at times save you even dozens of bytes.If this thread is to be believed, you need to supply the
-ffunction-sections
and-fdata-sections
to gcc, which will put each function and data object in its own section. Then you give and--gc-sections
to GNU ld to remove the unused sections.strip --strip-unneeded
only operates on the symbol table of your executable. It doesn't actually remove any executable code.The standard libraries achieve the result you're after by splitting all of their functions into seperate object files, which are combined using
ar
. If you then link the resultant archive as a library (ie. give the option-l your_library
to ld) then ld will only include the object files, and therefore the symbols, that are actually used.You may also find some of the responses to this similar question of use.
The answer is
-flto
. You have to pass it to both your compilation and link steps, otherwise it doesn't do anything.It actually works very well - reduced the size of a microcontroller program I wrote to less than 50% of its previous size!
Unfortunately it did seem a bit buggy - I had instances of things not being built correctly. It may have been due to the build system I'm using (QBS; it's very new), but in any case I'd recommend you only enable it for your final build if possible, and test that build thoroughly.
You can use strip binary on object file(eg. executable) to strip all symbols from it.
Note: it changes file itself and don't create copy.
I don't know if this will help with your current predicament as this is a recent feature, but you can specify the visibility of symbols in a global manner. Passing
-fvisibility=hidden -fvisibility-inlines-hidden
at compilation can help the linker to later get rid of unneeded symbols. If you're producing an executable (as opposed to a shared library) there's nothing more to do.More information (and a fine-grained approach for e.g. libraries) is available on the GCC wiki.