我正在编写一个setup.py来安装我的包reboundx
,它只有一个依赖项rebound
。我的包构建了一个扩展libreboundx.so
,需要链接到setup.py
librebound.so
rebxExt = Extension('libreboundx', libraries=['rebound'], library_dirs = [rebound_path]...)
我希望能够在install_requires
调用中使用setup(...)
来构建reboundx
模块,以确保安装了rebound
的正确版本。有没有办法解决循环问题?
如果未安装rebound
,我会以某种方式需要setuptools通过install_requires
检测到这一点,安装rebound
,然后找到正确的路径并构建扩展程序libreboundx.so
。
答案 0 :(得分: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'
你可以用反弹做类似的东西。使用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]...)
答案 1 :(得分: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
修改强>:
它应该为setup_requires
中的每个条目创建一个egg目录。 然而,我只是尝试了反弹,实际上无法在简易安装下构建。
$> 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
答案 2 :(得分:1)
似乎setuptools通过setup_requires
关键字实现了这一点,正如sn6uv所指出的那样。但是,我发现很难找到展示如何使用它的文档和/或示例。从我的确发现,对于没有经验的人来说,它似乎也有点微妙/复杂。
首先,使用pip时,setup_requires
中的依赖项安装方式与其他所有内容的安装方式不同(请参阅Install package which has setup_requires from local source distributions)。看起来如果你需要在setup.py中导入依赖项,你需要继承install命令,以便延迟导入直到它可用(深入到distutils邮件列表上的一个主题争论setup_requires,Donald Stufft谈到这个和链接到一个例子:https://mail.python.org/pipermail/distutils-sig/2015-March/025882.html)。
所以我放弃并实施了类似于goCards建议的手动检查。只是想我会发布更多雄心勃勃的人的链接。