如何使用gcc编译Cython的.c代码

27

现在我已经在Windows 7上成功安装了Cython,我尝试使用Cython编译一些Cython代码,但是gcc让我的生活变得困难。

cdef void say_hello(name):
    print "Hello %s" % name

使用gcc编译代码时,会抛出数十个 undefined reference to 错误,我很确定 libpython.a 是可用的(因为安装教程说了,如果缺少此文件将会引发 undefined reference to 错误)。

$ cython ctest.pyx
$ gcc ctest.c -I"C:\Python27\include"

C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1038): undefined reference to `_imp__PyString_FromStringAndSize'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1075): undefined reference to `_imp___Py_TrueStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1086): undefined reference to `_imp___Py_ZeroStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1099): undefined reference to `_imp___Py_NoneStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x10b8): undefined reference to `_imp__PyObject_IsTrue'
c:/program files/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
奇怪的是,使用pyximport*或者setup脚本都可以正常工作,但当仍在一个模块上工作时,它们都不太方便。

如何使用gcc编译使用Cython生成的那些.c文件?

或使用任何其他编译器,重要的是它能正常工作! *pyximport:只有Python本地函数和类被包含在导入模块中而不是cdef函数和类,这正常吗?例如:
# filename: cython_test.pyx
cdef c_foo():
    print "c_foo !"
def foo():
    print "foo !"
    c_foo()

import pyximport as p; p.install()
import cython_test
cython_test.foo()
# foo !\nc_foo !
cython_test.c_foo()
# AttributeError, module object has no attribute c_foo

更新

调用 $ gcc ctest.c "C:\Python27\libs\libpython27.a" 可以消除未定义的引用错误,但仍会出现以下错误:

c:/program files/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined reference to `WinMain@16'

"undefined reference to `WinMain@16'" 的意思是 gcc 在寻找(但没有找到)“main”入口点。例如,请参见 https://dev59.com/9W435IYBdhLWcg3wtSYV。 - Francesco
2个回答

21

试试这样做:

gcc -c -IC:\Python27\include -o ctest.o ctest.c
gcc -shared -LC:\Python27\libs -o ctest.pyd ctest.o -lpython27

-shared 用于创建共享库。-lpython27 与导入库 C:\Python27\libs\libpython27.a 进行链接。


太棒了,.pyd文件已经编译成功了!我可以将它包含到Python中。 cdefs不能从Python中调用吗?那么我是不是必须为每个cdef编写一个def-wrapper?我会去检查一下的! - Niklas R
非常重要:如果在“ctest.c -o ctest.pyd”之前放置“-lpython27”,它就无法工作... - Saullo G. P. Castro
@SaulloCastro:我编辑了命令,试图使顺序更清晰。 - Eryk Sun

1

这是一个链接器(ld)错误,而不是编译器错误。你应该提供库的路径(-l和-L),而不仅仅是头文件的路径(-I)。


不幸的是,添加“-L”C:\Python27\libs”并不能解决这个问题。 - Niklas R
使用-I"C:\Python27\libs\libpython.a",gcc告诉我-I不是一个目录。顺便说一下,请注意更新的问题。 - Niklas R
这是小写的L,不是大写的i。 - Francesco
啊,抱歉。这样做(gcc ctest.c -l "C:\Python27\libs\libpython27.a")会导致这个错误,真的很令人困惑。这个文件是存在的。c:/program files/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../../mingw32/bin/ld.exe: cannot find -lC:\Python27\libs\libpython27.a - Niklas R
是的,“version”是相同的,-L是库目录的路径,而-l指定了库的名称 :-) - Francesco
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接