1

我正在编写一个 setup.py 来安装我的包reboundx,它有一个依赖项,rebound. libreboundx.so我的包构建了一个需要链接到librebound.sosetup.py的扩展

rebxExt = Extension('libreboundx', libraries=['rebound'], library_dirs = [rebound_path]...)

我希望能够install_requiressetup(...)调用中使用来构建reboundx模块以确保rebound安装了正确的版本。有没有办法解决循环问题?

如果rebound没有安装,我会以某种方式需要 setuptools 来检测它install_requires,安装rebound,然后找到正确的路径并构建扩展libreboundx.so

4

3 回答 3

1

(如果你喜欢这种方法,我可以进一步阐述)考虑这个例子。我使用 ctypes 加载共享库。然后使用函数调用获取库的版本。

>>> import ctypes
>>> x = ctypes.cdll.LoadLibrary("libc.so.6")
>>> x.gnu_get_libc_version
<_FuncPtr object at 0x7f9a08e3e460>
>>> getversion = x.gnu_get_libc_version
>>> getversion.restype = ctypes.c_char_p
>>> getversion()
'2.19'

你可以用反弹.so 做类似的事情。使用 try 语句加载 librebound。如果是错误的版本或者在库的标准搜索路径中没有找到,则编译 librebound。

#setup.py
import ctypes
try:
    x = ctypes.cdll.LoadLibrary("librebound.so")
    x.restype = ctypes.c_char_p
    version = x.get_version()
    major,minor = version.split(".")
    if int(major) < REQUIRED_VERSION:
        raise False, "LIBREBOUND VERSION %s IS NOT SUPPORTED"%(str(version))

except:
    pass
    #invoke rebound's makefile
    #probably install the new library to lib path.
    #link to new rebound 

rebxExt = Extension('libreboundx', libraries=['rebound'], library_dirs = [rebound_path]...)
于 2016-01-31T03:20:47.137 回答
1

您应该使用setup_requires参数来setup(). 从文档中,

setup_requires

一个字符串或字符串列表,指定需要存在哪些其他发行版才能运行安装脚本。setuptools 将在处理其余的设置脚本或命令之前尝试获取这些(甚至使用 EasyInstall 下载它们)。如果您在构建过程中使用 distutils 扩展,则需要此参数;例如,处理 setup() 参数并将它们转换为 EGG-INFO 元数据文件的扩展。

(注意:setup_requires 中列出的项目不会自动安装在运行安装脚本的系统上。如果它们在本地不可用,它们只需下载到 ./.eggs 目录。如果您希望安装它们,以及在运行安装脚本时可用,您应该将它们添加到 install_requires 和 setup_requires。)

https://pythonhosted.org/setuptools/setuptools.html#new-and-changed-setup-keywords

编辑:它应该为中的每个条目创建一个 egg 目录setup_requires但是,我只是尝试了反弹,它实际上无法在易于安装的情况下构建。

$> python2 setup.py install
install_dir .
warning: no files found matching 'src/rebound.h'
src/rebound.c:38:21: fatal error: rebound.h: No such file or directory
compilation terminated.
Traceback (most recent call last):
  File "setup.py", line 187, in <module>
    url="http://www.mathics.github.io/",   # project home page, if any
  File "/usr/lib/python2.7/distutils/core.py", line 111, in setup
    _setup_distribution = dist = klass(attrs)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/dist.py", line 221, in __init__
    self.fetch_build_eggs(attrs.pop('setup_requires'))
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/dist.py", line 245, in fetch_build_eggs
    parse_requirements(requires), installer=self.fetch_build_egg
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/pkg_resources.py", line 544, in resolve
    dist = best[req.key] = env.best_match(req, self, installer)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/pkg_resources.py", line 786, in best_match
    return self.obtain(req, installer) # try and download/install
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/pkg_resources.py", line 798, in obtain
    return installer(requirement)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/dist.py", line 293, in fetch_build_egg
    return cmd.easy_install(req)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/command/easy_install.py", line 582, in easy_install
    return self.install_item(spec, dist.location, tmpdir, deps)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/command/easy_install.py", line 612, in install_item
    dists = self.install_eggs(spec, download, tmpdir)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/command/easy_install.py", line 802, in install_eggs
    return self.build_and_install(setup_script, setup_base)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/command/easy_install.py", line 1079, in build_and_install
    self.run_setup(setup_script, setup_base, args)
  File "/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg/setuptools/command/easy_install.py", line 1070, in run_setup
    raise DistutilsError("Setup script exited with %s" % (v.args[0],))
distutils.errors.DistutilsError: Setup script exited with error: command 'gcc' failed with exit status 1
于 2016-01-31T16:42:38.600 回答
1

setup_requires正如 sn6uv所指出的,setuptools似乎确实通过关键字使这成为可能。但是,我发现很难找到说明如何使用它的文档和/或示例。从我的发现来看,对于外行来说,这似乎有点微妙/复杂。

一方面,使用 pip 时,依赖项setup_requires的安装方式与其他所有内容不同(请参阅安装包,其中包含来自本地源分发的 setup_requires)。似乎如果您需要在 setup.py 中导入依赖项,则需要对 install 命令进行子类化以延迟导入直到它可用(在 distutils 邮件列表中争论 setup_requires 的线程深处,Donald Stufft 谈到这并链接到一个示例:https ://mail.python.org/pipermail/distutils-sig/2015-March/025882.html )。

所以我放弃并实现了类似于 goCards 建议的手动检查的东西。只是以为我会为遇到此问题的更雄心勃勃的人发布链接。

于 2016-02-01T22:30:42.890 回答