使用setuptool排除源文件在构建的rpm发行版中

1 投票
1 回答
1955 浏览
提问于 2025-04-18 14:33

我有一个典型的项目结构,长得像这样:

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 <生成的egg文件> 时,我的eg.info文件被复制过去了,但源文件没有被复制到/usr/lib/python2.6/site-packages目录下。我原本以为会有一个叫做Engine的文件夹。

有没有人能指出我哪里做错了?提前谢谢大家。

1 个回答

1

尽量保持事情简单。

sdist 快速检查

试试这个:

$ python setup.py sdist

这会为你的包创建一个源代码分发文件。

这个文件是zip格式的,所以解压后检查一下,里面是否有你预期的所有文件。

如果没有,你需要找出为什么预期的文件在你的分发中缺失。

一步一步检查(并简化)

你有使用 .py 后缀吗?

这可能是个傻问题,但在你的文件列表中,我没有看到任何 src 目录下的py文件。

如果那里只有没有 .py 后缀的文件,find_packages 就找不到任何东西。

你的 __init__.py 文件放在哪里?

告诉我们这些文件在哪里:

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

如果缺少 __init__.pyfind_packages 就找不到整个包。

移除 utils

你为什么要把它放在那里?

最好把它安装在你开发的源代码之外,或者把它移动到项目根目录的子目录中。

这样就不需要在你的 MANIFEST.in 中使用 prune src/utils 了。

在 MANIFEST.in 中只放必要的文件

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

因此,你应该移除 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

会在断言时失败。这是一个信号,说明一些预期的文件缺失。检查一下。

在你让项目以简单的方式运行后,可以逐步添加更多细节(确保你不会破坏什么)。

撰写回答