python - Cython 生成重复符号 _PyInit_ 和 ___pyx_module_is_main_

标签 python python-3.x linker cython

当尝试将 Python 代码移植到 cython 时,我收到以下链接器错误消息:

cls ~/workspace/Prototypes/PLPcython $ python3 setup.py build_ext --inplace
running build_ext
cythoning src/graph.pyx to src/graph.c
cythoning src/community.pyx to src/community.c
building 'PLPcython' extension
creating build
creating build/temp.macosx-10.8-x86_64-3.3
creating build/temp.macosx-10.8-x86_64-3.3/src
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c src/graph.c -o build/temp.macosx-10.8-x86_64-3.3/src/graph.o
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c src/community.c -o build/temp.macosx-10.8-x86_64-3.3/src/community.o
src/community.c:1414:19: warning: expression result unused [-Wunused-value]
    PyObject_INIT(o, t);
    ~~~~~~~~~~~~~~^~~~~
/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m/objimpl.h:163:69: note: expanded from macro 'PyObject_INIT'
    ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
                                                                    ^
1 warning generated.
cc -bundle -undefined dynamic_lookup -L/usr/local/lib -L/usr/local/opt/sqlite/lib build/temp.macosx-10.8-x86_64-3.3/src/graph.o build/temp.macosx-10.8-x86_64-3.3/src/community.o -o /Users/cls/workspace/Prototypes/PLPcython/PLPcython.so
duplicate symbol _PyInit_PLPcython in:
    build/temp.macosx-10.8-x86_64-3.3/src/graph.o
    build/temp.macosx-10.8-x86_64-3.3/src/community.o
duplicate symbol ___pyx_module_is_main_PLPcython in:
    build/temp.macosx-10.8-x86_64-3.3/src/graph.o
    build/temp.macosx-10.8-x86_64-3.3/src/community.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'cc' failed with exit status 1

产生了明显重复的符号。什么是 _PyInit_*___pyx_module_is_main_

这是我尝试进行 cythonize 的两个源文件:graph.pyx

class Graph:

    def __init__(self, n=0):
        self.n = n
        self.m = 0  
        self.z = n  # max node id
        self.adja = [[] for i in range(self.z)]
        self.deg = [0 for i in range(self.z)]

    def maxNodeId(self):
        return self.z

    def numberOfNodes(self):
        return self.n

    def numberOfEdges(self):
        return self.m

    def addEdge(self, u, v):
        if (u == v):
            self.adja[u].append(v)
            self.deg[u] += 1
        else:
            self.adja[u].append(v)
            self.adja[v].append(u)
            self.deg[u] += 1
            self.deg[v] += 1
        self.m += 1

    def hasEdge(self, u, v):
        for w in self.adja[u]:
            if w == v:
                return True
        return False 

    def degree(self, u):
        return self.deg[u]

    def forNodes(self, handle):
        # assumtion: all nodes exist
        for u in range(self.z):
            handle(u)

    def forEdges(self, handle):
        for u in range(self.z):
            for v in self.adja[u]:
                if v <= u:
                    handle(u, v)

    def forNeighborsOf(self, u, handle):
        for v in self.adja[u]:
            handle(v)

community.pyx

def numberOfCommunities(zeta, G):
    labels = set()
    for label in zeta:
        if label is not None:
            labels.add(label)
    return len(labels)


def coverage(zeta, G):
    intra = 0
    inter = 0
    m = G.numberOfEdges()

    def scan(u, v):
        nonlocal intra
        nonlocal inter
        if zeta[u] == zeta[v]:
            intra += 1
        else:
            inter += 1

    G.forEdges(scan)

    print("intra-community edges: ", intra)
    print("inter-community edges: ",inter)

    assert (inter + intra == m)
    coverage = intra / m
    return coverage

最佳答案

我相信 Cython 仅支持将单个源文件编译为单个模块。因此,要么将两个文件编译为两个单独的模块,要么使用 include 语句 ( http://docs.cython.org/src/userguide/language_basics.html#the-include-statement ) 将它们组合到单个源文件中。

关于python - Cython 生成重复符号 _PyInit_ 和 ___pyx_module_is_main_,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17744604/

相关文章:

python - 使用elasticsearch-dsl-py在子字段(包含在另一个字段中的字段)上创建查询?

python - python 中的交互式 shell 程序包装

gcc - 将使用 ICC 构建的库与使用 GCC 构建的应用程序链接起来

c - Makefile LINK.cc - main.o 放在链接库之后并导致错误

python - Python 中总计 "CPU hours"

Python Selenium - 如何点击 javascript 按钮

python - 如何在 Python 中将 'X' 的字符串填充到最小长度?

html - 如何在 Twisted 中处理 POST 请求

python - Kivy:AttributeError 具有在 kv 文件中定义的属性

c++ - Visual Studio 警告 C4743 : How does Whole Program Optimization affect _fltused?