9. API 參照
***********

也參考:

  New and changed setup.py arguments in setuptools
     "setuptools" 项目为 "setup" 函数和其他 API 添加了新的功能，使得
     API 在不同 Python 版本间保持一致，因此推荐以它来取代直接使用
     "distutils"。

備註:

  这篇文档是历史遗留文档，在
  https://setuptools.readthedocs.io/en/latest/setuptools.html 上的
  "setuptools" 文档独立涵盖此处包含的所有相关信息之后，将不再单独作为
  正式文档保留。


9.1. "distutils.core" --- 分发包功能的核心
==========================================

The "distutils.core" 是为了使用 Distutils 工具唯一要安装的模块。它提供
函数 "setup()" （该函数被 setup 脚本调用）。间接提供了类
"distutils.dist.Distribution" 和 "distutils.cmd.Command".

distutils.core.setup(arguments)

   基本的包办一切的函数，它完成了您可以从Distutils方法中请求的大部分事
   情。

   setup函数接受大量参数。这些都列在下表中。

   +----------------------+----------------------------------+---------------------------------------------------------------+
   | 参数名称             | value                            | type                                                          |
   |======================|==================================|===============================================================|
   | *name*               | 包的名字                         | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *version*            | 包的版本号；参见                 | 字符串                                                        |
   |                      | "distutils.version"              |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *description*        | 单行的包的描述                   | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *long_description*   | 更长的包描述                     | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *author*             | 包的作者                         | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *author_email*       | 包的作者的电子邮件               | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *maintainer*         | 当前维护者的名字，如果与作者不同 | 字符串                                                        |
   |                      | 的话。 请注意，如果提供了维护者  |                                                               |
   |                      | ， distutils 将使用它作为 "PKG-  |                                                               |
   |                      | INFO" 中的作者。                 |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *maintainer_email*   | 当前维护者的电子邮件地址（如果与 | 字符串                                                        |
   |                      | 作者不同）                       |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *url*                | 包的URL（主页）                  | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *download_url*       | 包的下载地址                     | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *packages*           | distutils将操作的Python软件包的  | 字符串列表                                                    |
   |                      | 列表                             |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *py_modules*         | distutils 会操作的 Python 模块列 | 字符串列表                                                    |
   |                      | 表                               |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *scripts*            | 要构建和安装的独立脚本文件的列表 | 字符串列表                                                    |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *ext_modules*        | 要构建的 Python 扩展的列表       | 类 "distutils.core.Extension" 的实例的列表                    |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *classifiers*        | 包的类别列表                     | 一个字符串列表；可用的分类器已在 PyPI 上列出。                |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *distclass*          | 要使用的类 "Distribution" 类     | "distutils.core.Distribution" 的子类                          |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *script_name*        | setup.py 脚本名称 —— 默认为      | 字符串                                                        |
   |                      | "sys.argv[0]"                    |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *script_args*        | 提供给安装脚本的参数             | 字符串列表                                                    |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *options*            | 安装脚本的默认选项               | 字典                                                          |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *license*            | 包的许可证                       | 字符串                                                        |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *keywords*           | 描述性的元数据，参见 **PEP 314** | 字符串列表或逗号分隔的字符串                                  |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *platforms*          |                                  | 字符串列表或逗号分隔的字符串                                  |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *cmdclass*           | 一个从命令名称到 "Command" 子类  | 字典                                                          |
   |                      | 的映射                           |                                                               |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *data_files*         | 要安装的数据文件列表             | 列表                                                          |
   +----------------------+----------------------------------+---------------------------------------------------------------+
   | *package_dir*        | 包到目录名的映射                 | 字典                                                          |
   +----------------------+----------------------------------+---------------------------------------------------------------+

distutils.core.run_setup(script_name[, script_args=None, stop_after='run'])

   在某种程度上受控制的环境中运行一个安装脚本，并返回驱动程序的
   "distutils.dist.Distribution" 实例。 如果你需要查找分发元数据 (作为
   关键字 args 从 *script* 传递到 "setup()")，或者配置文件或命令行的内
   容，这将非常有用。

   *script_name* 是一个将使用 "exec()" 读取和运行的文件。在调用期间，
   "sys.argv[0]" 将被替换为 *script*。 *script_args* 是一个字符串列表
   ；如果提供了 "sys.argv[1:]"，则在调用期间将被 *script_args* 替换。

   *stop_after* 告诉 "setup()" 何时停止处理；可能的值有：

   +-----------------+-----------------------------------------------+
   | value           | 描述                                          |
   |=================|===============================================|
   | *init*          | 在创建 "Distribution" 实例并使用传给          |
   |                 | "setup()" 的关键字参数填充之后 停止           |
   +-----------------+-----------------------------------------------+
   | *config*        | 在解析配置文件（并将其数据存储在              |
   |                 | "Distribution" 实例中）之后停止               |
   +-----------------+-----------------------------------------------+
   | *commandline*   | 在解析命令行（"sys.argv[1:]" 或 *script_args* |
   |                 | ）（并将数据存储在 "Distribution" 实例中）之  |
   |                 | 后停止                                        |
   +-----------------+-----------------------------------------------+
   | *run*           | 在运行所有命令之后停止（就像以常规方式调用    |
   |                 | "setup()" 一样）。 这是 默认值。              |
   +-----------------+-----------------------------------------------+

此外，"distutils.core" 模块还公开了一些位于其他地方的类。

* 来自 "distutils.extension" 的 "Extension"

* 来自 "distutils.cmd" 的 "Command"

* 来自 "distutils.dist" 的 "Distribution"

下面是对其中每一项的简短说明，但完整的参考请参阅相关模块。

class distutils.core.Extension

   Extension 类描述了设置脚本中的单个 C 或 C++ 扩展模块。 它在其构造器
   中接受以下关键字参数：

   +--------------------------+----------------------------------+-----------------------------+
   | 参数名称                 | value                            | type                        |
   |==========================|==================================|=============================|
   | *name*                   | 扩展的完整名称，包括任何包 ---   | 字符串                      |
   |                          | 即 *不是* 文件名或路径名，而是以 |                             |
   |                          | 点号 分隔的 Python 名称          |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *sources*                | 源文件名列表，相对于分发包根目录 | 字符串列表                  |
   |                          | （设置脚本所在位置），为了可移植 |                             |
   |                          | 性 采用 Unix 形式（以斜杠分隔）  |                             |
   |                          | 。 源文件可以是 C、C++、SWIG     |                             |
   |                          | (.i)、平台 特定资源文件，或者由  |                             |
   |                          | **build_ext** 命令识别为 Python  |                             |
   |                          | 扩展源文件的任 何其他文件。      |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *include_dirs*           | 用于搜索 C/C++ 头文件的目录列表  | 字符串列表                  |
   |                          | （为了可移植性采用 Unix 形式）   |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *define_macros*          | 要定义的宏列表；每个宏都使用一个 | 元组列表                    |
   |                          | 二元组 "(name, value)" 来定义，  |                             |
   |                          | 其中 *value* 是将其定义为的字符  |                             |
   |                          | 串，或是 "None" 表示定义它而不带 |                             |
   |                          | 特定值（ 相当于源码中的 "#define |                             |
   |                          | FOO" 或 Unix C 编译器命令行上的  |                             |
   |                          | "-DFOO"）                        |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *undef_macros*           | 要明确取消定义的宏列表           | 字符串列表                  |
   +--------------------------+----------------------------------+-----------------------------+
   | *library_dirs*           | 在链接时用于搜索 C/C++ 库的目录  | 字符串列表                  |
   |                          | 列表                             |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *libraries*              | 要链接的库名列表（不是文件名或路 | 字符串列表                  |
   |                          | 径）                             |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *runtime_library_dirs*   | 在运行时（对于共享扩展，即加载扩 | 字符串列表                  |
   |                          | 展时）用于搜索 C/C++ 库的目录列  |                             |
   |                          | 表                               |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *extra_objects*          | 要一起链接的额外文件列表（例如未 | 字符串列表                  |
   |                          | 包含在 'sources' 中的目标文件、  |                             |
   |                          | 必须 显式指定的静态库、二进制资  |                             |
   |                          | 源文件等）                       |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *extra_compile_args*     | 在编译 'sources' 中的源文件时要  | 字符串列表                  |
   |                          | 使用的任何额外平台和编译器特定信 |                             |
   |                          | 息。 对于命令行有意义的平台和编  |                             |
   |                          | 译器，这通常是一个命令行参数列表 |                             |
   |                          | ，但对于 其他平台，它可以是任何  |                             |
   |                          | 内容。                           |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *extra_link_args*        | 在将目标文件链接在一起以创建扩展 | 字符串列表                  |
   |                          | （或创建新的静态 Python 解释器） |                             |
   |                          | 时 要使用的任何额外平台和编译器  |                             |
   |                          | 特定信息。 其解释方式与          |                             |
   |                          | 'extra_compile_args' 类似。      |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *export_symbols*         | 要从共享扩展导出的符号列表。 并  | 字符串列表                  |
   |                          | 非在所有平台上都使用，并且对于   |                             |
   |                          | Python 扩展通常也不是必需的，因  |                             |
   |                          | 为 Python 扩展通常只导出一个符号 |                             |
   |                          | ： "init" + extension_name。     |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *depends*                | 扩展名依赖的文件列表             | 字符串列表                  |
   +--------------------------+----------------------------------+-----------------------------+
   | *language*               | 扩展语言（即 "'c'"、 "'c++'"、   | 字符串                      |
   |                          | "'objc'"）。 如果未提供，则会根  |                             |
   |                          | 据源 文件扩展名进行检测。        |                             |
   +--------------------------+----------------------------------+-----------------------------+
   | *optional*               | 指定扩展中的构建失败不应中止构建 | 布尔                        |
   |                          | 过程，而只是跳过扩展。           |                             |
   +--------------------------+----------------------------------+-----------------------------+

   在 3.8 版的變更: 在 Unix 上，除了 Android 和 Cygwin 之外，C 扩展不
   再链接到 libpython。

class distutils.core.Distribution

   "Distribution" 描述了如何构建、安装和打包 Python 软件包。

   有关 Distribution 构造器接受的关键字参数列表，请参阅 "setup()" 函数
   。 "setup()" 会创建一个 Distribution 实例。

   在 3.7 版的變更: 如果 "classifiers"、 "keywords" 和 "platforms" 字
   段未指定为列表或字符串，"Distribution" 现在会发出警告。

class distutils.core.Command

   "Command" 类（或者更准确地说，其某个子类的实例）实现单个 distutils
   命令。


9.2. "distutils.ccompiler" --- CCompiler基类
============================================

此模块提供了 "CCompiler" 类的抽象基类。 "CCompiler" 实例可用于构建单个
项目所需的所有编译和链接步骤。 还提供了为编译器设置选项的方法 --- 宏定
义、包含目录、链接路径、库等。

此模块提供以下函数。

distutils.ccompiler.gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries)

   生成用于搜索库目录并与特定库链接的链接器选项。 *libraries* 和
   *library_dirs* 分别是库名称（不是文件名！）列表和搜索目录列表。 返
   回适合与某个编译器一起使用的命令行选项列表（取决于传入的两个格式字
   符串）。

distutils.ccompiler.gen_preprocess_options(macros, include_dirs)

   生成至少两种类型的编译器（典型的 Unix 编译器和 Visual C++）所使用的
   C 预处理器选项 ("-D", "-U", "-I")。 *macros* 是常规内容，即由一元组
   或二元组组成的列表，其中 "(name,)" 表示取消定义 ("-U") 宏 *name*，
   而 "(name, value)" 表示将宏 *name* 定义 ("-D") 为 *value*。
   *include_dirs* 只是一个要添加到头文件搜索路径 ("-I") 的目录名称列表
   。 返回适合 Unix 编译器或 Visual C++ 的命令行选项列表。

distutils.ccompiler.get_default_compiler(osname, platform)

   确定给定平台要使用的默认编译器。

   *osname* 应当是标准 Python 操作系统名称之一（即由 "os.name" 返回的
   名称），而 *platform* 是 "sys.platform" 为相关平台返回的常见值。

   如果未给出形参，则默认值为 "os.name" 和 "sys.platform"。

distutils.ccompiler.new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0)

   用于为所提供的平台/编译器组合生成某个 CCompiler 子类实例的工厂函数
   。 *plat* 默认为 "os.name" （例如 "'posix'"、 "'nt'"），而
   *compiler* 默认为该平台的默认编译器。 目前仅支持 "'posix'" 和
   "'nt'"，默认编译器是“传统 Unix 接口” ("UnixCCompiler" 类) 和 Visual
   C++ ("MSVCCompiler" 类)。 请注意，在 Windows 下请求 Unix 编译器对象
   以及在 Unix 下请求 Microsoft 编译器对象是完全可能的 --- 如果你为
   *compiler* 提供了值，*plat* 将被忽略。

distutils.ccompiler.show_compilers()

   打印可用编译器的列表（由 **build**、 **build_ext**、 **build_clib**
   的 "--help-compiler" 选项使用）。

class distutils.ccompiler.CCompiler([verbose=0, dry_run=0, force=0])

   抽象基类 "CCompiler" 定义了实际编译器类必须实现的接口。 该类还具有
   供几个编译器类使用的一些实用工具方法。

   编译器抽象类背后的基本思想是，每个实例都可以用于构建单个项目中的所
   有编译/链接步骤。 因此，所有这些编译和链接步骤共有的属性 --- 包含目
   录、要定义的宏、要链接的库等 --- 都是编译器实例的属性。 为了允许单
   独处理各个文件时的可变性，大多数这些属性可以在每次编译或每次链接的
   基础上进行更改。

   每个子类的构造器都会创建一个 Compiler 对象的实例。 标志为 *verbose*
   （显示详细输出）、 *dry_run* （不实际执行步骤）和 *force* （重新构
   建所有内容，无论依赖关系如何）。 所有这些标志均默认为 "0" （关闭）
   。 请注意，你可能并不希望直接实例化 "CCompiler" 或其某个子类 —— 请
   改用 "distutils.CCompiler.new_compiler()" 工厂函数。

   以下方法允许你手动更改 Compiler 类实例的编译器选项。

   add_include_dir(dir)

      将 *dir* 添加到将用于搜索头文件的目录列表中。 编译器会按照通过连
      续调用 "add_include_dir()" 所提供的顺序来搜索目录。

   set_include_dirs(dirs)

      将要搜索的目录列表设置为 *dirs* （字符串列表）。 这会覆盖之前对
      "add_include_dir()" 的任何调用；后续对 "add_include_dir()" 的调
      用会添加到传给 "set_include_dirs()" 的列表中。 这不会影响编译器
      默认可能搜索的任何标准包含目录列表。

   add_library(libname)

      将 *libname* 添加到由此编译器对象驱动的所有链接中所包含的库列表
      中。 请注意，*libname* *不* 应是包含库的文件名，而应是库本身的名
      称：实际文件名将由链接器、编译器或编译器类（取决于平台）推断得出
      。

      链接器将按照提供给 "add_library()" 和/或 "set_libraries()" 的顺
      序链接库。 重复库名称是完全有效的；链接器将按照库被提及的次数对
      其进行链接。

   set_libraries(libnames)

      将由此编译器对象驱动的所有链接中所包含的库列表设置为 *libnames*
      （字符串列表）。 这不会影响链接器默认可能包含的任何标准系统库。

   add_library_dir(dir)

      将 *dir* 添加到将用于搜索指定给 "add_library()" 和
      "set_libraries()" 的库的目录列表中。 链接器将按照提供给
      "add_library_dir()" 和/或 "set_library_dirs()" 的顺序搜索库。

   set_library_dirs(dirs)

      将库搜索目录列表设置为 *dirs* （字符串列表）。 这不会影响链接器
      默认可能搜索的任何标准库搜索路径。

   add_runtime_library_dir(dir)

      将 *dir* 添加到运行时将用于搜索共享库的目录列表中。

   set_runtime_library_dirs(dirs)

      将运行时用于搜索共享库的目录列表设置为 *dirs* （字符串列表）。
      这不会影响运行时链接器默认可能搜索的任何标准搜索路径。

   define_macro(name[, value=None])

      为由此编译器对象驱动的所有编译定义一个预处理器宏。 可选形参
      *value* 应为一个字符串；如果未提供，则该宏将在没有显式值的情况下
      被定义，确切结果取决于所使用的编译器。

   undefine_macro(name)

      为由此编译器对象驱动的所有编译取消定义一个预处理器宏。 如果同一
      个宏由 "define_macro()" 定义并由 "undefine_macro()" 取消定义，则
      最后一次调用优先（包括多次重新定义或取消定义）。 如果在单次编译
      的基础上（即在调用 "compile()" 时）重新定义/取消定义了该宏，则那
      次操作优先。

   add_link_object(object)

      将 *object* 添加到由此编译器对象驱动的每次链接中要包含的目标文件
      （或类似物，例如显式命名的库文件或“资源编译器”的输出）列表中。

   set_link_objects(objects)

      将每次链接中要包含的目标文件（或类似物）列表设置为 *objects*。
      这不会影响链接器默认可能包含的任何标准目标文件（例如系统库）。

   以下方法实现了用于自动检测编译器选项的方法，提供了一些类似于 GNU
   **autoconf** 的功能。

   detect_language(sources)

      检测给定文件或文件列表的语言。 使用实例属性 "language_map" （字
      典）和 "language_order" （列表）来完成此工作。

   find_library_file(dirs, lib[, debug=0])

      在指定的目录列表中搜索静态或共享库文件 *lib* 并返回该文件的完整
      路径。 如果 *debug* 为真值，则查找调试版本（如果这在当前平台上有
      意义）。 如果在任何指定目录中均未找到 *lib*，则返回 "None"。

   has_function(funcname[, includes=None, include_dirs=None, libraries=None, library_dirs=None])

      返回一个布尔值，指示当前平台上是否支持 *funcname*。 可选参数可用
      于通过提供额外的包含文件和路径以及库和路径来扩充编译环境。

   library_dir_option(dir)

      返回用于将 *dir* 添加到库搜索目录列表中的编译器选项。

   library_option(lib)

      返回用于将 *lib* 添加到链接进共享库或可执行文件的库列表中的编译
      器选项。

   runtime_library_dir_option(dir)

      返回用于将 *dir* 添加到运行时库搜索目录列表中的编译器选项。

   set_executables(**args)

      定义将运行以执行各个编译阶段的可执行文件（及其选项）。 此处可指
      定的确切可执行文件集取决于编译器类（通过 'executables' 类属性）
      ，但大多数都会有：

      +----------------+--------------------------------------------+
      | attribute --   | 描述                                       |
      | 属性           |                                            |
      |================|============================================|
      | *compiler*     | C/C++ 编译器                               |
      +----------------+--------------------------------------------+
      | *linker_so*    | 用于创建共享对象和库的链接器               |
      +----------------+--------------------------------------------+
      | *linker_exe*   | 用于创建二进制可执行文件的链接器           |
      +----------------+--------------------------------------------+
      | *archiver*     | 静态库创建者                               |
      +----------------+--------------------------------------------+

      在具有命令行的平台（Unix、DOS/Windows）上，其中每一项都是一个字
      符串，将被拆分为可执行文件名和（可选的）参数列表。 （拆分字符串
      的方式与 Unix shell 的操作方式类似：单词由空格分隔，但引号和反斜
      杠可以覆盖此行为。 参见 "distutils.util.split_quoted()"。）

   以下方法会调用构建过程中的各个阶段。

   compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None])

      编译一个或多个源文件。 生成目标文件（例如将 ".c" 文件转换为 ".o"
      文件）。

      *sources* 必须是文件名列表，最可能是 C/C++ 文件，但实际上可以是
      特定编译器和编译器类能够处理的任何内容（例如 "MSVCCompiler" 可以
      处理 *sources* 中的资源文件）。 返回目标文件名列表，对应
      *sources* 中的每个源文件名。 根据具体实现，并非所有源文件都一定
      会被编译，但会返回所有相应的目标文件名。

      如果给出了 *output_dir*，目标文件将被放置在其下，同时保留其原始
      路径组件。 也就是说，"foo/bar.c" 通常会编译为 "foo/bar.o" （对于
      Unix 实现）；如果 *output_dir* 为 *build*，那么它将编译为
      "build/foo/bar.o"。

      如果给出了 *macros*，它必须是宏定义列表。 宏定义可以是 "(name,
      value)" 二元组或 "(name,)" 一元组。 前者定义一个宏；如果值为
      "None"，则该宏在定义时不带显式值。 一元组的情况会取消定义一个宏
      。 靠后的定义/重新定义/取消定义优先。

      如果给出了 *include_dirs*，它必须是字符串列表，即仅针对此次编译
      要添加到默认包含文件搜索路径中的目录。

      *debug* 是一个布尔值；如果为真值，编译器将被指示在目标文件内部（
      或旁边）输出调试符号。

      *extra_preargs* 和 *extra_postargs* 是依赖于具体实现的。 在具有
      命令行概念的平台（例如 Unix、DOS/Windows）上，它们最可能是字符串
      列表：要前置/追加到编译器命令行的额外命令行参数。 在其他平台上，
      请查阅实现类的文档。 无论如何，当抽象编译器框架不敷使用时，它们
      旨在作为应急手段。

      如果给出了 *depends*，它是一个所有目标都依赖的文件名列表。 如果
      源文件比 depends 中的任何文件都旧，则该源文件将被重新编译。 这支
      持依赖关系跟踪，但仅限于粗粒度级别。

      失败时引发 "CompileError"。

   create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None])

      将一堆内容链接在一起以创建静态库文件。 这“一堆内容”由作为
      *objects* 提供的目标文件列表、提供给 "add_link_object()" 和/或
      "set_link_objects()" 的额外目标文件、提供给 "add_library()" 和/
      或 "set_libraries()" 的库，以及作为 *libraries* 提供的库（如果有
      ）组成。

      *output_libname* 应当是库名称，而不是文件名；文件名将从库名称推
      断得出。 *output_dir* 是将放置库文件的目录。

      *debug* 是一个布尔值；如果为真值，库中将包含调试信息（请注意，在
      大多数平台上，这在编译步骤中才起作用：此处包含 *debug* 标志只是
      为了保持一致性）。

      *target_lang* 是编译给定目标文件所针对的目标语言。 这允许在链接
      时对特定语言进行特殊处理。

      失败时引发 "LibError"。

   link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

      将一堆内容链接在一起以创建可执行文件或共享库文件。

      这“一堆内容”由作为 *objects* 提供的目标文件列表组成。
      *output_filename* 应当是一个文件名。 如果提供了 *output_dir*，则
      *output_filename* 是相对于它的（即如果需要，*output_filename* 可
      以提供目录组件）。

      *libraries* 是要链接的库列表。 这些是库名称，而不是文件名，因为
      它们会以平台特定的方式转换为文件名（例如 *foo* 在 Unix 上变为
      "libfoo.a"，在 DOS/Windows 上变为 "foo.lib"）。 但是，它们可以包
      含目录组件，这意味着链接器将在该特定目录中查找，而不是搜索所有常
      规位置。

      如果提供了 *library_dirs*，它应当是一个用于搜索以裸库名（即没有
      目录组件）指定的库的目录列表。 这些目录优先于系统默认值以及提供
      给 "add_library_dir()" 和/或 "set_library_dirs()" 的目录。
      *runtime_library_dirs* 是一个将被嵌入到共享库中并用于在运行时搜
      索 *它* 所依赖的其他共享库的目录列表。 （这可能仅在 Unix 上相关
      。）

      *export_symbols* 是共享库将导出的符号列表。 （这似乎仅在 Windows
      上相关。）

      *debug* 与 "compile()" 和 "create_static_lib()" 中的相同，微小的
      区别在于它在大多数平台上实际上起作用（与 "create_static_lib()"
      相反，后者包含 *debug* 标志主要是为了形式一致）。

      *extra_preargs* 和 *extra_postargs* 与 "compile()" 中的相同（当
      然，不同之处在于它们为所使用的特定链接器提供命令行参数）。

      *target_lang* 是编译给定目标文件所针对的目标语言。 这允许在链接
      时对特定语言进行特殊处理。

      失败时引发 "LinkError"。

   link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None])

      链接可执行文件。 *output_progname* 是可执行文件的名称，而
      *objects* 是要链接进来的目标文件名列表。 其他参数与 "link()" 方
      法相同。

   link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

      链接共享库。 *output_libname* 是输出库的名称，而 *objects* 是要
      链接进来的目标文件名列表。 其他参数与 "link()" 方法相同。

   link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

      链接共享目标文件。 *output_filename* 是将创建的共享目标文件的名
      称，而 *objects* 是要链接进来的目标文件名列表。 其他参数与
      "link()" 方法相同。

   preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None])

      预处理单个在 *source* 中命名的 C/C++ 源文件。 输出将写入名为
      *output_file* 的文件，如果未提供 *output_file* 则写入 *stdout*。
      *macros* 是与 "compile()" 相同的宏定义列表，它将扩充通过
      "define_macro()" 和 "undefine_macro()" 设置的宏。 *include_dirs*
      是将以与 "add_include_dir()" 相同的方式添加到默认列表中的目录名
      称列表。

      失败时引发 "PreprocessError"。

   以下实用工具方法由 "CCompiler" 类定义，供各个具体子类使用。

   executable_filename(basename[, strip_dir=0, output_dir=''])

      返回给定 *basename* 的可执行文件的文件名。 通常对于非 Windows 平
      台，这与 basename 相同，而 Windows 将会添加 ".exe"。

   library_filename(libname[, lib_type='static', strip_dir=0, output_dir=''])

      返回当前平台上给定库名称的文件名。 在 Unix 上，*lib_type* 为
      "'static'" 的库通常采用 "liblibname.a" 的形式，而 *lib_type* 为
      "'dynamic'" 的库将采用 "liblibname.so" 的形式。

   object_filenames(source_filenames[, strip_dir=0, output_dir=''])

      返回给定源文件的目标文件名称。 *source_filenames* 应当是文件名列
      表。

   shared_object_filename(basename[, strip_dir=0, output_dir=''])

      返回给定文件名 *basename* 的共享目标文件名称。

   execute(func, args[, msg=None, level=1])

      调用 "distutils.util.execute()"。 此方法在记录日志并考虑
      *dry_run* 标志之后，使用给定的参数 *args* 调用 Python 函数
      *func*。

   spawn(cmd)

      调用 "distutils.util.spawn()"。这会调用一个外部进程来运行给定的
      命令。

   mkpath(name[, mode=511])

      调用 "distutils.dir_util.mkpath()"。这会创建一个目录以及任何缺失
      的祖先目录。

   move_file(src, dst)

      调用 "distutils.file_util.move_file()"。将 *src* 重命名为 *dst*
      。

   announce(msg[, level=1])

      使用 "distutils.log.debug()" 写入一条消息。

   warn(msg)

      向标准错误写入一条警告消息 *msg*。

   debug_print(msg)

      如果在此 "CCompiler" 实例上设置了 *debug* 标志，则将 *msg* 打印
      到标准输出，否则不执行任何操作。


9.3. "distutils.unixccompiler" --- Unix C 编译器
================================================

此模块提供 "UnixCCompiler" 类，它是 "CCompiler" 的子类，用于处理典型的
Unix 风格命令行 C 编译器：

* 通过 "-Dname[=value]" 定义的宏

* 通过 "-Uname" 取消定义的宏

* 包括通过 "-Idir" 指定的搜索目录

* 通过 "-llib" 指定的库

* 通过 "-Ldir" 指定的库搜索目录

* 编译由带有 "-c" 选项的 **cc** （或类似）可执行文件处理：将 ".c" 编译
  为 ".o"

* 链接静态库由 **ar** 命令（可能配合 **ranlib** ）处理

* 链接共享库由 **cc** "-shared" 处理


9.4. "distutils.msvccompiler" --- Microsoft 编译器
==================================================

此模块提供 "MSVCCompiler"，它是针对 Microsoft Visual Studio 的抽象类
"CCompiler" 的实现。通常，扩展模块需要使用与编译 Python 相同的编译器进
行编译。对于 Python 2.3 及更早版本，编译器为 Visual Studio 6。对于
Python 2.4 和 2.5，编译器为 Visual Studio .NET 2003。

"MSVCCompiler" 通常会自行选择正确的编译器、链接器等。若要覆盖此选择，
必须同时设置环境变量 *DISTUTILS_USE_SDK* 和 *MSSdk*。*MSSdk* 表示当前
环境已由 SDK 的 "SetEnv.Cmd" 脚本设置，或者在安装 SDK 时已注册了环境变
量；*DISTUTILS_USE_SDK* 表示 distutils 用户已明确选择覆盖
"MSVCCompiler" 的编译器选择。


9.5. "distutils.bcppcompiler" --- Borland 编译器
================================================

此模块提供 "BorlandCCompiler"，它是针对 Borland C++ 编译器的抽象类
"CCompiler" 的子类。


9.6. "distutils.cygwincompiler" --- Cygwin 编译器
=================================================

此模块提供 "CygwinCCompiler" 类，它是 "UnixCCompiler" 的子类，用于处理
GNU C 编译器的 Windows Cygwin 移植版。它还包含 Mingw32CCompiler 类，用
于处理 GCC 的 mingw32 移植版（与处于 no-cygwin 模式的 cygwin 相同）。


9.7. "distutils.archive_util" --- 归档工具
==========================================

此模块提供了几个用于创建归档文件（如 tarball 或 zip 文件）的函数。

distutils.archive_util.make_archive(base_name, format[, root_dir=None, base_dir=None, verbose=0, dry_run=0])

   创建一个归档文件（例如 "zip" 或 "tar" ）。*base_name* 是要创建的文
   件名，不包含任何特定格式的扩展名；*format* 是归档格式："zip"、"tar"
   、"gztar"、"bztar"、"xztar" 或 "ztar" 之一。*root_dir* 是将作为归档
   根目录的目录；即我们通常在创建归档之前先 "chdir" 进入 *root_dir*。
   *base_dir* 是我们开始归档的目录；即 *base_dir* 将成为归档中所有文件
   和目录的公共前缀。*root_dir* 和 *base_dir* 均默认为当前目录。返回归
   档文件的名称。

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

distutils.archive_util.make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0])

   将 *base_dir* 中及其下的所有文件创建为一个（可选压缩的）tar 归档文
   件。*compress* 必须为 "'gzip'" （默认值）、"'bzip2'"、"'xz'"、
   "'compress'" 或 "None"。对于 "'compress'" 方法，名为 **compress**
   的压缩工具必须在默认程序搜索路径中，因此这可能是 Unix 特有的。输出
   的 tar 文件将命名为 "base_dir.tar"，并可能加上相应的压缩扩展名（
   ".gz"、".bz2"、".xz" 或 ".Z" ）。返回输出文件名。

   在 3.5 版的變更: 添加了对 "xz" 压缩的支持。

distutils.archive_util.make_zipfile(base_name, base_dir[, verbose=0, dry_run=0])

   将 *base_dir* 中及其下的所有文件创建为一个 zip 文件。输出的 zip 文
   件将命名为 *base_name* + ".zip"。使用 Python 的 "zipfile" 模块（如
   果可用）或 InfoZIP 的 "zip" 工具（如果已安装且在默认搜索路径中找到
   ）。如果两个工具均不可用，则引发 "DistutilsExecError"。返回输出 zip
   文件的名称。


9.8. "distutils.dep_util" --- 依赖关系检查
==========================================

此模块提供了用于对文件和文件组执行简单的基于时间戳的依赖关系检查的函数
；以及完全基于此类时间戳依赖关系分析的函数。

distutils.dep_util.newer(source, target)

   如果 *source* 存在且修改时间比 *target* 更新，或者如果 *source* 存
   在而 *target* 不存在，则返回真值。如果两者都存在且 *target* 的修改
   时间与 *source* 相同或更新，则返回假值。如果 *source* 不存在，则引
   发 "DistutilsFileError"。

distutils.dep_util.newer_pairwise(sources, targets)

   并行遍历两个文件名列表，测试每个源文件是否比其对应的目标文件更新。
   根据 "newer()" 的语义，返回源文件比目标文件更新的一对列表
   (*sources*, *targets*)。

distutils.dep_util.newer_group(sources, target[, missing='error'])

   如果 target 相对于 sources 中的任何文件已经过期，那么返回 true。换
   句话说，如果 target 存在且比 sources 中的每个文件都更新，那么返回
   false；否则，返回 true。missing 参数控制当源文件缺失时的处理方式：
   默认值（"'error'"）会抛出 "os.stat()" 产生的 "OSError"；如果设为
   "'ignore'"，那么静默忽略缺失的源文件；如果设为 "'newer'"，那么任何
   缺失的源文件都会导致假定 target 已经过期（这在“空运行”模式下很实用
   ：即使由于输入文件缺失导致命令不能实际执行，该模式也会让你模拟执行
   这些命令，反正你也不会真正运行它们）。


9.9. "distutils.dir_util" --- 目录树操作
========================================

此模块提供了用于操作目录和目录树的函数。

distutils.dir_util.mkpath(name[, mode=0o777, verbose=0, dry_run=0])

   创建一个目录以及任何缺失的祖先目录。如果该目录已存在（或者如果
   *name* 是空字符串，这表示当前目录，当然存在），则不执行任何操作。如
   果在创建过程中无法创建某个目录（例如某个子路径已存在，但它是文件而
   不是目录），则引发 "DistutilsFileError"。如果 *verbose* 为真值，则
   向标准输出打印每次 mkdir 的单行摘要。返回实际创建的目录列表。

distutils.dir_util.create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0])

   在 *base_dir* 下创建将 *files* 放置到此处所需的所有空目录。
   *base_dir* 只是一个不一定已经存在的目录名称；*files* 是要相对于
   *base_dir* 解析的文件名列表。如果 *base_dir* + *files* 中每个文件的
   目录部分尚不存在，则会创建它们。*mode*、*verbose* 和 *dry_run* 标志
   的含义与 "mkpath()" 相同。

distutils.dir_util.copy_tree(src, dst[, preserve_mode=1, preserve_times=1, preserve_symlinks=0, update=0, verbose=0, dry_run=0])

   将整个目录树 *src* 复制到新位置 *dst*。*src* 和 *dst* 都必须是目录
   名。如果 *src* 不是目录，则引发 "DistutilsFileError"。如果 *dst* 不
   存在，则使用 "mkpath()" 创建它。复制的最终结果是 *src* 中的每个文件
   都被复制到 *dst*，并且 *src* 下的目录被递归复制到 *dst*。使用其输出
   名称返回已复制或可能已复制的文件列表。返回值不受 *update* 或
   *dry_run* 的影响：它只是 *src* 下所有文件的列表，其名称更改为位于
   *dst* 下。

   *preserve_mode* 和 *preserve_times* 与
   "distutils.file_util.copy_file()" 中的相同；请注意，它们仅适用于常
   规文件，而不适用于目录。如果 *preserve_symlinks* 为真值，符号链接将
   作为符号链接进行复制（在支持符号链接的平台上！）；否则（默认情况下
   ），将复制符号链接的目标。*update* 和 *verbose* 与 "copy_file()" 中
   的相同。

   *src* 中以 ".nfs" 开头的文件将被跳过（有关这些文件的更多信息，请参
   阅 NFS 常见问题页面 中的回答 D2）。

   在 3.3.1 版的變更: 忽略 NFS 文件。

distutils.dir_util.remove_tree(directory[, verbose=0, dry_run=0])

   递归删除 *directory* 及其下的所有文件和目录。任何错误都将被忽略（除
   非 *verbose* 为真值时会报告给 "sys.stdout" ）。


9.10. "distutils.file_util" --- 单文件操作
==========================================

此模块包含一些用于操作单个文件的工具函数。

distutils.file_util.copy_file(src, dst[, preserve_mode=1, preserve_times=1, update=0, link=None, verbose=0, dry_run=0])

   将文件 *src* 复制到 *dst*。如果 *dst* 是目录，则将 *src* 以相同名称
   复制到该目录中；否则，它必须是一个文件名。（如果该文件已存在，它将
   被无情地覆盖。）如果 *preserve_mode* 为真值（默认值），则会复制文件
   的模式（类型和权限位，或当前平台上类似的任何属性）。如果
   *preserve_times* 为真值（默认值），则还会复制最后修改时间和最后访问
   时间。如果 *update* 为真值，则仅在 *dst* 不存在，或者 *dst* 存在但
   比 *src* 更旧时，才会复制 *src*。

   *link* 允许创建硬链接（使用 "os.link()" ）或符号链接（使用
   "os.symlink()" ）而不是复制：将其设置为 "'hard'" 或 "'sym'"；如果为
   "None" （默认值），则会复制文件。不要在不支持它的系统上设置 *link*
   ："copy_file()" 不会检查硬链接或符号链接是否可用。它使用
   "_copy_file_contents()" 来复制文件内容。

   返回一个元组 "(dest_name, copied)"：*dest_name* 是输出文件的实际名
   称，如果文件已复制（或者当 *dry_run* 为真值时本应被复制），则
   *copied* 为真值。

distutils.file_util.move_file(src, dst[, verbose, dry_run])

   将文件 *src* 移动到 *dst*。如果 *dst* 是目录，则该文件将以相同名称
   移动到其中；否则，只是将 *src* 重命名为 *dst*。返回文件的新完整名称
   。

   警告:

     在 Unix 上使用 "copy_file()" 处理跨设备移动。其他系统呢？

distutils.file_util.write_file(filename, contents)

   创建一个名为 *filename* 的文件，并将 *contents* （不含行终止符的字
   符串序列）写入其中。


9.11. "distutils.util" --- 其他杂项工具函数
===========================================

此模块包含不适合放入任何其他工具模块的其他零碎内容。

distutils.util.get_platform()

   返回一个标识当前平台的字符串。这主要用于区分特定于平台的构建目录和
   特定于平台的已构建发行版。通常包含操作系统名称、版本和架构（由
   'os.uname()' 提供），尽管包含的确切信息取决于操作系统；例如在 Linux
   上，内核版本并不是特别重要。

   返回值的示例：

   * "linux-i586"

   * "linux-alpha"

   * "solaris-2.6-sun4u"

   对于非 POSIX 平台，目前仅返回 "sys.platform"。

   对于 macOS 系统，操作系统版本反映二进制文件可运行的最低版本（即构建
   Python 期间 "MACOSX_DEPLOYMENT_TARGET" 的值），而不是当前系统的操作
   系统版本。

   对于 macOS 上的通用二进制构建，架构值反映通用二进制状态，而不是当前
   处理器的架构。对于 32 位通用二进制文件，架构为 "fat"；对于 64 位通
   用二进制文件，架构为 "fat64"；对于四路通用二进制文件，架构为
   "universal"。从 Python 2.7 和 Python 3.2 开始，架构 "fat3" 用于三路
   通用构建（ppc、i386、x86_64），而 "intel" 用于包含 i386 和 x86_64
   架构的通用构建

   macOS 上的返回值示例:

   * "macosx-10.3-ppc"

   * "macosx-10.3-fat"

   * "macosx-10.5-universal"

   * "macosx-10.6-intel"

   对于 AIX，Python 3.9 及更高版本返回一个以 "aix" 开头的字符串，后跟
   附加字段（由 "'-'" 分隔），这些字段分别代表 AIX 版本、发行版和技术
   级别的组合值（第一个字段）、构建日期（第二个字段）以及位数（第三个
   字段）。Python 3.8 及更早版本仅返回包含 AIX 版本和发行版的单个附加
   字段。

   在 AIX 上返回值的示例：

   * "aix-5307-0747-32" # AIX "oslevel -s": 5300-07-00-0000 上的 32 位
     构建

   * "aix-7105-1731-64" # AIX "oslevel -s": 7100-05-01-1731 上的 64 位
     构建

   * "aix-7.2"          # Python 3.8 及更早版本中报告的旧版形式

   在 3.9 版的變更: AIX 平台字符串格式现在还包含技术级别、构建日期和
   ABI 位数。

distutils.util.convert_path(pathname)

   将 'pathname' 作为可在本地文件系统上使用的名称返回，即按 '/' 分割它
   并使用当前目录分隔符重新组合。这是必需的，因为设置脚本中的文件名始
   终以 Unix 风格提供，在我们实际在文件系统中使用它们之前必须转换为本
   地约定。如果 *pathname* 以斜杠开头或结尾，则在非类 Unix 系统上会引
   发 "ValueError"。

distutils.util.change_root(new_root, pathname)

   返回在前面加上 *new_root* 的 *pathname*。如果 *pathname* 是相对路径
   ，这等价于 "os.path.join(new_root,pathname)"；否则，需要将
   *pathname* 变为相对路径然后再将两者连接起来，这在 DOS/Windows 上比
   较棘手。

distutils.util.check_environ()

   确保 'os.environ' 包含我们保证用户可以在配置文件、命令行选项等中使
   用的所有环境变量。目前这包括：

   * "HOME" - 用户的主目录（仅限 Unix）

   * "PLAT" - 当前平台的描述，包括硬件和操作系统（参见
     "get_platform()" ）

distutils.util.subst_vars(s, local_vars)

   对 *s* 执行 shell/Perl 风格的变量替换。每个出现的后跟名称的 "$" 都
   被视为一个变量，并且该变量将被替换为在 *local_vars* 字典中找到的值
   ，如果它不在 *local_vars* 中，则替换为在 "os.environ" 中找到的值。
   首先会检查/扩充 *os.environ* 以保证它包含某些值：参见
   "check_environ()"。对于在 *local_vars* 或 "os.environ" 中均未找到的
   任何变量，将引发 "ValueError"。

   请注意，这不是一个功能完备的字符串插值函数。有效的 "$variable" 只能
   由大小写字母、数字和下划线组成。不支持 { } 或 ( ) 风格的引用。

distutils.util.split_quoted(s)

   根据类似 Unix shell 的引号和反斜杠规则分割字符串。简而言之：单词由
   空格分隔，只要这些空格未被反斜杠转义，也不在带引号的字符串内。单引
   号和双引号是等价的，并且引号字符可以用反斜杠转义。反斜杠会从任何双
   字符转义序列中去除，仅留下被转义的字符。引号字符会从任何带引号的字
   符串中去除。返回一个单词列表。

distutils.util.execute(func, args[, msg=None, verbose=0, dry_run=0])

   执行某些会影响外部世界的操作（例如写入文件系统）。此类操作很特殊，
   因为它们会被 *dry_run* 标志禁用。此方法会为你处理所有这些繁琐的事务
   ；你所要做的就是提供要调用的函数及其参数元组（以体现正在执行的“外部
   操作”），以及可选的要打印的消息。

distutils.util.strtobool(val)

   将表示真假的字符串转换为真 (1) 或假 (0)。

   真值包括 "y"、"yes"、"t"、"true"、"on" 和 "1"；假值包括 "n"、"no"、
   "f"、"false"、"off" 和 "0"。如果 *val* 是任何其他值，则引发
   "ValueError"。

distutils.util.byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None])

   将一组 Python 源文件字节码编译为 "__pycache__" 子目录中的 ".pyc" 文
   件（参见 **PEP 3147** 和 **PEP 488** ）。*py_files* 是要编译的文件
   列表；任何不以 ".py" 结尾的文件都会被静默跳过。*optimize* 必须为以
   下值之一：

   * "0" - 不优化

   * "1" - 普通优化（类似于 "python -O" ）

   * "2" - 额外优化（类似于 "python -OO" ）

   如果 *force* 为真值，则无论时间戳如何，都会重新编译所有文件。

   每个 *bytecode* 文件中编码的源文件名默认为 *py_files* 中列出的文件
   名；你可以使用 *prefix* 和 *basedir* 修改这些名称。*prefix* 是将从
   每个源文件名中去除的字符串，而 *base_dir* 是将在（去除 *prefix* 之
   后）添加到前面的目录名。你可以根据需要提供 *prefix* 和 *base_dir*
   中的一个或两个（或都不提供）。

   如果 *dry_run* 为真值，则实际上不会执行任何会影响文件系统的操作。

   字节码编译可以直接在此解释器进程中使用标准 "py_compile" 模块完成，
   也可以通过编写临时脚本并执行它来间接完成。通常，你应该让
   "byte_compile()" 自行决定是否使用直接编译（详见源代码）。*direct*
   标志由间接模式下生成的脚本使用；除非你知道自己在做什么，否则请将其
   保持设置为 "None"。

   在 3.2.3 版的變更: 在 "__pycache__" 子目录中创建名称带有 "导入魔术
   标签" 的 ".pyc" 文件，而不是在当前目录中创建不带标签的文件。

   在 3.5 版的變更: 根据 **PEP 488** 创建 ".pyc" 文件。

distutils.util.rfc822_escape(header)

   返回经过转义以便包含在 **RFC 822** 标头中的 *header* 版本，方法是确
   保每个换行符后都有 8 个空格。请注意，它不会对字符串进行任何其他修改
   。


9.12. "distutils.dist" --- Distribution 类
==========================================

此模块提供 "Distribution" 类，它代表正在构建/安装/分发的模块发行版。


9.13. "distutils.extension" --- Extension 类
============================================

此模块提供 "Extension" 类，用于在设置脚本中描述 C/C++ 扩展模块。


9.14. "distutils.debug" --- Distutils 调试模式
==============================================

本模块提供DEBUG标识。


9.15. "distutils.errors" --- Distutils 异常
===========================================

提供由 Distutils 模块使用的异常。请注意，Distutils 模块可能会引发标准
异常；特别是，对于明显是最终用户造成的错误（例如错误的命令行参数），通
常会引发 SystemExit。

此模块在 "from ... import *" 模式下可以安全使用；它仅导出名称以
"Distutils" 开头且以 "Error" 结尾的符号。


9.16. "distutils.fancy_getopt" --- 标准 getopt 模块的包装器
===========================================================

此模块提供了对标准 "getopt" 模块的包装器，并提供以下附加特性：

* 短选项和长选项绑定在一起

* 选项具有帮助字符串，因此 "fancy_getopt()" 可以创建完整的用法摘要

* 选项可设置传入对象的属性

* 布尔选项可以有“否定别名” --- 例如，如果 "--quiet" 是 "--verbose" 的“
  否定别名”，那么命令行上的 "--quiet" 会将 *verbose* 设置为假值。

distutils.fancy_getopt.fancy_getopt(options, negative_opt, object, args)

   包装器函数。*options* 是如 "FancyGetopt" 构造器中所述的
   "(long_option, short_option, help_string)" 三元组列表。
   *negative_opt* 应为将选项名称映射到选项名称的字典，键和值都应在
   *options* 列表中。*object* 是将用于存储值的对象（参见 "FancyGetopt"
   类的 "getopt()" 方法）。*args* 是参数列表。如果将 "None" 作为
   *args* 传入，则将使用 "sys.argv[1:]"。

distutils.fancy_getopt.wrap_text(text, width)

   将 *text* 折行使其宽度小于 *width*。

class distutils.fancy_getopt.FancyGetopt([option_table=None])

   option_table 是一个三元组列表："(long_option, short_option,
   help_string)"

   如果一个选项接受参数，其 *long_option* 应当附加 "'='"；
   *short_option* 应当只是一个单字符，在任何情况下都不含 "':'"。如果
   *long_option* 没有对应的 *short_option*，则 *short_option* 应为
   "None"。所有选项元组都必须有长选项。

"FancyGetopt" 类提供以下方法：

FancyGetopt.getopt([args=None, object=None])

   解析 args 中的命令行选项。将其作为属性存储在 *object* 上。

   如果 *args* 为 "None" 或未提供，则使用 "sys.argv[1:]"。如果
   *object* 为 "None" 或未提供，则会创建一个新的 "OptionDummy" 实例，
   将选项值存储在其中，并返回一个元组 "(args, object)"。如果提供了
   *object*，则会就地修改它并且 "getopt()" 仅返回 *args*；在这两种情况
   下，返回的 *args* 都是所传入 *args* 列表的修改副本，原列表保持不变
   。

FancyGetopt.get_option_order()

   返回上一次运行 "getopt()" 所处理的 "(option, value)" 元组列表。如果
   尚未调用 "getopt()"，则会引发 "RuntimeError"。

FancyGetopt.generate_help([header=None])

   从此 "FancyGetopt" 对象的选项表中生成帮助文本（字符串列表，每个建议
   输出行对应一个字符串）。

   如果提供了 *header*，则在帮助信息的顶部打印所提供的 *header*。


9.17. "distutils.filelist" --- FileList 类
==========================================

此模块提供 "FileList" 类，用于探查文件系统并构建文件列表。


9.18. "distutils.log" --- 简单的 **PEP 282** 风格日志记录
=========================================================


9.19. "distutils.spawn" --- 生成子进程
======================================

此模块提供 "spawn()" 函数，它是用于在子进程中启动另一个程序的各种平台
特定函数的前端。还提供 "find_executable()" 以在路径中搜索给定的可执行
文件名称。


9.20. "distutils.sysconfig" --- 系统配置信息
============================================

在 3.10 版之後被棄用: "distutils.sysconfig" 已合并到 "sysconfig" 中。

"distutils.sysconfig" 模块提供对 Python 底层配置信息的访问。可用的具体
配置变量在很大程度上取决于平台和配置。具体变量取决于正在运行的特定
Python 版本的构建过程；这些变量是在 Unix 系统上随 Python 一起安装的
"Makefile" 和配置头文件中找到的变量。对于从 2.2 开始的 Python 版本，配
置头文件称为 "pyconfig.h"，而对于较早版本的 Python 则称为 "config.h"。

还提供了一些附加函数，用于为 "distutils" 包的其他部分执行一些有用的操
作。

distutils.sysconfig.PREFIX

   "os.path.normpath(sys.prefix)" 的结果。

distutils.sysconfig.EXEC_PREFIX

   "os.path.normpath(sys.exec_prefix)" 的结果。

distutils.sysconfig.get_config_var(name)

   返回单个变量的值。这等价于 "get_config_vars().get(name)"。

distutils.sysconfig.get_config_vars(...)

   返回一组变量定义。如果没有参数，则会返回一个将配置变量名称映射到值
   的字典。如果提供了参数，它们应为字符串，返回值将是一个给出相关联值
   的序列。如果给定名称没有对应的值，则该变量将包含 "None"。

distutils.sysconfig.get_config_h_filename()

   返回配置头文件的完整路径名。对于 Unix，这将是由 **configure** 脚本
   生成的头文件；对于其他平台，头文件将由 Python 源码发行版直接提供。
   该文件是一个平台特定的文本文件。

distutils.sysconfig.get_makefile_filename()

   返回用于构建 Python 的 "Makefile" 的完整路径名。对于 Unix，这将是由
   **configure** 脚本生成的文件；对于其他平台，其含义会有所不同。如果
   该文件存在，它是一个平台特定的文本文件。此函数仅在 POSIX 平台上使用
   。

以下函数随此模块一起被弃用，并且没有直接的替代品。

distutils.sysconfig.get_python_inc([plat_specific[, prefix]])

   返回通用或平台相关的 C 头文件目录。如果 *plat_specific* 为真值，则
   返回平台相关的头文件目录；如果为假值或省略，则返回平台无关的目录。
   如果给出了 *prefix*，则当 *plat_specific* 为假值时将其用作前缀以代
   替 "PREFIX"，或者当 *plat_specific* 为真值时将其用作 exec-prefix 以
   代替 "EXEC_PREFIX"。

distutils.sysconfig.get_python_lib([plat_specific[, standard_lib[, prefix]]])

   返回通用或平台相关的库安装目录。如果 *plat_specific* 为真值，则返回
   平台相关的包含目录；如果为假值或省略，则返回平台无关的目录。如果给
   出了 *prefix*，则当 *plat_specific* 为假值时将其用作前缀以代替
   "PREFIX"，或者当 *plat_specific* 为真值时将其用作 exec-prefix 以代
   替 "EXEC_PREFIX"。如果 *standard_lib* 为真值，则返回标准库的目录，
   而不是第三方扩展的安装目录。

以下函数仅供在 "distutils" 包内部使用。

distutils.sysconfig.customize_compiler(compiler)

   对 "distutils.ccompiler.CCompiler" 实例进行任何平台特定的定制。

   目前此函数仅在 Unix 上需要，但应当始终一致地调用以支持向前兼容性。
   它会插入因不同 Unix 流派而异并存储在 Python 的 "Makefile" 中的信息
   。此信息包括所选的编译器、编译器和链接器选项，以及链接器用于共享对
   象的扩展名。

此函数的用途更加特殊，仅应在 Python 自身的构建过程中使用。

distutils.sysconfig.set_python_build()

   告知 "distutils.sysconfig" 模块它正在作为 Python 构建过程的一部分被
   使用。这会更改许多文件的相对位置，使它们能够位于构建区域中，而不是
   在已安装的 Python 中。


9.21. "distutils.text_file" --- TextFile 类
===========================================

此模块提供 "TextFile" 类，它为文本文件提供了一个接口，可（可选地）负责
去除注释、忽略空行以及使用反斜杠连接行。

class distutils.text_file.TextFile([filename=None, file=None, **options])

   此类提供了一个文件类对象，负责处理具有逐行语法的文本文件时通常需要
   执行的所有操作：去除注释（只要 "#" 是注释字符）、跳过空行、通过转义
   换行符（即行尾的反斜杠）连接相邻行、去除开头和/或末尾的空白字符。所
   有这些都是可选的并且可以独立控制。

   该类提供了 "warn()" 方法，以便你可以生成报告物理行号的警告消息，即
   使所涉及的逻辑行跨越多个物理行。还提供了 "unreadline()" 用于实现逐
   行前瞻。

   "TextFile" 实例使用 *filename*、*file* 或两者一起创建。如果两者均为
   "None"，则会引发 "RuntimeError"。*filename* 应为字符串，而 *file*
   应为文件对象（或提供 "readline()" 和 "close()" 方法的对象）。建议至
   少提供 *filename*，以便 "TextFile" 可以将其包含在警告消息中。如果未
   提供 *file*，"TextFile" 会使用内置函数 "open()" 创建自己的文件对象
   。

   这些选项均为布尔值，并影响 "readline()" 返回的值

   +--------------------+----------------------------------+-----------+
   | 选项名称           | 描述                             | 默认值    |
   |====================|==================================|===========|
   | *strip_comments*   | 去除从 "'#'" 到行尾的内容，以及  | true      |
   |                    | "'#'" 之前的任何空白字符---除非  |           |
   |                    | 它被 反斜杠转义                  |           |
   +--------------------+----------------------------------+-----------+
   | *lstrip_ws*        | 在返回每行之前去除其开头的空白字 | false     |
   |                    | 符                               |           |
   +--------------------+----------------------------------+-----------+
   | *rstrip_ws*        | 在返回每行之前去除其末尾的空白字 | true      |
   |                    | 符（包括行终止符！）。           |           |
   +--------------------+----------------------------------+-----------+
   | *skip_blanks*      | 跳过在去除注释和空白字符 *之后*  | true      |
   |                    | 为空的行。（如果 lstrip_ws 和    |           |
   |                    | rstrip_ws 均为假值，则某些行可能 |           |
   |                    | 仅由空白字符组成：即使           |           |
   |                    | *skip_blanks* 为真值，这些行也 * |           |
   |                    | 不会* 被跳过。）                 |           |
   +--------------------+----------------------------------+-----------+
   | *join_lines*       | 如果在去除注释和空白字符后，反斜 | false     |
   |                    | 杠是一行中最后一个非换行字符，则 |           |
   |                    | 将 下一行连接到该行以形成一个逻  |           |
   |                    | 辑行；如果连续 N 行以反斜杠结尾  |           |
   |                    | ，则会将 N+1 个物理行连接起来以  |           |
   |                    | 形成一个逻辑行。                 |           |
   +--------------------+----------------------------------+-----------+
   | *collapse_join*    | 去除连接到前一行上的那些行开头的 | false     |
   |                    | 空白字符；仅在 "(join_lines and  |           |
   |                    | not lstrip_ws)" 时起作用         |           |
   +--------------------+----------------------------------+-----------+

   请注意，由于 *rstrip_ws* 可以去除末尾的换行符，因此 "readline()" 的
   语义必须与内置文件对象的 "readline()" 方法不同！特别是，
   "readline()" 在到达文件末尾时返回 "None"：如果 *rstrip_ws* 为真值但
   *skip_blanks* 不为真值，则空字符串可能只是一个空行（或全空白字符的
   行）。

   open(filename)

      打开一个新文件 *filename*。这会覆盖任何 *file* 或 *filename* 构
      造器参数。

   close()

      关闭当前文件并忘掉关于它的一切信息（包括文件名和当前行号）。

   warn(msg[, line=None])

      打印（到 stderr）一条与当前文件中的当前逻辑行绑定的警告消息。如
      果文件中的当前逻辑行跨越多个物理行，则警告会指代整个范围，例如
      ""lines 3-5""。如果提供了 *line*，它会覆盖当前行号；它可以是表示
      物理行范围的列表或元组，也可以是表示单个物理行的整数。

   readline()

      从当前文件（或者如果之前已使用 "unreadline()" “退回”了行，则从内
      部缓冲区）读取并返回单个逻辑行。如果 *join_lines* 选项为真值，这
      可能涉及读取拼接成单个字符串的多个物理行。更新当前行号，因此在
      "readline()" 之后调用 "warn()" 会发出关于刚刚读取的物理行的警告
      。在到达文件末尾时返回 "None"，因为如果 *rstrip_ws* 为真值但
      *strip_blanks* 不为真值，则可能会出现空字符串。

   readlines()

      读取并返回当前文件中剩余的所有逻辑行的列表。这会将当前行号更新为
      文件的最后一行。

   unreadline(line)

      将 *line* （一个字符串）推入内部缓冲区，供后续的 "readline()" 调
      用检查。这对于实现具有逐行前瞻功能的解析器非常方便。请注意，使用
      "unreadline()" “退回”的行在随后使用 "readline()" 读取时不会再次
      清理（例如去除空白字符等）。如果在调用 "readline()" 之前多次调用
      了 "unreadline()"，这些行将按最近推入优先的顺序返回。


9.22. "distutils.version" --- 版本号类
======================================


9.23. "distutils.cmd" --- Distutils 命令的抽象基类
==================================================

此模块提供抽象基类 "Command"。

class distutils.cmd.Command(dist)

   定义命令类的抽象基类，这些类是 Distutils 的“工蜂”。每个命令类可以看
   作子程序，其行为由若干“选项”（局部变量）控制。选项在
   "initialize_options()" 中声明，并在 "finalize_options()" 中定义（即
   赋予最终值），这两个方法都要由每个命令类实现。区分这两个阶段是必要
   的，因为选项值可能来自外部环境（命令行、配置文件等），任何依赖于其
   他选项的选项只能在这些外部影响因素处理完毕后才能计算得出——因此需要
   "finalize_options()" 方法。子程序的主体部分（即根据选项值执行所有实
   际工作的部分）是 "run()" 方法，每个命令类也应当实现该方法。

   该类的构造器接受单个参数 *dist*，它是一个 "Distribution" 实例。


9.24. 创建新的 Distutils 命令
=============================

本节概述了创建新 Distutils 命令的步骤。

新命令位于 "distutils.command" 包中的一个模块内。该目录中有一个名为
"command_template" 的示例模板。将该文件复制到一个与你要实现的新命令同
名的新模块中。此模块应当实现一个与该模块（以及该命令）同名的类。因此，
举例来说，要创建命令 "peel_banana" （以便用户可以运行 "setup.py
peel_banana" ），你可以将 "command_template" 复制到
"distutils/command/peel_banana.py"，然后对其进行编辑，使其实现
"distutils.cmd.Command" 的子类 "peel_banana"。

"Command" 的子类必须定义以下方法。

Command.initialize_options()

   为此命令支持的所有选项设置默认值。请注意，这些默认值可能会被其他命
   令、安装脚本、配置文件或命令行覆盖。因此，这里不是编写选项之间依赖
   关系的地方；通常，"initialize_options()" 的实现只是一连串 "self.foo
   = None" 赋值语句。

Command.finalize_options()

   为此命令支持的所有选项设置最终值。此方法总是尽可能晚地被调用，即在
   完成来自命令行或其他命令的任何选项赋值之后调用。因此，这里是编写选
   项依赖关系的地方：如果 *foo* 依赖于 *bar*，那么只要 *foo* 仍然保持
   在 "initialize_options()" 中被赋予的值，就可以安全地根据 *bar* 来设
   置 *foo*。

Command.run()

   命令存在的意义：执行它旨在完成的操作，受在 "initialize_options()"
   中初始化、由其他命令、安装脚本、命令行和配置文件定制、并在
   "finalize_options()" 中最终确定的选项控制。所有终端输出和文件系统交
   互都应由 "run()" 完成。

Command.sub_commands

   *sub_commands* 将命令“族”的概念形式化，例如以 "install" 作为父命令
   ，包含子命令 "install_lib"、"install_headers" 等。命令族的父命令将
   *sub_commands* 定义为类属性；它是一个二元组 "(command_name,
   predicate)" 的列表，其中 *command_name* 是字符串，*predicate* 是函
   数、字符串或 "None"。*predicate* 是父命令的一个方法，用于确定相应的
   命令在当前情况下是否适用。（例如，"install_headers" 仅在我们有任何
   要安装的 C 头文件时才适用。）如果 *predicate* 为 "None"，则该命令始
   终适用。

   *sub_commands* 通常定义在类的 *末尾*，因为谓词可以是该类的方法，所
   以它们必须已经定义过。典型的例子是 **install** 命令。


9.25. "distutils.command" --- 各个 Distutils 命令
=================================================


9.26. "distutils.command.bdist" --- 构建二进制安装程序
======================================================


9.27. "distutils.command.bdist_packager" --- 打包器的抽象基类
=============================================================


9.28. "distutils.command.bdist_dumb" --- 构建“简易”安装程序
===========================================================


9.29. "distutils.command.bdist_rpm" --- 将二进制发行版构建为 Redhat RPM 和 SRPM
===============================================================================


9.30. "distutils.command.sdist" --- 构建源码发行版
==================================================


9.31. "distutils.command.build" --- 构建包的所有文件
====================================================


9.32. "distutils.command.build_clib" --- 构建包中的任何 C 库
============================================================


9.33. "distutils.command.build_ext" --- 构建包中的任何扩展
==========================================================


9.34. "distutils.command.build_py" --- 构建包的 .py/.pyc 文件
=============================================================

class distutils.command.build_py.build_py

class distutils.command.build_py.build_py_2to3

   build_py 的替代实现，它还会在每个将要安装的 .py 文件上运行 2to3 转
   换库。若要在针对同时在 Python 2.x 和 3.x 下运行的发行版的 setup.py
   文件中使用此功能，请添加:

      try:
          from distutils.command.build_py import build_py_2to3 as build_py
      except ImportError:
          from distutils.command.build_py import build_py

   到你的 setup.py 中，并在稍后添加:

      cmdclass = {'build_py': build_py}

   到 setup() 的调用中。


9.35. "distutils.command.build_scripts" --- 构建包的脚本
========================================================


9.36. "distutils.command.clean" --- 清理包构建区域
==================================================

此命令会移除由 **build** 及其子命令创建的临时文件，例如中间编译目标文
件。使用 "--all" 选项时，整个构建目录都将被移除。

就地 构建的扩展模块不会被清理，因为它们不在构建目录中。


9.37. "distutils.command.config" --- 执行包配置
===============================================


9.38. "distutils.command.install" --- 安装包
============================================


9.39. "distutils.command.install_data" --- 安装包中的数据文件
=============================================================


9.40. "distutils.command.install_headers" --- 安装包中的 C/C++ 头文件
=====================================================================


9.41. "distutils.command.install_lib" --- 安装包中的库文件
==========================================================


9.42. "distutils.command.install_scripts" --- 安装包中的脚本文件
================================================================


9.43. "distutils.command.register" --- 在 Python 包索引中注册模块
=================================================================

"register" 命令将包注册到 Python 包索引（PyPI）。这在 **PEP 301** 中有
更详细的描述。


9.44. "distutils.command.check" --- 检查包的元数据
==================================================

"check" 命令对包的元数据执行一些测试。例如，它会验证是否已将所有必需的
元数据作为参数传递给 "setup()" 函数。
