4. 创建源代码分发包
*******************

注解:

  这篇文档只有在
  https://setuptools.readthedocs.io/en/latest/setuptools.html 上的
  "setuptools" 文档独立涵盖此处包含的所有相关信息之前，才会单独保留。

如 一个简单的例子 一节所示，可以使用 **sdist** 命令来创建一个源代码分
发包。 在最简单的场景下，:

   python setup.py sdist

（假定你没有在设置脚本或配置文件中指定任何 **sdist** 选项），**sdist**
将创建基于当前平台的默认格式的归档。 在 Unix 上默认格式为 gzip 的 tar
文件，而在 Windows 上则为 ZIP 文件。

你可以使用 "--formats" 选项来指定任何你想要的格式，例如:

   python setup.py sdist --formats=gztar,zip

创建一个 gzip 的 tar 文件和一个 zip 文件。 可用的格式有:

+-------------+---------------------------+-----------+
| 格式        | 描述                      | 注释      |
|=============|===========================|===========|
| "zip"       | zip 文件 (".zip")         | (1),(3)   |
+-------------+---------------------------+-----------+
| "gztar"     | gzip'ed tar 文件          | (2)       |
|             | (".tar.gz")               |           |
+-------------+---------------------------+-----------+
| "bztar"     | bzip2'ed tar 文件         |           |
|             | (".tar.bz2")              |           |
+-------------+---------------------------+-----------+
| "xztar"     | xz'ed tar 文件            |           |
|             | (".tar.xz")               |           |
+-------------+---------------------------+-----------+
| "ztar"      | 压缩 tar 文件 (".tar.Z")  | (4)       |
+-------------+---------------------------+-----------+
| "tar"       | tar 文件 (".tar")         |           |
+-------------+---------------------------+-----------+

在 3.5 版更改: 添加了对 "xztar" 格式的支持

注释:

1. 默认Windows

2. 默认 Unix

3. 需要有外部 **zip** 工具或 "zipfile" 模块（自 Python 1.6 起是标准
   Python 库的一部分）

4. 需要有 **compress** 程序。 请注意此格式计划要弃用并将在未来的
   Python 版本中被移除。

当使用任意 "tar" 格式 ("gztar", "bztar", "xztar", "ztar" 或 "tar") 时
，在 Unix 中你可以指定将为每个归档成员设置的 "owner" 和 "group" 名称。

举例来说，如果你希望归档中所有文件均为 root 所有:

   python setup.py sdist --owner=root --group=root


4.1. 指定要分发的文件
=====================

如果你没有显式提供文件列表（或如何生成该列表的说明），则 **sdist** 命
令会将一个最小化默认集加入源代码分发版:

* 通过 "py_modules" 和 "packages" 选项指明的所有 Python 源文件

* 在 "ext_modules" 在 "libraries" 选项提及的所有 C 源代码文件

* 通过 "scripts" 选项标识的脚本，参见 Installing Scripts。

* 任何看起来像是测试脚本的文件: "test/test*.py" (目前，Distutils 不会
  对测试脚本做除了将它们包括到源代码分发版以外的任何操作，但是在未来将
  会有一个测试 Python 模块分发版的标准)

* 任何标准的 README 文件 ("README", "README.txt" 或 "README.rst"),
  "setup.py" (或任何你指定的安装脚本) 以及 "setup.cfg"。

* 所有匹配 "package_data" 元数据的文件。 参见 Installing Package Data
  。

* 所有匹配 "data_files" 元数据的文件。 参见 Installing Additional
  Files。

有时这就足够了，但通常你还会希望指定要分发的额外文件。 实现这一点的通
常方式是编写一个 *声明模板*，默认名称为 "MANIFEST.in"。 声明模板就是一
个有关如何生成你的声明文件 "MANIFEST" 的指令列表，也就是要实际包括在你
的源代码分发版中的文件的列表。 **sdist** 命令会处理这个模板并基于其指
令及其在文件系统中的查找结果生成一个声明文件。

如果你想要制作你自己的声明文件，格式很简单：每行一个文件名，仅限常规文
件。 如果你提供你自己的 "MANIFEST"，你必须指明一切：上面描述的默认集将
不适用于这种情况。

在 3.1 版更改: 现有的已生成 "MANIFEST" 将被生成而无需 **sdist** 来将其
修改时间与 "MANIFEST.in" 或 "setup.py" 的修改时间进行比较。

在 3.1.3 版更改: "MANIFEST" 文件以一个表明它们已生成的注释开始。 没有
这条注释的文件不会被覆盖或移除。

在 3.2.2 版更改: **sdist** 将在不存在 "MANIFEST.in" 时读取一个
"MANIFEST" 文件，如它以前所做的一样。

在 3.7 版更改: "README.rst" 现在已被包括在 distutils 标准 README 列表
中。

声明模板每行都有一个命令，其中每个命令指定了一组源代码发布版中要包括或
排除的文件。 举例来说，我们再次关注 Distutils 自己的声明模板:

   include *.txt
   recursive-include examples *.txt *.py
   prune examples/sample?/build

其含义应当很清楚：包括发布在根目录中所有匹配 "*.txt" 的文件，在
"examples" 目录下任何位置上匹配 "*.txt" 或 "*.py" 的所有文件，并排除匹
配 "examples/sample?/build" 的所有目录。 所有这些操作都将在标准的包括
集 *之后* 执行，因此你可以通过在声明模板中的显式指令来排除标准集中的文
件。 （或者，你也可以使用 "--no-defaults" 选项来完全禁用标准集。） 在
声明模板迷你语言中还有一些其他的可用命令；参见 创建源码发行包: sdist
命令 小节。

声明模板中命令的顺序是很重要的：在初始状态下，我们有如上所述的默认文件
列表，而模板中的每个命令将在该文件列表中添加或移除条目。 一旦我们完全
处理好声明模板，我们将再移除不应包括在源代码发布版中的文件:

* Distutils "构建" 目录树中的所有文件 (默认值:file:*build/*)

* 目录中所有名为 "RCS", "CVS", ".svn", ".hg", ".git", ".bzr" 或
  "_darcs" 的文件

现在我们有了完整的文件列表，它已被写入声明以供将来引用，并随后用于构建
源代码分发压缩 包。

你可以通过 "--no-defaults" 选项禁用默认的包括文件集，你还可以通过 "--
no-prune" 禁用默认的排除文件集。

跟随 Distutils 自己的声明模板，让我们追踪' own manifest template,
let's trace how the **sdist** 命令是如何构建要包括在 Distutils 源代码
分发版中的文件列表的:

1. 包括 "distutils" 和 "distutils/command" 子目录中的所有 Python 源代
   码文件（因为与这两个目录对应的包在 setup 脚本的 "packages" 选项中被
   提及 --- 参见 编写安装脚本 一节）

2. 包括 "README.txt", "setup.py" 和 "setup.cfg" (标准文件)

3. 包括 "test/test*.py" (标准文件)

4. 包括分发根目录下的 "*.txt" (这将第二次找到 "README.txt"，但这样的冗
   余随后会被清除)

5. 包括 "examples" 下所有子目录树中匹配 "*.txt" 或 "*.py" 的任何文件，

6. 排除从匹配 "examples/sample?/build" 的目录开始的子目录树中的所有文
   件 --- 这可能会排除之前两个步骤所包括的文件，因此重要的一点是声明模
   板中的 "prune" 命令应放在 "recursive-include" 命令之后

7. 排除整个 "build" 目录树，以及任何 "RCS", "CVS", ".svn", ".hg",
   ".git", ".bzr" and "_darcs" 目录

就像在设置脚本中一样，声明模板中的文件和目录名应当总是以斜杠分隔；
Distutils 将会负责把它们转化为你的系统平台上的标准表示形式。 通过这种
方式，声明模板将可跨操作系统移植。


4.2. 声明相关选项
=================

针对 **sdist** 命令的正常操作过程如下:

* 如果声明文件 (默认为 "MANIFEST") 存在且第一行不为表示它是由
  "MANIFEST.in" 生成的注释，则它会被不加修改地原样使用

* 如果声明文件不存在或是在此之前被自动生成的，则读取 "MANIFEST.in" 并
  创建声明文件

* 如果 "MANIFEST" 或 "MANIFEST.in" 均不存在，则使用默认文件集创建声明
  文件

* 使用当前 "MANIFEST" (刚生成的或读入的) 中的文件列表创建源代码分发压
  缩包

有数个选项可以修改此行为。 首先，使用 "--no-defaults" 和 "--no-prune"
来禁用标准的 "包括" 和 "排除" 集。

第二，你可能只是想要（重）生成声明文件，但不想要创建源代码分发包:

   python setup.py sdist --manifest-only

"-o" 是 "--manifest-only" 的缩写。
