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

时间:2013-12-20 14:32:39

标签: c++ python makefile setuptools setup.py

我正在编写Python 2.7 C ++扩展。 Python扩展包含了C ++库(Kaldi)的一部分。 以前我创建了共享库并使用Python扩展分发它。 (我需要设置LD_LIBRARY_PATH)。

我想静态编译扩展名。可以静态编译Kaldi库(带-fPIC标志)。问题是编译依赖于其他库,并且configure脚本生成了标志。

我想使用setup.py编译扩展程序并从Makefile“窃取”编译设置。 你会怎么做?

链接共享库的命令是:

$(CXX) -shared -DPIC -o $@ -Wl,-soname=$@,--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更好地部署。

1 个答案:

答案 0 :(得分:0)

在构建 python 可执行文件时,您必须将静态扩展链接到python。

这是因为使用dlopen(或Windows上的LoadLibrary)将扩展加载到解释器中,并且此功能不支持静态“库”,它们只不过是目标文件的tarball。对象文件是系统运行时仍然无法使用的原始表单,直到它们经历了链接阶段。