Say we have huge static libraries with lots of unneeded features (in the example below we have libraries lib1.a and lib2.a with unneeded functions g1() and f2()).
We want to build shared library with a few exported methods which use only a few functions/classes from that huge libraries. See example below: we want to export function foo().
QUESTIONS
- Can we tell linker (
ld) which functions/methods we want to export (like we do it for DLL in Windows)? - Can linker resolve dependecies and remove unneeded functions/methods? Or is there any other way to solve the problem?
- If you have a solution, please, write the fixes for the example below.
EXAMPLE
File 1.h:
int f1( int n );
int g1( int n );
File 2.h:
int f2( int n );
File foo.cpp:
#include "1.h"
#include "2.h"
int foo( int n )
{
return f1( n );
}
File 1.cpp:
int f1( int n ) { return n; }
int g1( int n ) { return n; }
File 2.cpp:
int f2( int n ) { return n; }
File makefile:
CXXFLAGS = -g -I. -Wall -Wno-sign-compare
all: prepare libFoo.so
clean:
rm -f obj/*.a obj/*.o res/*.so
prepare:
mkdir -p src
mkdir -p obj
mkdir -p res
lib1.a lib2.a: lib%.a: %.o
ar r obj/$@ obj/$*.o
1.o 2.o foo.o: %.o:
g++ $(CXXFLAGS) -c -o obj/$@ src/$*.cpp
libFoo.so: lib1.a lib2.a foo.o
ld -shared -o res/libFoo.so obj/foo.o -Lobj -l1 -l2
And after making target all we have nm res/libFoo.so:
...
000001d8 T _Z2f1i
0000020e T _Z2g1i
000001c4 T _Z3fooi
...
So ld has removed 2.o object file according to dependencies between object files. But didn’t remove function g1() from 1.o.
First, as Basile pointed out, you should add
-fPICflag when buildinglib{1,2}.a.Second, you get all of
1.olinked in because that’s how UNIX linkers work.The simplest solution (much simpler than using
-flto) is to turn on linker garbage collection by adding-Wl,--gc-sectionstolibFoo.solink line, and to buildlib{1,2}.awith-ffunction-sections -fdata-sections. This will effectively turn each function into its own separate “book”.