当生成带有SWIG的接口模块时,生成的C/C++文件包含大量静态样板函数。因此,如果想要在同一个应用程序中使用许多单独编译的小接口来模块化使用SWIG生成的接口,则由于这些重复的功能而导致大量的膨胀。当使用许多SWIG生成的模块时避免重复的SWIG样板
使用gcc的-ffunction-sections
选项,以及GNU链接器的--icf=safe
选项(-Wl,--icf=safe
编译器),可以去掉一些重复的,但绝不是所有的(我认为它不会合并任何有搬迁在其中 - 这些功能中的许多功能)。
我的问题:我想知道是否有办法删除更多这种重复的样板,理想情况下不依赖于GNU特定的编译器/链接器选项。
特别是,是否有SWIG选项/标记/说“不在每个输出文件中包含样板”?其实是 SWIG选项,-external-runtime
,它告诉它产生一个“样板只”的输出文件,但没有明显的方式来抑制包含在每个正常输出文件中的副本。 [我认为这样的事情在SWIG中应该相当简单,所以我很惊讶它似乎并不存在......但我似乎无法找到任何记录。]
这是一个小例子:
鉴于接口文件swg-oink.swg
的模块swt_oink
:
%module swt_oink
%{ extern int oinker (const char *x); %}
extern int oinker (const char *x);
...和类似的接口swg-barf.swg
为swt_barf
:
%module swt_barf
%{ extern int barfer (const char *x); %}
extern int barfer (const char *x);
...和测试主文件,swt-main.cc
:
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
extern int luaopen_swt_oink (lua_State *);
extern int luaopen_swt_barf (lua_State *);
}
int main()
{
lua_State *L = lua_open();
luaopen_swt_oink (L);
luaopen_swt_barf (L);
}
int oinker (const char *) { return 7; }
int barfer (const char *) { return 2; }
和编译他们像:
swig -lua -c++ swt-oink.swg
g++ -c -I/usr/include/lua5.1 swt-oink_wrap.cxx
swig -lua -c++ swt-barf.swg
g++ -c -I/usr/include/lua5.1 swt-barf_wrap.cxx
g++ -c -I/usr/include/lua5.1 swt-main.cc
g++ -o swt swt-main.o swt-oink_wrap.o swt-barf_wrap.o
那么每个XXX_wrap.o
文件的大小是16KB左右,其中95%是样板文件,最终可执行文件的大小大概是这些的总和,约为39K。如果用-ffunction-sections
编译每个接口文件,并链接到-Wl,--icf=safe
,最终可执行文件的大小是34KB,但仍然有很多重复(在可执行文件上使用nm
可以看到多次定义的大量函数,他们的来源,很明显,对于大多数人来说,使用单一的全局定义是很好的)。
好点。我想这可以通过在名称中包含某种ABI版本来处理,但将所有内容都设置为静态的确实简单得多,并且不易出错。增加优化确实也有助于减少开销:在一个具有优化的实际案例中,每个目标文件的大小约为4KB;仍然有点膨胀,但我认为SWIG永远不会是非常轻量级的...... – snogglethorpe