简体   繁体   English

如何在setup.py中访问setuptools的install_requires安装的模块?

[英]How to access a module installed by setuptools' install_requires within setup.py?

I'm writing a setup.py to install my package reboundx , which has a single dependency, rebound . 我正在写一个setup.py来安装我的软件包reboundx ,它有一个依赖, rebound My package builds an extension libreboundx.so that needs to link to librebound.so in setup.py 我的包构建了一个扩展libreboundx.so ,需要链接到setup.py中的librebound.so

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

I'd like to be able to use install_requires in the setup(...) call to build the reboundx module to make sure the right version of rebound is installed. 我希望能够在setup(...)调用中使用install_requires来构建reboundx模块,以确保安装正确版本的rebound Is there any way to resolve the circularity? 有没有办法解决循环问题?

If rebound is not installed, I would somehow need setuptools to detect this through install_requires , install rebound , and THEN find the right paths and build the extension libreboundx.so . 如果没有安装rebound ,我会以某种方式需要setuptools通过install_requires检测到这一点,安装rebound ,然后找到正确的路径并构建扩展libreboundx.so

(If you like this approach, I can elaborate further) Consider this example. (如果您喜欢这种方法,我可以进一步详细说明)考虑这个例子。 I use ctypes to load a shared library. 我使用ctypes加载共享库。 Then get the version of the library using a function call. 然后使用函数调用获取库的版本。

>>> 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'

You could do something similar with rebound.so. 你可以做一些类似于反弹的东西。 Use a try statement to load librebound. 使用try语句加载librebound。 If it is the wrong version or it is not found in the standard search path for libraries, then compile 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]...)

You should use the setup_requires argument to setup() . 您应该使用setup_requires参数来setup() From the docs, 从文档中,

setup_requires setup_requires

A string or list of strings specifying what other distributions need to be present in order for the setup script to run. 字符串或字符串列表,指定需要存在的其他分发以便运行安装脚本。 setuptools will attempt to obtain these (even going so far as to download them using EasyInstall) before processing the rest of the setup script or commands. 在处理其余的安装脚本或命令之前,setuptools将尝试获取这些(甚至可以使用EasyInstall下载它们)。 This argument is needed if you are using distutils extensions as part of your build process; 如果您在构建过程中使用distutils扩展,则需要此参数; for example, extensions that process setup() arguments and turn them into EGG-INFO metadata files. 例如,处理setup()参数并将它们转换为EGG-INFO元数据文件的扩展。

(Note: projects listed in setup_requires will NOT be automatically installed on the system where the setup script is being run. They are simply downloaded to the ./.eggs directory if they're not locally available already. If you want them to be installed, as well as being available when the setup script is run, you should add them to install_requires and setup_requires.) (注意:setup_requires中列出的项目不会自动安装在运行安装脚本的系统上。如果它们本地不可用,则只需将它们下载到./.eggs目录。如果要安装它们,以及在运行安装脚本时可用,您应该将它们添加到install_requires和setup_requires。)

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

Edit : It should create an egg directory for each entry in setup_requires . 编辑 :它应该为setup_requires每个条目创建一个egg目录。 However , I just tried this with rebound and it actually fails to build under easy install. 但是 ,我只是尝试了反弹,实际上无法在简单安装下构建。

$> 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

It seems setuptools does make this possible through the setup_requires keyword, as pointed out by sn6uv. 似乎setuptools通过setup_requires关键字实现了这setup_requires ,正如setup_requires所指出的那样。 However, I found it difficult to find documentation and/or examples that showed how to use it. 但是,我发现很难找到展示如何使用它的文档和/或示例。 From what I did find, it also seemed like it might be a bit delicate/complicated for the uninitiated. 从我的确发现,对于没有经验的人来说,它似乎也有点微妙/复杂。

For one, when using pip, the dependencies in setup_requires are installed differently than everything else (see Install package which has setup_requires from local source distributions ). 首先,当使用pip时, setup_requires中的依赖setup_requires的安装方式与其他所有内容的安装方式不同(请参阅从本地源代码分发中安装setup_requires的安装包 )。 It also seems like if you need to import the dependency within setup.py, you need to subclass the install command in order to delay the import until it's available (deep in a thread on the distutils mailing list arguing over setup_requires, Donald Stufft talks about this and links to an example: https://mail.python.org/pipermail/distutils-sig/2015-March/025882.html ). 看起来如果你需要在setup.py中导入依赖项,你需要继承install命令,以便延迟导入直到它可用(深入到distutils邮件列表上的一个主题争论setup_requires,Donald Stufft谈到这个和链接到一个例子: https//mail.python.org/pipermail/distutils-sig/2015-March/025882.html )。

So I gave up and implemented something similar to the manual check suggested by goCards. 所以我放弃并实现了类似于goCards建议的手动检查的东西。 Just thought I'd post the links for the more ambitious who come across this. 只是想我会发布更多雄心勃勃的人的链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 setup.py中的install_requires取决于安装的Python版本 - install_requires in setup.py depending on installed Python version 如何使 setup.py 的 install_requires 部分跳过已安装的依赖项 - How to make setup.py's install_requires section skip already installed dependencies 如何从 setup.py install_requires 列表中安装 PyTorch 和相关工具? - How does one install PyTorch and related tools from within the setup.py install_requires list? setup.py install_requires 应该包含 setuptools 的任何原因? - Any reason setup.py install_requires should include setuptools? setuptools setup.py 文件中 install_requires kwarg 的参考 requirements.txt - Reference requirements.txt for the install_requires kwarg in setuptools setup.py file python setup.py install 忽略 install_requires - python setup.py install ignores install_requires setup.py dependency_links 未搜索 install_requires - setup.py dependency_links not searched for install_requires 在setup.py中对install_requires进行“或......或......”区分 - Make an “either… or… ” distinction for install_requires in setup.py 在python setup.py install_requires列表中传递参数 - Passing arguments in python setup.py install_requires list ModuleNotFoundError 尽管在 setup.py 中声明了 install_requires - ModuleNotFoundError despite declairing install_requires in setup.py
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM