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

前端 未结 11 2095
北荒
北荒 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:23

    From the GCC 4.2.1 manual, section -fwhole-program:

    Assume that the current compilation unit represents whole program being compiled. All public functions and variables with the exception of main and those merged by attribute externally_visible become static functions and in a affect gets more aggressively optimized by interprocedural optimizers. While this option is equivalent to proper use of static keyword for programs consisting of single file, in combination with option --combine this flag can be used to compile most of smaller scale C programs since the functions and variables become local for the whole combined compilation unit, not for the single source file itself.

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

    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.

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

    You'll want to check your docs for your version of gcc & ld:

    However for me (OS X gcc 4.0.1) I find these for ld

    -dead_strip
    

    Remove functions and data that are unreachable by the entry point or exported symbols.

    -dead_strip_dylibs
    

    Remove dylibs that are unreachable by the entry point or exported symbols. That is, suppresses the generation of load command commands for dylibs which supplied no symbols during the link. This option should not be used when linking against a dylib which is required at runtime for some indirect reason such as the dylib has an important initializer.

    And this helpful option

    -why_live symbol_name
    

    Logs a chain of references to symbol_name. Only applicable with -dead_strip. It can help debug why something that you think should be dead strip removed is not removed.

    There's also a note in the gcc/g++ man that certain kinds of dead code elimination are only performed if optimization is enabled when compiling.

    While these options/conditions may not hold for your compiler, I suggest you look for something similar in your docs.

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

    Programming habits could help too; e.g. add static to functions that are not accessed outside a specific file; use shorter names for symbols (can help a bit, likely not too much); use const char x[] where possible; ... this paper, though it talks about dynamic shared objects, can contain suggestions that, if followed, can help to make your final binary output size smaller (if your target is ELF).

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

    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.

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