art*_*stv 11 c++ optimization shared-libraries android-ndk
假设我们有很多不必要的功能巨大的静态库(在下面的例子中,我们有图书馆lib1.a,并lib2.a与不需要的功能g1()和f2()).
我们想用一些导出的方法构建共享库,这些方法只使用那些巨大的库中的一些函数/类.请参见下面的示例:我们要导出函数foo().
质询
ld)我们想要导出哪些函数/方法(就像我们在Windows中为DLL做的那样)?例
档案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.
首先,正如 Basile 指出的,您应该-fPIC在构建时添加标志lib{1,2}.a。
其次,您可以获得所有1.o链接,因为这就是UNIX 链接器的工作方式。
最简单的解决方案(比使用简单得多)是通过添加到链接行-flto来打开链接器垃圾收集,并使用进行构建。这将有效地将每个功能变成自己单独的“书”。-Wl,--gc-sectionslibFoo.solib{1,2}.a-ffunction-sections -fdata-sections