简体   繁体   English

将复杂的链接标志从Makefile传递到setup.py

[英]Passing complex linking flags from Makefile to setup.py

I am writing Python 2.7 C++ extension. 我正在编写Python 2.7 C ++扩展。 The Python extension wraps part of C++ library (Kaldi). Python扩展包装了C ++库(Kaldi)的一部分。 Previously I created shared library and distributed it with the Python extension. 以前,我创建了共享库,并使用Python扩展分发了它。 (I needed set up LD_LIBRARY_PATH). (我需要设置LD_LIBRARY_PATH)。

I want to compile the extension statically. 我想静态地编译扩展。 The Kaldi library can be compiled statically (with -fPIC flag). 可以静态编译Kaldi库(带有-fPIC标志)。 The problem is that the compilation depends on other libraries and flags are generated by the configure script. 问题在于编译依赖于其他库,并且标志由configure脚本生成。

I want to compile the extension using setup.py and "steal" the compilation setup from Makefile . 我想使用setup.py编译扩展名并从Makefile “窃取”编译设置。 How would you do it? 你会怎么做?

The command for linking the shared library was: 链接共享库的命令是:

$(CXX) -shared -DPIC -o $@ -Wl,-soname=$@,--whole-archive $^ -Wl,--no-whole-archive $(EXTRA_LDLIBS) $(LDFLAGS) $(LDLIBS)

In the setup.py I had: setup.py我有:

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

The $(EXTRA_LDLIBS) , $(LDFLAGS) and $(LDLIBS) are generated by configure script. $(EXTRA_LDLIBS)$(LDFLAGS)$(LDLIBS)configure脚本生成。 The $(LDLIBS) contains some static libraries some shared. $(LDLIBS)包含一些共享的静态库。

NOW I have 我现在有

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'],
                             ))

Note 1: I am using Cython, but it should not matter. 注意1:我正在使用Cython,但这没关系。

Note 2: I know I can compile the extension using make , I would prefer setup.py for better deployment. 注意2:我知道我可以使用make编译扩展,我希望使用setup.py进行更好的部署。

You would have to link a static extension to python when you build the python executable. 构建python可执行文件时,您必须将静态扩展链接到python。

That is because extensions are loaded into the interpreter using dlopen (or LoadLibrary on Windows) and this functionality can not support static 'libraries' which are nothing more than a tarball of the object files. 这是因为扩展是使用dlopen(或Windows上的LoadLibrary)加载到解释器中的,并且此功能不能支持静态“库”,而静态“库”仅是目标文件的压缩文件。 Object files are a raw form still unusable by the system runtime until they've gone through a linking phase. 目标文件是原始格式,直到经过链接阶段后,系统运行时仍无法使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM