2013-12-20 41 views
1

我正在編寫Python 2.7 C++擴展。 Python擴展包裝了C++庫(Kaldi)的一部分。 以前我創建了共享庫並使用Python擴展分發它。 (我需要設置LD_LIBRARY_PATH)。將複雜鏈接標誌從Makefile傳遞到setup.py

我想靜態地編譯擴展名。 Kaldi庫可以靜態編譯(使用-fPIC標誌)。問題是編譯依賴於其他庫和標誌由configure腳本生成。

我想使用setup.py編譯擴展名,並從Makefile「竊取」編譯設置。 你會怎麼做?

爲共享庫鏈接的命令是:

$(CXX) -shared -DPIC -o [email protected] -Wl,[email protected],--whole-archive $^ -Wl,--no-whole-archive $(EXTRA_LDLIBS) $(LDFLAGS) $(LDLIBS) 

setup.py我有:

ext_modules.append(Extension('pykaldi.decoders', 
         language='c++', 
         include_dirs=['..', 'fst'], 
         library_dirs=['.'], 
         libraries=['pykaldi'], 
         sources=['pykaldi/decoders.pyx'], 
         )) 

$(EXTRA_LDLIBS)的,$(LDFLAGS)$(LDLIBS)configure腳本生成。 $(LDLIBS)包含一些共享的靜態庫。

我現在已經

if STATIC: 
    # STATIC 
    # TODO extract linking parameters from Makefile 
    library_dirs, libraries = [], [] 
    extra_objects = ['pykaldi.a', ] 
else: 
    # DYNAMIC 
    library_dirs = ['.'], 
    libraries = ['pykaldi'] 
    extra_objects = [] 
ext_modules.append(Extension('pykaldi.decoders', 
          language='c++', 
          include_dirs=['..', 'fst'], 
          library_dirs=library_dirs, 
          libraries=libraries, 
          extra_objects=extra_objects, 
          sources=['pykaldi/decoders.pyx'], 
          )) 

注1:我用用Cython,但它不應該的問題。注2:我知道我可以使用make編譯擴展名,我更喜歡setup.py以獲得更好的部署。

回答

0

當您構建python可執行文件時,您將必須將靜態擴展名鏈接到python。

這是因爲使用dlopen(或Windows上的LoadLibrary)將擴展加載到解釋器中,並且此功能無法支持靜態「庫」,它們只不過是對象文件的tarball。對象文件是系統運行時仍然不能使用的原始表單,直到它們經歷了一個鏈接階段。