如何发布不含.c文件的Cython平台专属Wheel包?
解决Cython Wheel包中自动移除生成的.c文件问题
我明白你的需求——用Cython编译实现代码混淆,只发布平台专属Wheel,不想把生成的C源码文件打包进去。折腾了一整天没找到方法确实闹心,下面是几个可行的方案,按推荐度排序:
方案1:自定义build_ext类,编译完成后自动清理.c文件
这个方法最直接,通过继承默认的build_ext类,在编译流程结束后自动删掉生成的C源码。修改你的setup.py如下:
from setuptools import setup from Cython.Build import build_ext from Cython.Build import cythonize from Cython.Distutils import Extension import os class CleanCBuildExt(build_ext): def run(self): # 先执行默认的编译流程 super().run() # 遍历所有扩展模块,删除对应的.c文件 for ext in self.extensions: # 替换pyx文件后缀为.c,定位生成的C源码 c_file = ext.sources[0].replace('.pyx', '.c') if os.path.exists(c_file): os.remove(c_file) print(f"自动清理生成的C源码: {c_file}") setup(name='pythonlib', zip_safe=False, include_package_data=True, cmdclass={'build_ext': CleanCBuildExt}, ext_modules=cythonize([ Extension('example_module', ['example_module.pyx']) ]), )
如果你的Cython编译是在临时build子目录生成.c文件,可以调整c_file的路径,比如从self.build_temp目录下查找对应文件。
方案2:指定Cython编译的临时目录,避免.c文件被打包
另一种思路是把生成的.c文件放到单独的临时目录,让bdist_wheel完全不会把它打包进去。修改cythonize的调用,添加build_dir参数:
ext_modules=cythonize( [Extension('example_module', ['example_module.pyx'])], build_dir="build/cython_temp" # 指定临时目录存放生成的.c文件 )
生成的.c文件会被放到build/cython_temp目录下,Wheel包只会打包最终编译好的.so(Windows下是.pyd)文件。编译完成后你可以手动删除这个临时目录,也可以在setup.py里额外加一个清理命令。
方案3:用MANIFEST.in排除.c文件(补充方案)
如果发现还是有.c文件被打包,可能是include_package_data=True导致的(它会依据MANIFEST.in规则包含文件)。可以在项目根目录创建MANIFEST.in文件,添加以下内容:
exclude *.c
这个方案是在打包阶段直接排除所有.c文件,适合作为前两个方案的补充保险。
验证方法
修改完setup.py后,重新构建Wheel:
python setup.py bdist_wheel
构建完成后,用unzip命令解压生成的Wheel包,检查里面是否还存在.c文件。如果一切正常,就只有编译后的二进制模块文件了。
内容的提问来源于stack exchange,提问作者Matthijs
相关产品推荐
相关产品推荐

