Cython Hello World示例适用于Anacondas Python 3.3,但不适用于3.4

时间:2015-03-30 21:37:33

标签: python-3.x cython anaconda

我在64位Windows机器上使用Anacondas。

我编写了一个hello world Cython示例。它位于文件hello.pyx中,包含:

def say_hello_to(name):
    print("Hello %s!" % name)

我正在使用run_hello.py

运行它
import pyximport; pyximport.install()
import hello as hello

hello.say_hello_to('jon')

安装文件是setup.py:

from distutils.core import setup
from Cython.Build import cythonize

setup(
  name = 'Hello world app',
  ext_modules = cythonize("hello.pyx"),
)

然后我使用以下代码在Anacondas上编译Python 3.3中的代码:

> activate py33
> python setup.py build_ext --inplace

(请注意py33是我的Python 3.3环境)

然后我可以运行示例:

python run_hello.py

打印出“Hello jon!”如预期的那样。

现在,如果我将我的环境更改为Python 3.4并编译:

> activate py34
> python setup.py build_ext --inplace

我没有错误,shell显示

running build_ext

但是,如果我尝试使用以下命令从py34环境运行run_hello.py:

python run_hello.py

我明白了:

Traceback (most recent call last):
  File "run_hello.py", line 2, in <module>
    import hello as hello
ImportError: DLL load failed: The specified module could not be found.

错误不是很具描述性。我能做些什么来帮助我在Python 3.4上完成这项工作?


如果我从硬盘中删除hello.c和/ build文件夹,尝试从Python 3.4编译返回:

Compiling hello.pyx because it changed.
Cythonizing hello.pyx
running build_ext
building 'hello' extension
creating build
creating build\temp.win-amd64-3.4
creating build\temp.win-amd64-3.4\Release
C:\Anaconda\envs\py34\Scripts\gcc.bat -mdll -O -Wall -IC:\Anaconda\envs\py34\include -IC:\Anaconda\envs\py34\include -c hello.c -o build\temp.win-amd64-3.4\Release\hello.o
writing build\temp.win-amd64-3.4\Release\hello.def
C:\Anaconda\envs\py34\Scripts\gcc.bat -shared -s build\temp.win-amd64-3.4\Release\hello.o build\temp.win-amd64-3.4\Release\hello.def -LC:\Anaconda\envs\py34\libs -LC:\Anaconda\envs\py34\PCbuild\amd64
-lpython34 -lmsvcr100 -o c:\Users\Jon\Documents\GitHub\CythonFunctions\example1\hello.pyd
build\temp.win-amd64-3.4\Release\hello.o:hello.c:(.text+0x314): undefined reference to `__imp__PyThreadState_Current'
build\temp.win-amd64-3.4\Release\hello.o:hello.c:(.text+0x493): undefined reference to `__imp__Py_NoneStruct'
build\temp.win-amd64-3.4\Release\hello.o:hello.c:(.text+0x97b): undefined reference to `__imp_PyExc_ImportError'
collect2.exe: error: ld returned 1 exit status
error: command 'C:\\Anaconda\\envs\\py34\\Scripts\\gcc.bat' failed with exit status 1

如果我对Python 3.3做同样的事情,我会得到:

Compiling hello.pyx because it changed.
Cythonizing hello.pyx
running build_ext
building 'hello' extension
creating build
creating build\temp.win-amd64-3.3
creating build\temp.win-amd64-3.3\Release
C:\Anaconda\envs\py33\Scripts\gcc.bat -DMS_WIN64 -mdll -O -Wall -IC:\Anaconda\envs\py33\include -IC:\Anaconda\envs\py33\include -c hello.c -o build\temp.win-amd64-3.3\Release\hello.o
writing build\temp.win-amd64-3.3\Release\hello.def
C:\Anaconda\envs\py33\Scripts\gcc.bat -DMS_WIN64 -shared -s build\temp.win-amd64-3.3\Release\hello.o build\temp.win-amd64-3.3\Release\hello.def -LC:\Anaconda\envs\py33\libs -LC:\Anaconda\envs\py33\PCb
uild\amd64 -lpython33 -lmsvcr100 -o c:\Users\Jon\Documents\GitHub\CythonFunctions\example1\hello.pyd

其他一些遇到“gcc.bat失败并退出状态为1”的用户发现问题是由于32/64位冲突造成的。

在py33版本的编译数据中,gcc.bat参数中有-DMS_WIN64,但它不在py34参数中。这可能是导致我的问题的原因吗?如果是这样,我如何让py34添加它?

2 个答案:

答案 0 :(得分:2)

我几年来一直使用TDM-GCC作为64位编译器和Python 2.7 64位没有任何问题,但是在安装Python 3.4 64位后,我在编译Cython模块时遇到了问题。

我相信我用mingw-w64-for-python解决了这个问题。 (另请查看此github issue)。

有一个自述文件(目前为mingwpy-2015-04-readme.pdf),因此很简单。但是,您需要做的是:

  1. 下载mingwpy x86-64工具链(64位)(目前mingw64static-2014-11.tar.xz
  2. 将文件解压缩到目录(例如C:\mingw64static
  3. C:\mingw64static\bin C:\Anaconda3\Scripts前面添加Path 环境变量。
  4. 按照readme文件中的说明下载libpython。 (我用了 {3.4} 64位的libpython-cp34-none-win_amd64.7z
  5. 将存档中的文件(libmsvcr100.alibpython34.dll.a)解压缩并复制到C:\Python\libs\目录中(对于Anaconda,它是C:\Anaconda3\libs
  6. distutils.cfg中创建名为C:\Python\Lib\distutils的文件 目录(对于Anaconda,它是C:\Anaconda3\Lib\distutils)与 以下内容:

    [build]
    
    compiler=mingw32
    
  7. 现在python将在编译cython模块时正确使用mingw-w64

答案 1 :(得分:0)

看起来py33环境正在使用Visual Studio(-lmsvcr100)进行编译。这可能是因为它没有安装libpython conda包,这导致distutils使用mingw(gcc)来编译而不是Visual Studio。 conda remove libpython可能会解决Python 3.4环境的问题。