2011-11-18 90 views
4

當生成帶有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.swgswt_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可以看到多次定義的大量函數,他們的來源,很明顯,對於大多數人來說,使用單一的全局定義是很好的)。

回答

2

我很確定SWIG沒有這樣做的選項。我現在在猜測,但我認爲原因可能是由於使用不同版本的SWIG構建的模塊的可見性而引起的關注。設想以下情況:

兩個庫X和Y都使用SWIG爲其代碼提供了一個接口。他們都選擇在不同的翻譯單元上使「SWIG膠水」可見,以減少代碼大小。如果X和Y都使用相同版本的SWIG,這一切都會很好。如果X使用SWIG 1.1和Y使用SWIG 1.3,會發生什麼?兩個模塊都能正常工作,但取決於平臺如何處理共享對象以及語言本身如何加載它們(RTLD_GLOBAL?)在同一個VM中使用的兩個模塊的組合可能會發生一些非常糟糕的情況。

代碼重複的代價非常低我懷疑 - 在VM和本機代碼之間交換代價通常非常高,這可能會使指令緩存命中略有減少,儘管看到真實基準可能會很有趣。另一方面,這是代碼,沒有用戶需要擔心它,因爲它全部是自動生成的,並且都正確地保留了爲相應版本編寫的接口。

+1

好點。我想這可以通過在名稱中包含某種ABI版本來處理,但將所有內容都設置爲靜態的確實簡單得多,並且不易出錯。增加優化確實也有助於減少開銷:在一個具有優化的實際案例中,每個目標文件的大小約爲4KB;仍然有點膨脹,但我認爲SWIG永遠不會是非常輕量級的...... – snogglethorpe

1

我可能是有點晚了,但這裏是一個解決辦法:

  • 在痛飲(< = 1.3)有-noruntime命令行選項
  • 由於痛飲2.0 -noruntime被廢棄了,所以現在一個應該將-DSWIG_NOINCLUDE傳遞給C預處理器 - 而不是swig本身

我完全不確定這是否正確,但它至少適用於我。我將在SWIG的郵件列表中澄清這個問題。

相關問題