如何优化共享库的大小?

art*_*stv 11 c++ optimization shared-libraries android-ndk

假设我们有很多不必要的功能巨大的静态库(在下面的例子中,我们有图书馆lib1.a,并lib2.a与不需要的功能g1()f2()).

我们想用一些导出的方法构建共享库,这些方法只使用那些巨大的库中的一些函数/类.请参见下面的示例:我们要导出函数foo().

质询

  1. 我们可以告诉linker(ld)我们想要导出哪些函数/方法(就像我们在Windows中为DLL做的那样)?
  2. 链接器可以解析依赖并删除不需要的函数/方法吗?或者还有其他方法可以解决问题吗?
  3. 如果您有解决方案,请写下以下示例的修复程序.

档案1.h:

int f1( int n );
int g1( int n );
Run Code Online (Sandbox Code Playgroud)

档案2.h:

int f2( int n );
Run Code Online (Sandbox Code Playgroud)

档案foo.cpp:

#include "1.h"
#include "2.h"

int foo( int n )
{
    return f1( n );
}
Run Code Online (Sandbox Code Playgroud)

档案1.cpp:

int f1( int n ) { return n; }
int g1( int n ) { return n; }
Run Code Online (Sandbox Code Playgroud)

档案2.cpp:

int f2( int n ) { return n; }
Run Code Online (Sandbox Code Playgroud)

档案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
Run Code Online (Sandbox Code Playgroud)

制定目标后,all我们有nm res/libFoo.so:

...
000001d8 T _Z2f1i
0000020e T _Z2g1i
000001c4 T _Z3fooi
...
Run Code Online (Sandbox Code Playgroud)

因此根据目标文件之间的依赖关系ld删除了2.o目标文件.但并没有消除功能g1()1.o.

Emp*_*ian 3

首先,正如 Basile 指出的,您应该-fPIC在构建时添加标志lib{1,2}.a

其次,您可以获得所有1.o链接,因为这就是UNIX 链接器的工作方式

最简单的解决方案(比使用简单得多)是通过添加到链接行-flto来打开链接器垃圾收集,并使用进行构建。这将有效地将每个功能变成自己单独的“书”。-Wl,--gc-sectionslibFoo.solib{1,2}.a-ffunction-sections -fdata-sections