我在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添加它?
答案 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
),因此很简单。但是,您需要做的是:
mingw64static-2014-11.tar.xz
)C:\mingw64static
)C:\mingw64static\bin
C:\Anaconda3\Scripts
前面添加Path
环境变量。readme
文件中的说明下载libpython
。 (我用了
{3.4} 64位的libpython-cp34-none-win_amd64.7z
)libmsvcr100.a
,libpython34.dll.a
)解压缩并复制到C:\Python\libs\
目录中(对于Anaconda,它是C:\Anaconda3\libs
)在distutils.cfg
中创建名为C:\Python\Lib\distutils
的文件
目录(对于Anaconda,它是C:\Anaconda3\Lib\distutils
)与
以下内容:
[build]
compiler=mingw32
现在python将在编译cython模块时正确使用mingw-w64
。
答案 1 :(得分:0)
看起来py33环境正在使用Visual Studio(-lmsvcr100
)进行编译。这可能是因为它没有安装libpython
conda包,这导致distutils使用mingw(gcc)来编译而不是Visual Studio。 conda remove libpython
可能会解决Python 3.4环境的问题。