setup.py构建不排除测试,使用cx_Freeze时添加data_files

setup.py build does not exclude tests and add data_files when using cx_Freeze

我正在尝试为我的 python gui 应用程序创建可执行文件,并且需要:

我试图将这些包含在 setup.py 的构建中,但我似乎无法让它工作。没有添加数据文件,我的测试文件错误地添加到linb。

我的树结构是这样的:

setup.py
mypkg/
    __init__.py
    gui_app.py
icons/
    add.png
    import.png
config/
    mycfg.json
tests
    __init__.py
    tests.py
...

我正在尝试使用这个:

https://docs.python.org/3/distutils/setupscript.html#distutils-additional-files

我有以下内容:

from setuptools import setup, find_packages
from codecs import open
from cx_Freeze import setup, Executable
import sys

...

setup(
    ...
    packages=find_packages(exclude=('tests', 'docs')),
    executables=[Executable("./mypkg/gui_app.py", base=base)],
    data_files=[('icons', ["./icons/add.png", "./icons/import.png"]),
                ('config', ["./config/mycfg.json"])],
    ...
)

任何人都可以建议如何使它与 python3.6 一起工作吗?拜托,python2.7 或 python3.5 及以下版本没有解决方案。

TL;DR cx_Freeze 是一种特殊情况,它忽略了 distutilssetuptools 在构建轮子或源代码分发时使用的许多选项。将您的 setup() 调用重写为:

setup(
    ...
    executables=[Executable("./mypkg/gui_app.py", base=base)],
    options={
        'build_exe': {
            'packages': find_packages(exclude=('tests', 'docs')),
            'include_files': ['icons', 'config'],
        }
    }
)

include a number of image and config files

data_filescx_Freeze 忽略。相反,它使用在 options 中传递的自己的名为 include_files 的参数。根据文档,它应该是

list containing files to be copied to the target directory; it is expected that this list will contain strings or 2-tuples for the source and destination; the source can be a file or a directory (in which case the tree is copied except for .svn and CVS directories); the target must not be an absolute path

所以你在data_files中指定的内容变成了

setup(
    ...
    options={'build_exe': {'include_files': ['icons', 'config']}},
)

这将复制文件而不更改它们的相对路径。要更改它们,请以元组形式传递目标路径。例如,将 icons 中的文件写入目标目录 ico:

options={'build_exe': {'include_files': [('icons', 'ico'), 'config']}}

config/mycfg.json写成config/othercfg.json:

options={'build_exe': {'include_files': [('config/mycfg.json', 'config/othercfg.json')]}}

exclude unittest files

同样适用于 packages - 当传递给 setup() 函数时,此选项不会对 cx_Freeze 执行任何操作。使用 packages 参数代替 options

comma separated list of packages to include, which includes all submodules in the package

注意子模块是静默包含的 - 小心你在列表中传递的内容,尤其是当你使用 find_packages() 时。例如,

find_packages(exclude=['tests.*'])

将排除 tests 的所有子包,但不排除 tests 本身。所以当声明

'packages': find_packages(exclude=['tests.*'])

由于包含根包testsfind_packages中排除的所有子包都将被包含回来。所以排除无效。

Source.