【问题标题】:Cython Hello World Example works on Anacondas Python 3.3, but not 3.4Cython Hello World 示例适用于 Anacondas Python 3.3,但不适用于 3.4
【发布时间】:2015-03-30 21:37:33
【问题描述】:

我在 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

打印出“你好,乔恩!”正如预期的那样。

现在,如果我将环境更改为 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 failed with exit status 1”的用户发现问题是由于32/64位冲突造成的。

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

【问题讨论】:

    标签: python-3.x cython anaconda


    【解决方案1】:

    多年来,我一直使用 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. Path 中的C:\Anaconda3\Scripts 前面添加C:\mingw64static\bin 环境变量。
    4. 按照readme 文件中的说明下载libpython。 (我用了 libpython-cp34-none-win_amd64.7z 适用于 Python 3.4 64 位)
    5. 解压并复制存档中的文件(libmsvcr100.alibpython34.dll.a)到C:\Python\libs\目录(对于Anaconda,它是C:\Anaconda3\libs
    6. 在您的C:\Python\Lib\distutils 中创建一个名为distutils.cfg 的文件 目录(对于 Anaconda,它是 C:\Anaconda3\Lib\distutils) 以下内容:

      [build]
      
      compiler=mingw32
      

    现在,当您编译 cython 模块时,python 将正确使用 mingw-w64

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,但 py33 和 py34 都在使用 -lmsvcr100 选项。
      • 抱歉,我没有在 3.4 输出中看到它。删除 libpython 可以解决问题吗?
      • 我尝试删除它,但它似乎没有安装在我的 py34 环境中。
      • 根据github.com/ContinuumIO/anaconda-issues/issues/…,可以尝试使用mingwstatic。
      猜你喜欢
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 2016-05-04
      • 2014-04-26
      • 1970-01-01
      • 2015-03-07
      相关资源
      最近更新 更多