首先,回答您的实际问题:
我想是否有办法将 Cython 设置为使用指定的 UCS 模式进行编译。
您可以从源代码构建单独的 python 安装并将 Cython 链接到其标头。要查找标题,您可以使用该python-config
工具(或python3-config
用于 Python 3)。它通常位于可执行文件bin
所在的目录中:python
$ # system python on my machine (macos):
$ which python-config
/usr/bin/python-config
$ # python 3 installation
$ which python3-config
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3-config
$ python-config --cflags
-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE
$ python-config --ldflags
-L/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -lpython2.7 -ldl -framework CoreFoundation
将输出复制到setup.py
:
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize
cflags_ucs4 = [
'-I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m',
'-I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m',
...
]
ldflags_ucs4 = [
'-L/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin',
'-lpython3.6m',
...
]
cflags_ucs4 = [...]
ldflags_ucs2 = [...]
should_build_ucs2 = False # i.e. could be passed via sys.argv
if should_build_ucs2:
cflags = cflags_ucs2
ldflags = ldflags_ucs2
else:
cflags = cflags_ucs4
ldflags = ldflags_ucs4
extensions = [
Extension('hello.py', extra_compile_args=cflags, extra_link_args=ldflags),
]
setup(
ext_modules = cythonize(extensions)
)
但是,我不建议这样做,因为这样做你不会赢得任何东西——你仍然需要构建和分发两个单独的包(一个用于 UCS2,另一个用于 UCS4),维护起来很麻烦。
相反,如果您正在构建一个可以安装在各种 Linux 发行版上的轮子(这很可能是您的实际目标),我建议您使您的构建符合PEP 513(manylinux1
软件包)。我建议您阅读它因为当我遇到分发兼容 Linux 的轮子的问题时,它对我很有帮助。
现在,获得manylinux1
符合标准的轮子的一种方法是在您的机器上构建轮子,然后运行auditwheel
以检查特定于平台的问题并尝试解决它们:
$ pip install auditwheel
$ python setup.py bdist_wheel
$ # there should be now a mypkg-myver-cp36-cp36m-linux_x86_64.whl file in your dist directory
$ auditwheel show dist/mypkg-myver-cp36-cp36m-linux_x86_64.whl
$ # check what warnings auditwheel produced
$ # if there are warnings, try to repair them:
$ auditwheel repair dist/mypkg-myver-cp36-cp36m-linux_x86_64.whl
这应该生成一个mypkg-myver-cp36-cp36m-manylinux1_x86_64.whl
在wheelhouse
目录中命名的轮文件。通过运行再次检查一切是否正常auditwheel show wheelhouse/mypkg-myver-cp36-cp36m-manylinux1_x86_64.whl
。manylinux1
如果轮子现在与它)。
轮毂修不好怎么办auditwheel
?最好的方法是拉出 PyPA 提供的一个特殊的 docker 容器来构建manylinux1
兼容的轮子(这是我自己使用的):
$ docker pull https://quay.io/repository/pypa/manylinux1_x86_64
在这个容器中构建的轮子可以在大多数 Linux 发行版上运行(不包括一些像 Alpine 这样的外来发行版)。