Cython用Visual Studio(Windoes SDK包)编译cl.exe来创建.pyd

时间:2013-08-11 09:49:25

标签: python visual-studio compilation compiler-errors cython

我正在尝试使用.c编译由Cython创建的.pyd文件到cl.exe文件,该文件随Microsoft Windows SDK一起提供。

由于这是在Windows 7 64位下为Python 2.7 64位构建Cython的recommended包,我认为使用相同的编译器创建.pyd文件是个好主意。

我当前的通话使用cythoncc.bat文件:

set CLPATH="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe"
SET INCLUDE="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include";"C:\Program Files\Microsoft SDKs\Windows\v7.0\Include";"C:\Python27\include";"C:\Python27\Lib\site-packages\numpy\core\include";
SET LIB="C:\Python27\libs";"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\amd64";"C:\Program Files\Microsoft SDKs\Windows\v7.0\Lib\x64";
SET CFLAGS="/O2 /favor:<INTEL64>"
%CLPATH% %CFLAGS% /Fo%1.pyd %2.c

我认为问题出在最后一行,但还不确定......它给了我错误:

/out:_conecyl.exe
_conecyl.pyd
   Creating library _conecyl.lib and object _conecyl.exp
LIBCMT.lib(crt0.obj) : error LNK2019: unresolved external symbol main referenced
 in function __tmainCRTStartup
_conecyl.exe : fatal error LNK1120: 1 unresolved externals

并创建一个.pyd加一个.lib文件。

任何帮助将非常感谢!谢谢!

2 个答案:

答案 0 :(得分:3)

使用documentationhere

中说明的setup.py食谱

Saullo的编辑:

setup.py看起来像这样:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("_conecyl", ["_conecyl.pyx"])]

setup(
  name = '_conecyl',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

通过以下调用,它的工作非常完美:

setenv /x64 / release
set INCLUDE=%INCLUDE%;C:\Python27\include;C:\Python27\Lib\site-packages\numpy\core\include
set LIB=%LIB%;C:\Python27\libs
set DISTUTILS_USE_SDK=1
python setup.py install

答案 1 :(得分:1)

我一直在与Windows上的Cython pyd创作作斗争,并且有一个可行的解决方案。这篇文章在搜索“构建cython pyd visual studio windows”时非常重要,所以我想我会添加自己的方法以节省一些人的愤怒和风险。眼泪。

我的要求如下:

  • 我用pyCharm用Python编写的大部分代码
  • 我使用Cython来加速某些涉及固定大小的浮动数组的计算
  • 调试Cython(这是另一个主题!)是可行的,但不是用户友好的。我发现最好的方法是不断添加/删除日志/打印 我的pyx中的语句并重新运行我的开发Python脚本。显然我想快点 从更改pyx文件到具有链接的pyd文件的转变 再次使用Python。

这就是我的所作所为。假设我们想要创建一个新的Cython模块:

  1. 使用构建和体系结构信息创建一个python文件。例如functions_362_64.py。我现在在Python中编写了一个很好的功能框架。 我建议写一些测试并让它们通过 - 这在Cython领域会更难。您的测试使用来自xxx.yyy.zzz.functions_362_64.py的&#39;导入my_function1&#39;等等。现在将文件名更改为&#39; functions_362_64.pyx&#39;。

  2. 运行&#39; cythonize.exe -a functions_362_64.pyx&#39;创建2个文件。 html以人类可读的形式解释了Cython对您的代码所做的事情 - 它对于调试非常有用。您也可以在&#39; functions_362_64.c&#39;中获取C代码。

  3. 现在我们使用Visual Studio创建pyd。阅读有关获取匹配版本的所有内容。我目前在Python32上使用MSVS2017。创建一个空白解决方案为每个pyd文件创建一个C ++ dll项目。所以我们在这里创建一个名为&#39; functions_362_64&#39;的项目。进行以下类型的更改以获得有用的编译和链接:

    • 包含Python venv中的目录
    • 来自Python env的libs目录
    • 将输出名称更改为pyd
    • 在发布版本中链接调试符号
    • 没有预编译的标题
    • 在您完成测试之前没有短期构建或优化
    • 将pyd / pbd复制到Python导入目录的构建后步骤 这都是非常标准的东西(你可以在许多MSVS帖子中找到它)。
  4. 你现在应该有&#39; functions_362_64.pyd&#39;与&#39; functions_362_64.pdb&#39;。检查它是否可以替代原始py文件 - 导入不会改变。

    1. 现在我们想要一个批处理文件来自动化所有东西 - 我有8行。您需要做的是获取visual studio在项目中使用的构建命令。转到工具 - &gt;选项 - &gt;项目和解决方案 - &gt;构建和运行 - &gt;输出详细程度并设置为详细。构建项目并搜索成功输出以获取PATH,LIB,LIBPATH,INCLUDE,cl.exe和副本。然后将正确的行粘贴到批处理文件中,并添加&#34;&#34;和&#39; SET&#39;需要的地方。我看起来像这样:
      • 第1行:&#34; C:... your_path ... \ Scripts \ cythonize.exe&#34; -a&#34; C:... your_path ... \ functions_362_64.pyx&#34;
      • 第2行:SET PATH = C:.....从构建输出中粘贴.....
      • 第3行:SET LIB = C:.....从构建输出中粘贴.....
      • 第4行:SET LIBPATH = C:.....从构建输出中粘贴.....
      • 第5行:SET INCLUDE = C:.....从构建输出中粘贴.....
      • 第6行:&#34; C:... microsoft_path ... \ CL.exe&#34; / c .....从构建输出中粘贴.....
      • 第7行:复制/ Y&#34; C:.....构建后复制pyd .....
      • 第8行:复制/ Y&#34; C:.....构建后复制pdb .....
    2. 将此.bat放在Visual Studio项目目录中。获取命令提示符以便坐在那里。

      现在你拥有一切:

      • 更改pyx文件
      • 运行.bat
      • 再次运行Python

      一切都很快。您甚至可以使用PyCharm或您使用的任何IDE来运行此脚本作为外部工具。我发现继续运行.bat文件更容易。

      好吧,我希望这可以节省你们一些时间和麻烦。在让这个过程工作之前,我几乎在考虑使用swicthing .......:)

      谢谢, LJHW

      作者修订: 2017年8月23日

      我现在使用x86或x64 Visual Studio Native Tools命令提示符 - 我认为这些都带有SDK安装以及完整的MSVS。这会解决所有ENV问题,这似乎会导致大多数人出现问题。通过这样做,一切都以跨平台的方式开箱即用,这样一个人就不会实现特定的Windows hacks。我也做了一些整理,所以我使用.bat文件。

      • 将windows_setup.bat添加到包目录
      • 在VS Native提示符
      • 中运行此命令

      在此.bat文件中添加:

      1. del ... \ functions.pyd
      2. python.exe setup.py build_ext --inplace
      3. del ... \ functions.c
      4. 重命名functions.cp36-win_amd64.pyd functions.pyd
      5. 现在,我只是简单地将pyx转换为pyd并且没有中间文件。 python.exe的体系结构必须与cmd.exe匹配。这样做的好处是你可以在网上运行所有基于linux的例子 - 你只需相应地更新你的setup.py文件,setuptools / disutils会处理windows特定的东西,因为你有正确的ENV设置原生提示。

        所以要发展,我去:

        • 更改pyx文件
        • 运行windows_setup.bat
        • 再次使用python代码开发

        如果我需要调试,我不会删除c文件,在Visual Studio中加载functions.c并按照原始帖子中的说明构建pdb。我不明白为什么这个系统不能用Python32&amp; MSVC10只使用10.0原生提示。