使用Buildozer构建Kivy安卓应用时Cython编译错误求助
Kivy安卓构建Cython编译错误的分析与解决
错误含义
这个错误是Cython 3.0对函数异常标注的严格类型检查导致的:
- SDL2库定义的
SDL_RWops结构体中,write和close函数指针要求是noexcept类型(即函数不会抛出任何异常)。 - 但Kivy的
_img_sdl2.pyx文件里,自定义的rwops_bytesio_write和rwops_bytesio_close函数标注的是except? -1(表示函数可能抛出值为-1的异常),两种异常标注类型不兼容,因此编译失败。
解决方法
方案1:降级Cython到兼容版本
Kivy 2.2.1尚未完全适配Cython 3.0,降级到Cython 0.29.x或2.x版本可解决类型检查冲突:
- 卸载当前Cython:
pip uninstall cython -y - 安装兼容版本(以0.29.36为例):
pip install cython==0.29.36 - 清理Buildozer构建缓存:
buildozer android clean - 重新执行构建命令:
buildozer android debug deploy run
方案2:修改Kivy源码适配Cython 3.0
手动修改Kivy的_img_sdl2.pyx文件,将函数的异常标注改为noexcept:
- 找到虚拟环境中Kivy的安装路径,例如:
/home/vishakraj/Documents/app/app_env/lib/python3.10/site-packages/kivy/core/image/_img_sdl2.pyx - 定位到
rwops_bytesio_write和rwops_bytesio_close的函数定义,将except? -1替换为noexcept:
原代码:
修改后:cdef size_t rwops_bytesio_write(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum) except? -1: # 函数实现...
对cdef size_t rwops_bytesio_write(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum) noexcept: # 函数实现...rwops_bytesio_close函数做同样修改。 - 清理Buildozer缓存后重新构建。
方案3:升级Kivy到兼容Cython 3.0的版本
Kivy 2.3.0及以上版本已修复Cython 3.0的兼容性问题:
- 升级Kivy:
pip install --upgrade kivy - 清理Buildozer缓存后重新执行构建命令。
内容的提问来源于stack exchange,提问作者Vishak Raj
相关产品推荐
相关产品推荐

