【问题标题】:Excluding source files from built rpm distribution with setuptool使用 setuptools 从构建 rpm 分发中排除源文件
【发布时间】:2014-09-15 10:51:57
【问题描述】:

我有一个典型的项目结构,如下所示:

EngineEmulator
    src
        ship
            engine
                emulator
                mapping
            tests
                emulator
                mapping
        utils
            common

    doc
       ....
    tools
       ....
    setup.py
    MANIFEST.in
    setup.cfg
    README.rst

我的 setup.py 如下所示:

from setuptools import setup, find_packages
setup(
   name='Engine',
   version=1.0.0,
   description='Engine Project',       
   package_dir={'': 'src'},
   packages=find_packages(
    'src',
    exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
   install_requires =['pycrypto', 
                      'kombu >=1.1.3'],
   author='Demo',
   author_email='demo@eliza.net'
   license='MIT',
   classifiers=[
    'Topic :: Demo Engine',
    'Development Status:: 3 - Iteration',
    'Programming Language :: Python -2.6'
]

)

我的 setup.cfg 如下所示:

[egg_info]
tag_build = .dev
tag_svn_revision = 1

[rotate]
#keep last 15 eggs, clean up order
match = .egg
keep = 15   

我的 MANIFEST.in 如下所示:

include README.rst
recursive-include src/ship/Engine
prune src/utils
prune src/ship/tests
prune tools/

当我运行 python setup.py bdist_eggpython setup.py bdist_rpm 时,我得到了 egg 文件和两个 rpm 文件(noarch.rpm 和 src.rpm)。

在我的目标机器上,当我运行easy_install <generated egg file> 时,我的 eg.info 文件被复制,但源文件没有被复制到 /usr/lib/python2.6/site-packages。我原以为我会有一个名为 Engine 的目录。

谁能指出我做错了什么?提前致谢。

【问题讨论】:

  • @ArunaDev 假设您的项目是纯 Python 项目(项目中没有 C 或 C++ 代码),我建议使用 sdist 而不是 egg。我还假设,您安装在与创建 egg 相同的操作系统中。学习使用pip,并尽可能停止使用easy_installpip 提供更好的服务。您应该能够$ pip install <package_file> 从 egg、sdist 或其他格式安装。
  • pip 不支持 egg。 sdist 可以,但我们希望在交付给客户之前预先构建一些 C 代码。此外,出于其他我不会讨论的原因,我们只想发送 .pyc 文件。
  • @ArunaDev 抱歉,pip 和鸡蛋我错了。您可能会发现使用 wheel 格式很方便 - 这是安装软件包的更快方法。但它似乎包含源 python 文件,因此它可能不符合您的标准。无论如何,一旦我错误地删除了我的 py 文件并在谷歌搜索、测试、反编译和编辑的一个小时内设法从 pyc 文件中获取可用源,“只有 pyc”并不是那么大的胜利。
  • 是的,这并不是易于反编译的原因……它对于支持的东西要容易得多。

标签: python rpm setuptools egg


【解决方案1】:

尽量保持简单。

sdist快速检查

试试这个:

$ python setup.py sdist

它将为您的包创建源分发文件。

它是zip格式的,所以解压它并检查里面是否有所有预期的文件。

如果没有,您必须找出原因,即您的发行版中缺少预期文件的原因。

逐步检查(并简化)

您使用.py 扩展名吗?

可能是个愚蠢的问题,但在您的文件列表中,我没有看到 src 树内的任何 py 文件。

如果您只有没有.py 扩展名的文件,find_packages 将找不到任何东西。

您的__init__.py 文件在哪里?

让我们知道文件在哪里:

$ cd src
$ find . -name "*.py"

如果你错过了__init__.pyfind_packages 将找不到完整的包。

删除utils

你为什么把它放在那里?

最好将它安装在您开发的源代码之外或将其移动到项目中的子目录中 根。

这将使prune src/utils 在您的MANIFEST.in 中变得不必要。

仅将必须存在的内容放入 MANIFEST.in 中

如果您阅读MANIFEST.in 的文档,它会说明自动包含哪些文件(所有,什么 在 setup 函数的参数中提到,所以在你的情况下,所有 python 源文件返回 find_packages)。

出于这个原因,您应该删除recursive-include src/shop/Engine,因为它已经是 包含在setup 电话中。

删除prune 行。

  • src/utils 不应出现在您的源代码树中 - 它只会把事情搞砸。
  • tools 不包含在内,因此无需修剪。
  • src/ship/tests 可以在那里,如果您将这些文件保存在分发中,它不会有害。

断言,找到了什么包

确保您的设置为packages 正确命名。

为此,您可以尽快致电find_package 并断言它包含您所期望的内容。

(暂时)删除setup.cfg

只是为了让事情更简单。

提议的项目重组

你应该有类似的文件结构如下:

src/ship/__init__.py
src/ship/engine/__init__.py
src/ship/engine/emulator/__init__.py
src/ship/engine/emulator/module.py
src/ship/engine/emulator/module2.py
src/ship/engine/mapping/other.py
src/ship/engine/mapping/another.py
src/ship/tests/__init__.py
src/ship/tests/emulator/__init__.py
src/ship/tests/emulator/test_module.py
src/ship/tests/emulator/test_module2.py
src/ship/tests/mapping/__init__.py
src/ship/tests/mapping/test_other.py
src/ship/tests/mapping/test_another.py
doc
doc/index.rst
tools
tools/knife.py
setup.py
MANIFEST.in
README.rst

setup.py

from setuptools import setup, find_packages

packages=find_packages("src")
assert "ship.engine" in packages
assert "ship.engine.emulator" in packages
assert "ship.engine.mapping" in packages
#etc

install_requires =['pycrypto', 'kombu>=1.1.3'] #watch the spaces around `>=`, shall not be there

setup(
    name="Engine",
    package_dir={'': 'src'},
    packages=packages,
    install_requires=install_requires
)

MANIFEST.in

include README.rst

结论

它可能会发生,运行

$ python setup.py sdist

断言失败。这是标志,一些预期的文件丢失了。检查一下。

在你让你的项目以简单的方式生活之后,你可能会添加更多的细节(并按照步骤 逐步确定,您不会破坏某些东西)。

【讨论】:

  • Jan 非常感谢您的回答!是的,我的 src 目录有我在相关代码中省略的 a__init__.py。并且 sdist 内容确实包含模块。断言也通过了。我做了你建议的所有改变。然后我运行easy_install python setup.py bdist_egg,但是当我在目标机器上运行easy_install 时,没有任何源文件被复制到/usr/lib/python2.6/site-packages/。我期待一个目录'Engine',我正确吗(因为那是我指定的项目名称)?只有一个 Engine-1.0.0-py2.7.egg 目录。
  • @ArunavDev 尝试$ pip freeze 并检查是否列出了包。试试pip show Engine,它会告诉你,包安装在哪里。最重要的是,如果您能够导入模块。创建一些目录是次要主题。顺便说一句,你使用 virtualenv 吗?如果是这样(强烈推荐),软件包将安装到 virtulanev 目录而不是系统中。
  • @ArunavDev 顺便说一句,__init__.py 目录中不应有 __init__.py 包。 __init__.py 只能在目录中,即包,src 不应该是包,而是包目录的父目录。
  • 谢谢 1 月 pip freeze 显示 Engine==1.0.0 并且 pip show Engine 显示站点包中的 egg 文件位置。看起来里面的 egg 文件包含 Engine 和 EGG-INFO 文件。这违背了我的最终目标,因为 Engine 不再位于默认的 PYTHONPATH 中。
猜你喜欢
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 2015-09-02
  • 2017-10-17
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多