Cython编译好了,但找不到符号:__ZNSs4_Rep20_S_empty_rep_storageE在Mac OS上运行时

时间:2018-03-18 22:27:48

标签: python c++ c++11 clang cython

系统:Mac OS 10.12.6。 Python:来自Anoconda3的Python 3.5.2。用Cython == 0.28。

我用

设置并编译了Cython
# the .pyx file 
from libc.stdint cimport *
cimport CLexActivator
def SetProductFile(filePath):
    cdef bytes py_bytes = filePath.encode()
    cdef const char* c_string = py_bytes
    cdef int32_t status = CLexActivator.SetProductFile(c_string)
    print(status)
    return status

# the setup file
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules=[
    Extension("PyLexActivator",
          sources=["PyLexActivator.pyx"],
          language='c',
          extra_objects=["libLexActivator.a"], 
    )
]
setup(
    name = "PyLexActivator",
    ext_modules = cythonize(ext_modules)
)

我使用python setup.py build_ext --inplace进行编译。

Compiling PyLexActivator.pyx because it changed.
[1/1] Cythonizing PyLexActivator.pyx
running build_ext
building 'PyLexActivator' extension
creating build
creating build/temp.macosx-10.6-x86_64-3.5
/usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/o/anaconda/include -arch x86_64 -I. -I/Users/o/anaconda/include/python3.5m -c PyLexActivator.c -o 
build/temp.macosx-10.6-x86_64-3.5/PyLexActivator.o
/usr/bin/clang -bundle -undefined dynamic_lookup -L/Users/o/anaconda/lib -arch x86_64 build/temp.macosx-10.6-x86_64-3.5/PyLexActivator.o libLexActivator.a -L/Users/o/anaconda/lib -o /path to/PyLexActivator.cpython-35m-darwin.so

运行import PyLexActivator

时出错
dlopen(/path to/PyLexActivator.cpython-35m-darwin.so, 2): 
Symbol not found: __ZNSs4_Rep20_S_empty_rep_storageE
Referenced from: /path to/PyLexActivator.cpython-35m-darwin.so
Expected in: flat namespace
in /path to/PyLexActivator.cpython-35m-darwin.so

我不知道__ZNSs4_Rep20_S_empty_rep_storageE代表什么。由于.pyx使用静态库libLexActivator.a编译,我猜这个错误可能来自未知的引用。但我不知道如何解决它。

我还使用otool -L来显示

PyLexActivator.cpython-35m-darwin.so:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

PS:如果我使用language="c++",则会出现另一个错误Symbol not found: _kSCPropNetProxiesHTTPPort

1 个答案:

答案 0 :(得分:1)

首先,缺少的函数是C ++错位名称。现在大多数编译器都带有解码工具,或者你可以使用像this one这样的在线解码器,它适用于所有非古老版本的clang ++,g ++和MSVC。结果是_std::string::_Rep::_S_empty_rep_storage

这显然是C ++标准库的一部分。问题是您编译了一些代码以使用C ++ std::string,但没有链接C ++ stdlib。这不是你的Cython生成的代码或Python,所以可能是libLexActivator.a

通过在language="c++"电话中添加cythonize,可以轻松解决此问题。have Cython compile all of your code as C++ instead of C。这比你需要的更加极端,但它可能很好。

或者,你可以选择正确的C ++ stdlib并链接到那个。这对Mac上的clang来说有点混乱,因为有两个,libc++libstdc++。最新版本默认为前者(libc++是一个较新的实现,由LLVM / Clang团队构建,可以更好地与C ++ 11及更高版本配合使用)。但如果你的建造时间为10.6,我不确定这是否仍然正确。所以你可能需要研究它(或者询问有关C ++,Mac和Clang相关标签的专家),或者只是尝试两种并看看。

根据您的评论,修复后,您会看到另一个缺失的符号_kSCPropNetProxiesHTTPPort。这种与众不同的命名风格几乎可以肯定意味着它是由Apple的CoreFoundation框架内部或者其他C框架之一导出的常量导出的。但不要猜测,只需将其粘贴到您最喜爱的搜索引擎中,您就会找到the docs,这表明它是SystemConfiguration框架的一部分。因此,您还需要将其添加到构建中。

此时,很明显libLexActivator.a不仅仅是简单的C / POSIX代码;它有一些平台依赖(并且它可能也有第三方依赖,对于我所知道的所有)它需要链接。因此,最好的办法是找到它的文档,看看它与它的链接需要什么。 (如果没有这样的文档,你应该能够从Makefile和/或其他构建工具中找到它,但如果你不知道怎么做,你应该真的问一个单独标记的C ++问题帮助。)