Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove dead code when linking static library into dynamic library

Suppose I have the following files:

libmy_static_lib.c:

#include <stdio.h>
void func1(void){
    printf("func1() called from a static library\n");
}
void unused_func1(void){
    printf("printing from the unused function1\n");
}
void unused_func2(void){
    printf("printing from unused function2\n");
}

libmy_static_lib.h:

void func(void);
void unused_func1(void);
void unused_func2(void);

my_prog.c:

#include "libmy_static_lib.h"
#include <stdio.h>
void func_in_my_prog()
{
    printf("in my prog\n");
    func1();

}

And here is how I link the library:

# build the static library libmy_static_lib.a
gcc -fPIC -c -fdata-sections --function-sections -c libmy_static_lib.c -o libmy_static_lib.o
ar rcs libmy_static_lib.a libmy_static_lib.o

# build libmy_static_lib.a into a new shared library
gcc -fPIC -c ./my_prog.c -o ./my_prog.o
gcc -Wl,--gc-sections -shared -m64 -o libmy_shared_lib.so ./my_prog.o -L. -l:libmy_static_lib.a

There are 2 functions in libmy_static_lib.c that are not used, and from this post, I think

gcc fdata-sections --function-sections

should create a symbol for each function, and

gcc -Wl,--gc-sections

should remove the unused symbols when linking

however when I run

nm libmy_shared_lib.so

It is showing that these 2 unused functions are also being linked into the shared library.

Any suggestions on how to have gcc remove the unused functions automatically?

Edit: I am able to use the above options for gcc to remove the unused functions if I am linking a static library directly to executable. But it doesn't remove the unused functions if I link the static library to a shared library.

like image 611
J. Lui Avatar asked Jun 15 '18 19:06

J. Lui


People also ask

What are two disadvantages of static linking of shared libraries?

Slower execution time compared to static libraries. Potential compatibility issues if a library is changed without recompiling the library into memory.

Can you statically link a dynamic library?

You can't statically link a shared library (or dynamically link a static one).

What happens when you link a static library?

Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory.

How do you explain the difference between the static and dynamic library linking?

What are the differences between static and dynamic libraries? Static libraries, while reusable in multiple programs, are locked into a program at compile time. Dynamic, or shared libraries, on the other hand, exist as separate files outside of the executable file.

What is static linking and static libraries?

Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory. Examples of static libraries (libraries which are statically linked) are,.a files in Linux and.lib files in Windows.

Do we still use static libraries in production line software?

Many production line software use static libraries even today. Dynamic linking and Dynamic Libraries Dynamic Linking doesn’t require the code to be copied, it is done by just placing name of the library in the binary file. The actual linking happens when the program is run, when both the binary file and the library are in memory.

Is there dynamic querying of symbols in static libraries?

There will be no dynamic querying of symbols in static libraries. Many production line software use static libraries even today. Dynamic linking and Dynamic Libraries Dynamic Linking doesn’t require the code to be copied, it is done by just placing name of the library in the binary file.

How to create a static library in Unix?

Steps to create a static library Let us create and use a Static Library in UNIX or UNIX like OS. 1. Create a C file that contains functions in your library. 3. Compile library files. 4. Create static library. 1. Create a C file with main function 3. Link the compiled driver program to the static library. 4. Run the driver program


1 Answers

You can use a version script to mark the entry points in combination with -ffunction-sections and --gc-sections.

For example, consider this C file (example.c):

int
foo (void)
{
  return 17;
}

int
bar (void)
{
  return 251;
}

And this version script, called version.script:

{
  global: foo;
  local: *;
};

Compile and link the sources like this:

gcc -Wl,--gc-sections -shared -ffunction-sections -Wl,--version-script=version.script example.c

If you look at the output of objdump -d --reloc a.out, you will notice that only foo is included in the shared object, but not bar.

When removing functions in this way, the linker will take indirect dependencies into account. For example, if you turn foo into this:

void *
foo (void)
{
  extern int bar (void);
  return bar;
}

the linker will put both foo and bar into the shared object because both are needed, even though only bar is exported.

(Obviously, this will not work on all platforms, but ELF supports this.)

like image 126
Florian Weimer Avatar answered Oct 18 '22 15:10

Florian Weimer