用 Go 编写 Python 扩展
tzfpy 是 tzf 的 Python
binding。 如果只是本地可用,Go 代码加上 CGO 扩展编译成 .so
文件就能用了。
不过要做成发布到 PyPI 上在其他地方能直接安装的 wheel 是有些曲折的,看 CI
失败的记录就挺明显的。
有挺多社区文档里没有注明的事情, 解决方案分散在各个 issues 里,当最终成功了以后已经不记得增加的改动的目的是什么。
项目没有用 Poerty 等 fancy 的工具打包,而是用了淳朴的
setup.py
(好处是可以直接被 GitHub 识别出来)。
配置 setup.cfg
#
忘记具体的原因了,大致是为了覆盖某个工具的默认配置,如果没有会构建失败
[install]
install_lib=
配置发布的时候携带 .so
文件#
用下来发现要配置两个地方才行
package_data={"so": ["tzfpy/tzf.so"]},
include_package_data=True,
cmdclass={"bdist_wheel": bdist_wheel, "build_ext": build_ext},
distclass=BinaryDistribution,
include tzfpy/tzf.so
用 cibuildwheel 修正 Linux wheels#
直接构建出来的 wheel 不满足 PyPI 的要求,还需要用
pypa/cibuildwheel
修正一遍。
看情况配置
- name: Build wheels
uses: pypa/cibuildwheel@v2.8.1
env:
CIBW_BUILD_FRONTEND: "build"
CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014"
CIBW_MANYLINUX_I686_IMAGE: "manylinux2014"
CIBW_BUILD: "*manylinux_x86_64"
End#
一路折腾下来感觉干的好像是个挺另类的事情,社区的扩展大多是 C/C++/Rust 实现的,我这种弄个 Go 的在 PyPI 上还没见到过正经的项目。
有个项目叫
asottile/setuptools-golang
,
但是作者自己在
#106
说:
to be honest, I haven’t used this for anything more than basic things – but anything in the C api should work
目前的场景还算简单,以后可能会用 https://github.com/go-python/cpy3 写一些更奇怪的扩展搞事情。
不过学会 Rust 用 PyO3 可能是更清爽的做法。
Read other posts