准备setup.py
from distutils.core import setup
from Cython.Build import cythonize
import glob
# 指定目标目录 python setup.py build -c mingw32
target_dir = "src"
# 使用glob模块匹配目录中的所有.pyx文件
pyx_files = glob.glob(target_dir + "/**/*.py", recursive=True)
print(f"pyx_files={pyx_files}")
# 将匹配到的所有.pyx文件进行编译
setup(ext_modules=cythonize(pyx_files, language_level=3))
运行命令:
python setup.py build -c mingw32
不出意外就会将src目录的文件全部编译城.c文件。出意外就看下面的错误集↓↓↓
-----------
众所周知,很多Python的库都需要编译(可能是用了Cython),这时直接用pip安装会报错:error: Microsoft Visual C++ 14.0 is required.
不知为何,我的电脑死活不能安装上VC,只能用mingw作为编译器。
附:MinGW-w64 密码:2jfy,tdm64-gcc tdm-gcc(32位)
最新版:tdm-gcc GCC with the MCF thread model MinGW-w64
环境变量:[Windows配置MinGW环境变量]
然后编辑你的 Python 路径/Lib/distutils/distutils.cfg
或者 %USERPROFILE%\pydistutils.cfg
[build]
compiler=mingw32
[build_ext]
compiler = mingw32
# To solve the gcc error of "error: enumerator value for '__pyx_check_sizeof_voidp' is not an integer constant"
# if you have a mingw for 64bit then
# refer to https://docs.python.org/zh-cn/3/distutils/configfile.html
# you can also refer to https://github.com/cython/cython/issues/3405#issuecomment-596975159
define = MS_WIN64
仍然会报错 Unknown MS Compiler version XXXX
编辑你的Python路径/Lib/distutils/cygwinccompiler.py
在
elif msc_ver == '1600':
# VS2010 / MSVC 10.0
return ['msvcr100']
后添加
elif msc_ver == '1927':
# MinGW64 with gcc 8.3.0
return ['msvcr120'] # seem to be a dynamic-linker program name for command `ld`
其中1927改为你的Compiler version
----------------------
然后编译又报错:
error: enumerator value for '__pyx_check_sizeof_voidp' is not an integer constant
解决办法:
您可以简单地将此补丁应用于%PYTHON_DIR%\include\pyconfig.h
:
--- pyconfig.h 2016-01-27 10:54:56.000000000 +0300
+++ pyconfig.h 2016-03-28 11:46:48.000000000 +0300
@@ -100,6 +100,12 @@
/* Compiler specific defines */
+#ifdef __MINGW32__
+#ifdef _WIN64
+#define MS_WIN64
+#endif
+#endif
+
/* ------------------------------------------------------------------------*/
/* Microsoft C defines _MSC_VER */
#ifdef _MSC_VER
# --inplace 将放在原地 # 指定目标目录 python setup.py build_ext -c mingw32
setup.py完整如下:
import os
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import glob
# 获取当前脚本所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 指定源代码目录
source_dir = os.path.join(current_dir, "src")
# 使用glob模块匹配目录中的所有.pyx文件
pyx_files = glob.glob(os.path.join(source_dir, "**/*.py"), recursive=True)
# 保持相对路径
relative_pyx_files = [os.path.relpath(pyx, current_dir) for pyx in pyx_files]
print(f"pyx_files={relative_pyx_files}")
# 指定目标目录
target_dir = os.path.join(current_dir, "build")
# 将匹配到的所有.pyx文件进行编译
extensions = [Extension(os.path.splitext(pyx)[0].replace(os.sep, '.'), [pyx]) for pyx in relative_pyx_files]
setup(
ext_modules=cythonize(extensions, language_level=3),
script_args=['build_ext', '--build-temp', target_dir, '-c', 'mingw32'],
)
通过执行python setup.py 就会将当前py文件转成pyd
-----------------
在Python开发中,我们经常需要保护我们的代码不被轻易查看或修改。同时,我们也希望提高代码的执行效率。将Python文件编译为.pyd动态链接库是一种可以实现这两点的有效方法。.pyd文件类似于Windows平台上的.dll文件,是一种动态链接库,包含了编译后的二进制代码。通过这种方式,我们可以隐藏源代码,同时利用编译的优势提高代码的执行效率。
要实现这一目标,我们需要使用Cython工具。Cython是一个Python到C的编译器,可以将Python代码转换为C代码,然后编译成.pyd文件。
下面是一个简单的步骤指南:
- 安装Cython:首先,你需要在你的开发环境中安装Cython。可以通过pip安装,命令如下:
pip install cython
- 创建Cython文件:创建一个新的Python文件,后缀名为.pyx。这个文件将包含你要编译的Python代码。例如,你可以创建一个名为example.pyx的文件,其中包含以下内容:
def say_hello(name):
print(f'Hello, {name}!')
- 编写setup.py:接下来,你需要创建一个setup.py文件,用于配置编译过程。以下是一个简单的setup.py示例:
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize('example.pyx')
)
- 编译为C文件:在命令行中进入包含setup.py和example.pyx的目录,然后运行以下命令:
pip install -e . # 或者 python setup.py build_ext --inplace
- 使用编译后的模块:现在你可以像普通Python模块一样导入并使用你的.pyd文件了。例如:
import example
example.say_hello('World') # 输出:Hello, World!
参考:将Python文件编译为.pyd动态链接库:加密与加速的完美结合