gcclinkershared-libraries

Remove unused functions from shared library


Consider the following files:

foo.c

void
bar(void);

void
foo(void)
{
    bar();
}

bar.c

#include <stdio.h>

void
bar(void)
{
    printf("bar\n");
}

void
baz(void)
{
    printf("baz\n");
}

vis.map

{
    global:
        foo;
    local:
        *;
};

I've compiled them into a library by

gcc -c -ffunction-sections foo.c
gcc -c -ffunction-sections bar.c
gcc -Wl,--version-script,vis.map -shared -o libfoo.so foo.o bar.o

As expected, nm -D libfoo.so shows only the foo symbol. However, objdump -d libfoo.so shows the code for baz. I would have thought, given that it's unreachable from the only visible function, that the linker would have removed baz from the final output.

Is there a linker flag or something to accomplish this?

For context, bar.c represents code from another project that I'm trying to use in my project. So, it's infeasible to alter it.


Solution

  • The --gc-sections linker flag does the trick. According to man ld, it

    [enables] garbage collection of unused input sections.

    Since you're compiling with -ffunction-sections, each function will be put into its own section. Adding -Wl,--gc-sections to your final gcc invocation will remove the unused baz section.