如何避免使用我的python包构建C库?

Gui*_*ent 20 python pip cmake python-3.x

我正在使用带有ctypes的C库构建一个python包.我想让我的包可移植(Windows,Mac和Linux).

我发现了一个策略,在安装我的包时使用build_extwith pip来构建库.它创建libfoo.dll或者libfoo.dylib还是libfoo.so取决于目标的平台上.

这个问题是我的用户需要安装CMake.

是否存在避免在安装过程中构建的另一种策略?我是否必须在我的包中捆绑构建的库?

我希望让我的用户继续这样做pip install mylib.

编辑:感谢@Dawid评论,我试图python wheel用命令做一个python setup.py bdist_wheel没有任何成功.

如何使用嵌入式库为不同平台创建我的python轮?

编辑2:我正在使用python 3.4并在Mac OS X上工作,但我可以访问Windows计算机和Linux计算机

Pet*_*ain 7

根据我的研究,你肯定正走在正确的道路上......正如丹尼尔所说,你唯一的选择是自己建立和分发二进制文件.

通常,包装用户指南中提供了推荐的安装包的方法.我不会在那里重复建议,因为你已经清楚地发现了它.然而,关键在于Python社区,特别是PyPA正试图使用平台轮来标准化二进制扩展.可悲的是,此时存在一些问题:

  1. 您无法为所有Linux变体创建分发,但您可以为兼容子集构建轮子.有关详细信息,请参阅https://www.python.org/dev/peps/pep-0513/.
  2. 关于构建扩展建议有些不完整,反映出缺乏二进制发行版的完整解决方案.
  3. 然后人们尝试构建自己的库并将其作为数据文件分发,这会混淆setuptools.

我想你是在讨论最后一期.一个解决办法是迫使分布建立通过重写is_pure平台车轮()总是返回False.但是,您可以保留原始构建指令,bdist_wheel应该处理它.

但是,一旦你构建了轮子,你仍然需要分发它,也许还需要它使用或使用它的其他二进制包.此时,您可能需要使用推荐的工具之一(如conda)或PyPI代理(如devpi)来提供轮子.

编辑:回答关于交叉编译的额外问题

如此处所述, Python 2.6及更高版本允许对Windows 32/64位版本进行交叉编译.其他平台上的其他软件包没有正式支持,人们尝试这样做的成功有限.您最好在每个Linux/Mac/Windows环境中本地构建.

  • "你无法将Linux轮子上传到PyPI"为什么不呢? (2认同)

Gui*_*ent 5

@rth 和 @PeterBrittain 帮了我很多。这里我使用的解决方案:

结构文件夹:

setup.py
python_package/
    lib/
        libfoo.dylib
        libfoo.dll
    __init__.py
    main.py
Run Code Online (Sandbox Code Playgroud)

设置.py:

from setuptools import setup, dist


class BinaryDistribution(dist.Distribution):
    def is_pure(self):
        return False


setup(
    name='python_package',
    package_data={'python_package': ['lib/libfoo.dylib','lib/libfoo.dll']},
    include_package_data=True,
    distclass=BinaryDistribution,
    packages=['python_package'],
)
Run Code Online (Sandbox Code Playgroud)

主要.py:

#!/usr/bin/env python
import platform
from ctypes import CDLL, c_char_p

import pkg_resources

sysname = platform.system()

if sysname == 'Darwin':
    lib_name = "libfoo.dylib"
elif sysname == 'Windows':
    lib_name = "libfoo.dll"
else:
    lib_name = "libfoo.so"
lib_path = pkg_resources.resource_filename('python_package', 'lib/{}'.format(lib_name))
foo = CDLL(lib_path)

bar = foo.bar
bar.restype = c_char_p
bar.argtypes = [c_char_p]

print(bar('hello'))
Run Code Online (Sandbox Code Playgroud)

构建轮:

python setup.py bdist_wheel
Run Code Online (Sandbox Code Playgroud)

它创建了一个特定的平台轮rtfdoc-0.0.1-cp34-cp34m-macosx_10_10_x86_64.whl,mac用户可以做一个简单的pip install rtfdoc-0.0.1-cp34-cp34m-macosx_10_10_x86_64.whl

这个解决方案并不完全令人满意:

  • 我想我仍然需要为 linux 用户创建一个扩展或查看SCons
  • 由于lib的产生,更新我的包会很困难
  • 我不知道如何管理 32 位和 64 位的 .dll

谢谢,学到了很多,明白了为什么Pillow或Psycopg2中的setup.py很大