【问题标题】:Cython compiled ok, but Symbol not found: __ZNSs4_Rep20_S_empty_rep_storageE when running on Mac OSCython 编译正常,但在 Mac OS 上运行时找不到符号:__ZNSs4_Rep20_S_empty_rep_storageE
【发布时间】:2018-08-27 10:51:09
【问题描述】:

系统:Mac OS 10.12.6。 Python:来自 Anconda3 的 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

【问题讨论】:

  • 那是 _std::string::_Rep::_S_empty_rep_storage 的 C++ 名称修改。像这样的错误通常意味着您将一些代码编译为 C++,但随后没有与 C++ 标准库链接。在这种情况下,大概是 libLexActivator.a 需要 C++ 标准库。如果是这样,两个选项是:(1)添加 language="c++" 以便 Cython 将所有内容构建为 C++,或(2)添加适当的 libc++libstdc++ 或类似的作为额外的库。
  • 嗨,@abarnert 当我使用language="c++" 时,还有另一个错误Symbol not found: _kSCPropNetProxiesHTTPPort
  • 这是一个不同的问题。 _kSCPropNetProxiesHTTPPortCoreFoundation 框架的一部分,因此您还需要链接 that。与其一步一步地尝试找出每个错误的来源,是否有一些关于针对libLexActivator.a 构建可执行文件/dylib 的文档?如果没有,是否有 Makefile(或它使用的任何构建系统)?
  • @abarnert 我认为你可能是对的。我已经在 Xcode 中成功使用了这个静态库。我添加了两个额外的库CoreFoundation.frameworkSystemConfiguration.framework。我在 Xcode 中使用了c++ 编译器。
  • 好的,这正是您在 Cython 中需要做的事情。我很确定有一种正确的方法可以在setupExtension 构造函数中指定框架(而不是假装它们只是奇怪的LDFLAGS),但我不记得它是什么。尝试搜索,如果找不到,我也可以尝试。

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


【解决方案1】:

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

这显然是 C++ 标准库的一部分。问题是您已经编译了一些代码以使用 C++ std::string,但尚未链接 C++ 标准库。这不是你的 Cython 生成的代码,也不是 Python,所以大概是 libLexActivator.a

解决此问题的简单方法是通过在您的 cythonize 调用中添加 language="c++" 来添加 have Cython compile all of your code as C++ instead of C。这比您需要的要极端一些,但可能没问题。

或者,您可以选择正确的 C++ 标准库并链接到该标准库。这与 Mac 上的 clang 有点混淆,因为其中有两个,libc++libstdc++。最近的版本默认为前者(libc++ 是一个较新的实现,由 LLVM/Clang 团队构建,可以更好地与 C++11 及更高版本一起工作)。但是如果你正在为 10.6 构建,我不确定这是否仍然正确。所以你可能需要研究一下(或者请教 C++、Mac 和 Clang 相关标签的专家),或者两者都试试看。


从您的 cmets 中,修复该问题后,您会得到另一个丢失的符号 _kSCPropNetProxiesHTTPPort。这种独特的命名风格几乎可以肯定意味着它是由 Apple 的 CoreFoundation 框架内的某个东西或位于它之上的其他 C 框架之一导出的常量。但不要猜测,只需将其粘贴到您最喜欢的搜索引擎中,您就会找到the docs,这表明它是SystemConfiguration 框架的一部分。因此,您还需要将其添加到构建中。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 2014-02-11
    • 2019-08-21
    • 2019-03-14
    相关资源
    最近更新 更多