How to remove unused C/C++ symbols with GCC and ld?

前端 未结 11 2094
北荒
北荒 2020-11-22 09:46

I need to optimize the size of my executable severely (ARM development) and I noticed that in my current build scheme (gcc + ld) unuse

相关标签:
11条回答
  • 2020-11-22 10:09

    It seems to me that the answer provided by Nemo is the correct one. If those instructions do not work, the issue may be related to the version of gcc/ld you're using, as an exercise I compiled an example program using instructions detailed here

    #include <stdio.h>
    void deadcode() { printf("This is d dead codez\n"); }
    int main(void) { printf("This is main\n"); return 0 ; }
    

    Then I compiled the code using progressively more aggressive dead-code removal switches:

    gcc -Os test.c -o test.elf
    gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections
    gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections -Wl,--strip-all
    

    These compilation and linking parameters produced executables of size 8457, 8164 and 6160 bytes, respectively, the most substantial contribution coming from the 'strip-all' declaration. If you cannot produce similar reductions on your platform,then maybe your version of gcc does not support this functionality. I'm using gcc(4.5.2-8ubuntu4), ld(2.21.0.20110327) on Linux Mint 2.6.38-8-generic x86_64

    0 讨论(0)
  • 2020-11-22 10:15

    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.

    0 讨论(0)
  • 2020-11-22 10:16

    For GCC, this is accomplished in two stages:

    First compile the data but tell the compiler to separate the code into separate sections within the translation unit. This will be done for functions, classes, and external variables by using the following two compiler flags:

    -fdata-sections -ffunction-sections
    

    Link the translation units together using the linker optimization flag (this causes the linker to discard unreferenced sections):

    -Wl,--gc-sections
    

    So if you had one file called test.cpp that had two functions declared in it, but one of them was unused, you could omit the unused one with the following command to gcc(g++):

    gcc -Os -fdata-sections -ffunction-sections test.cpp -o test -Wl,--gc-sections
    

    (Note that -Os is an additional compiler flag that tells GCC to optimize for size)

    0 讨论(0)
  • 2020-11-22 10:17

    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.

    0 讨论(0)
  • 2020-11-22 10:20

    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.

    0 讨论(0)
  • 2020-11-22 10:20

    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.

    0 讨论(0)
提交回复
热议问题