742 lines
70 KiB
HTML
742 lines
70 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||
<head>
|
||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||
|
||
<title>2. 编写安装脚本 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<script src="../_static/language_data.js"></script>
|
||
<script src="../_static/translations.js"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="在 Python 3.8.20 文档 中搜索"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||
<link rel="index" title="索引" href="../genindex.html" />
|
||
<link rel="search" title="搜索" href="../search.html" />
|
||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||
<link rel="next" title="3. 编写设置脚本的配置文件" href="configfile.html" />
|
||
<link rel="prev" title="1. Distutils 模块介绍" href="introduction.html" />
|
||
<link rel="canonical" href="https://docs.python.org/3/distutils/setupscript.html" />
|
||
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/menu.js"></script>
|
||
|
||
</head>
|
||
<body>
|
||
<div class="mobile-nav">
|
||
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
|
||
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<nav class="nav-content" role="navigation">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Logo"/>
|
||
</a>
|
||
<div class="version_switcher_placeholder"></div>
|
||
<form role="search" class="search" action="../search.html" method="get">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
|
||
<path fill-rule="nonzero"
|
||
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
|
||
</svg>
|
||
<input type="text" name="q" aria-label="快速搜索"/>
|
||
<input type="submit" value="转向"/>
|
||
</form>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">2. 编写安装脚本</a><ul>
|
||
<li><a class="reference internal" href="#listing-whole-packages">2.1. 列出全部的包</a></li>
|
||
<li><a class="reference internal" href="#listing-individual-modules">2.2. 列出单独的模块</a></li>
|
||
<li><a class="reference internal" href="#describing-extension-modules">2.3. 描述扩展模块</a><ul>
|
||
<li><a class="reference internal" href="#extension-names-and-packages">2.3.1. 扩展名和软件包</a></li>
|
||
<li><a class="reference internal" href="#extension-source-files">2.3.2. 扩展的源文件</a></li>
|
||
<li><a class="reference internal" href="#preprocessor-options">2.3.3. 预处理器选项</a></li>
|
||
<li><a class="reference internal" href="#library-options">2.3.4. 库选项</a></li>
|
||
<li><a class="reference internal" href="#other-options">2.3.5. 其它选项</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#relationships-between-distributions-and-packages">2.4. 分发和软件包之间的关系</a></li>
|
||
<li><a class="reference internal" href="#installing-scripts">2.5. 安装脚本</a></li>
|
||
<li><a class="reference internal" href="#installing-package-data">2.6. 安装软件包数据</a></li>
|
||
<li><a class="reference internal" href="#installing-additional-files">2.7. 安装其它文件</a></li>
|
||
<li><a class="reference internal" href="#additional-meta-data">2.8. 附加元数据</a></li>
|
||
<li><a class="reference internal" href="#debugging-the-setup-script">2.9. 调试安装脚本</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="introduction.html"
|
||
title="上一章"><span class="section-number">1. </span>Distutils 模块介绍</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="configfile.html"
|
||
title="下一章"><span class="section-number">3. </span>编写设置脚本的配置文件</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/distutils/setupscript.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||
你应当升级版本,并阅读
|
||
<a href="/3/distutils/setupscript.html"> Python 当前稳定版本的文档</a>.
|
||
</div>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
accesskey="I">索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="configfile.html" title="3. 编写设置脚本的配置文件"
|
||
accesskey="N">下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="introduction.html" title="1. Distutils 模块介绍"
|
||
accesskey="P">上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">分发 Python 模块(遗留版本)</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="writing-the-setup-script">
|
||
<span id="setup-script"></span><h1><span class="section-number">2. </span>编写安装脚本<a class="headerlink" href="#writing-the-setup-script" title="永久链接至标题">¶</a></h1>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>这篇文档是历史遗留文档,在 <a class="reference external" href="https://setuptools.readthedocs.io/en/latest/setuptools.html">https://setuptools.readthedocs.io/en/latest/setuptools.html</a> 上的 <code class="docutils literal notranslate"><span class="pre">setuptools</span></code> 文档独立涵盖此处包含的所有相关信息之后,将不再单独作为正式文档保留。</p>
|
||
</div>
|
||
<p>安装脚本是使用 Distutils 进行构建、分发和安装模块的的入口。设置脚本的主要目的是向 Distutils 描述如何分发您的模块,以便对您的模块进行操作的各种命令正确运行。正如我们在上面的 <a class="reference internal" href="introduction.html#distutils-simple-example"><span class="std std-ref">一个简单的例子</span></a> 部分中看到的,安装脚本主要包含对 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 的调用,并且模块开发人员提供给 Distutils 的大部分信息都通过关键字参数提供给 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code>。</p>
|
||
<p>这是一个略微复杂一点的例子,我们将在接下来的几节中继续追踪它:Distutils 本身的安装脚本。 (请记住,虽然 Distutils 被包括在 Python 1.6 及之后的版本中,但它们也仍保存独立存在因此 Python 1.5.2 用户可以使用它们来安装其他模块分发版。 这里所演示的 Distutils 本身的安装脚本,是用来将该软件包安装到 Python 1.5.2 中。)</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">distutils.core</span> <span class="kn">import</span> <span class="n">setup</span>
|
||
|
||
<span class="n">setup</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">'Distutils'</span><span class="p">,</span>
|
||
<span class="n">version</span><span class="o">=</span><span class="s1">'1.0'</span><span class="p">,</span>
|
||
<span class="n">description</span><span class="o">=</span><span class="s1">'Python Distribution Utilities'</span><span class="p">,</span>
|
||
<span class="n">author</span><span class="o">=</span><span class="s1">'Greg Ward'</span><span class="p">,</span>
|
||
<span class="n">author_email</span><span class="o">=</span><span class="s1">'gward@python.net'</span><span class="p">,</span>
|
||
<span class="n">url</span><span class="o">=</span><span class="s1">'https://www.python.org/sigs/distutils-sig/'</span><span class="p">,</span>
|
||
<span class="n">packages</span><span class="o">=</span><span class="p">[</span><span class="s1">'distutils'</span><span class="p">,</span> <span class="s1">'distutils.command'</span><span class="p">],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>这里与 <a class="reference internal" href="introduction.html#distutils-simple-example"><span class="std std-ref">一个简单的例子</span></a> 一节中介绍的最简版单文件分发包只有两处差异:更多的元数据,以及按包列出纯 Python 模块,而非按模块列出。 这一点很重要因为 Distutils 是由(目前)分成两个包的几十个模块组成的;显式地列出每个模块将十分繁琐并且难以维护。 有关额外元数据的更多信息,请参阅 <a class="reference internal" href="#meta-data"><span class="std std-ref">附加元数据</span></a> 一节。</p>
|
||
<p>请注意在 setup 脚本中提供的任何路径名称(文件或目录)都应当使用 Unix 约定来书写,即以斜杠分隔。 Distutils 会负责在实际使用该路径名称之前将这个与平台无关的表示形式转换为适用于你的当前平台的形式 。 这使得你的 setup 脚本可以在跨操作系统进行移植,这当然是 Distutils 的主要目标之一。 基于此精神,在本文档中的所有路径名称都是以斜杠分隔的。</p>
|
||
<p>当然,这仅适用于提供给 Distutils 函数的路径名称。 举例来说,如果你使用标准 Python 函数例如 <a class="reference internal" href="../library/glob.html#glob.glob" title="glob.glob"><code class="xref py py-func docutils literal notranslate"><span class="pre">glob.glob()</span></code></a> 或 <a class="reference internal" href="../library/os.html#os.listdir" title="os.listdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.listdir()</span></code></a> 来指定文件,则你应当小心地编写可移植的代码而不是硬编码路径分隔符:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'mydir'</span><span class="p">,</span> <span class="s1">'subdir'</span><span class="p">,</span> <span class="s1">'*.html'</span><span class="p">))</span>
|
||
<span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'mydir'</span><span class="p">,</span> <span class="s1">'subdir'</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<section id="listing-whole-packages">
|
||
<span id="listing-packages"></span><h2><span class="section-number">2.1. </span>列出全部的包<a class="headerlink" href="#listing-whole-packages" title="永久链接至标题">¶</a></h2>
|
||
<p><code class="docutils literal notranslate"><span class="pre">packages</span></code> 选项通知 Distutils 处理(构建、分发、安装等)在 <code class="docutils literal notranslate"><span class="pre">packages</span></code> 列表中提及的每个包中找到的所有纯 Python 模块。 当然,为做到这一点,包名称和文件系统的目录之间必须保持对应关系。 默认的对应关系是很显然的,即 <a class="reference internal" href="../library/distutils.html#module-distutils" title="distutils: Support for building and installing Python modules into an existing Python installation."><code class="xref py py-mod docutils literal notranslate"><span class="pre">distutils</span></code></a> 包即相对于分发包根目录的 <code class="file docutils literal notranslate"><span class="pre">distutils</span></code> 目录。 因此,当你在你的 setup 脚本中写 <code class="docutils literal notranslate"><span class="pre">packages</span> <span class="pre">=</span> <span class="pre">['foo']</span></code> 时,你就承诺了 Distutils 将在相对于你的 setup 脚本所在目录下找到一个文件 <code class="file docutils literal notranslate"><span class="pre">foo/__init__.py</span></code> (在你的目录上可能会有不同的拼写形式,但意思已经很明白了)。 如果你违反此承诺,Distutils 将发出警告但无论如何仍会处理损坏的包。</p>
|
||
<p>如果你使用不同的约定来布局你的源目录,那也没有问题:你只需提供 <code class="docutils literal notranslate"><span class="pre">package_dir</span></code> 选项来告知 Distutils 你的约定。 例如,假设你将所有For example, say you keep all Python 源代码保存在 <code class="file docutils literal notranslate"><span class="pre">lib</span></code> 下,以便“根包”中的模块(即不属于任何包的模块)位于 <code class="file docutils literal notranslate"><span class="pre">lib</span></code> 中,<code class="xref py py-mod docutils literal notranslate"><span class="pre">foo</span></code> 包中的模块位于 <code class="file docutils literal notranslate"><span class="pre">lib/foo</span></code> 中,依此类推。 那么你应当编写:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">package_dir</span> <span class="o">=</span> <span class="p">{</span><span class="s1">''</span><span class="p">:</span> <span class="s1">'lib'</span><span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>在你的 setup 脚本中。 这个字典的键是包名,空的包名代表根包。 字典的值是相对于你的发布包根目录的目录名。 在本例中,当你声明 <code class="docutils literal notranslate"><span class="pre">packages</span> <span class="pre">=</span> <span class="pre">['foo']</span></code> 时,你将承诺存在 <code class="file docutils literal notranslate"><span class="pre">lib/foo/__init__.py</span></code> 这个文件。</p>
|
||
<p>另一种可能的约定是将 <code class="xref py py-mod docutils literal notranslate"><span class="pre">foo</span></code> 包直接放在 <code class="file docutils literal notranslate"><span class="pre">lib</span></code> 中,将 <code class="xref py py-mod docutils literal notranslate"><span class="pre">foo.bar</span></code> 包放在 <code class="file docutils literal notranslate"><span class="pre">lib/bar</span></code> 中等等。 这可以在 setup 脚本中写为</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">package_dir</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'foo'</span><span class="p">:</span> <span class="s1">'lib'</span><span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">package_dir</span></code> 字典中的 <code class="docutils literal notranslate"><span class="pre">package:</span> <span class="pre">dir</span></code> 条目隐式地应用于 <em>package</em> 以下的所有包,因而在这里 <code class="xref py py-mod docutils literal notranslate"><span class="pre">foo.bar</span></code> 的情况会被自动地处理。 在这个示例中,使用 <code class="docutils literal notranslate"><span class="pre">packages</span> <span class="pre">=</span> <span class="pre">['foo',</span> <span class="pre">'foo.bar']</span></code> 告知 Distutils 要查找 <code class="file docutils literal notranslate"><span class="pre">lib/__init__.py</span></code> 和 <code class="file docutils literal notranslate"><span class="pre">lib/bar/__init__.py</span></code>。 (请记住虽然 <code class="docutils literal notranslate"><span class="pre">package_dir</span></code> 会递归地应用,但你必须在 <code class="docutils literal notranslate"><span class="pre">packages</span></code> 中显式地列出所有的包:Distutils <em>不会</em> 递归地扫描你的源代码树来查找任何带有 <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件的目录。)</p>
|
||
</section>
|
||
<section id="listing-individual-modules">
|
||
<span id="listing-modules"></span><h2><span class="section-number">2.2. </span>列出单独的模块<a class="headerlink" href="#listing-individual-modules" title="永久链接至标题">¶</a></h2>
|
||
<p>对于一个小型的模块分发包,你可能会倾向于列出所有的模块而不是只列出包 --- 特别是在“根包”中只有一个模块(即根本不存在包)的情况下。 这种最简单的情况见 <a class="reference internal" href="introduction.html#distutils-simple-example"><span class="std std-ref">一个简单的例子</span></a> 一节;下面是一个稍微复杂一点的例子:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">py_modules</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'mod1'</span><span class="p">,</span> <span class="s1">'pkg.mod2'</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>这描述了两个模块,其中一个是在 "root" 包中,另一个是在 <code class="xref py py-mod docutils literal notranslate"><span class="pre">pkg</span></code> 包中。 同样地,默认的包/目录布局表明这两个模块位于 <code class="file docutils literal notranslate"><span class="pre">mod1.py</span></code> 和 <code class="file docutils literal notranslate"><span class="pre">pkg/mod2.py</span></code> 中,并且也存在 <code class="file docutils literal notranslate"><span class="pre">pkg/__init__.py</span></code>。 同样地,你可以使用 <code class="docutils literal notranslate"><span class="pre">package_dir</span></code> 选项来重载包/目录的对应关系。</p>
|
||
</section>
|
||
<section id="describing-extension-modules">
|
||
<span id="describing-extensions"></span><h2><span class="section-number">2.3. </span>描述扩展模块<a class="headerlink" href="#describing-extension-modules" title="永久链接至标题">¶</a></h2>
|
||
<p>正如编写Python扩展模块比编写纯Python模块要复杂一些一样,在Distutils中描述它们也要复杂一些。与纯模块不同,仅仅列出模块或包并期望Distutils出去找到正确的文件是不够的;您必须指定扩展名、源文件和任何编译/链接要求(包括要链接的目录、库等)。</p>
|
||
<p>所有这些都是通过 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 的另一个关键字参数 <code class="docutils literal notranslate"><span class="pre">ext_modules</span></code> 选项实现的。 <code class="docutils literal notranslate"><span class="pre">ext_modules</span></code> 是 由 <a class="reference internal" href="apiref.html#distutils.core.Extension" title="distutils.core.Extension"><code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code></a> 实例组成的列表,每个实例描述一个扩展模块。 假设你的发行版包括一个扩展模块,名为 <code class="xref py py-mod docutils literal notranslate"><span class="pre">foo</span></code> 并由 <code class="file docutils literal notranslate"><span class="pre">foo.c</span></code> 实现。 如果不需要编译器/链接器的额外指令,描述这个扩展很简单:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.c'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code> 类可以与 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 一起从 <a class="reference internal" href="apiref.html#module-distutils.core" title="distutils.core: The core Distutils functionality"><code class="xref py py-mod docutils literal notranslate"><span class="pre">distutils.core</span></code></a> 导入。 因此,只包含这一个扩展而不包含其他扩展的模块分发版的安装脚本可能是:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">distutils.core</span> <span class="kn">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">Extension</span>
|
||
<span class="n">setup</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">'foo'</span><span class="p">,</span>
|
||
<span class="n">version</span><span class="o">=</span><span class="s1">'1.0'</span><span class="p">,</span>
|
||
<span class="n">ext_modules</span><span class="o">=</span><span class="p">[</span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.c'</span><span class="p">])],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code> 类(实际上,由 <strong class="command">build_ext</strong> 命令实现的底层扩展构建机制)在描述 Python 扩展时支持很大的灵活性,这将在以下部分中进行解释。</p>
|
||
<section id="extension-names-and-packages">
|
||
<h3><span class="section-number">2.3.1. </span>扩展名和软件包<a class="headerlink" href="#extension-names-and-packages" title="永久链接至标题">¶</a></h3>
|
||
<p><a class="reference internal" href="apiref.html#distutils.core.Extension" title="distutils.core.Extension"><code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code></a> 构造器的第一个参数始终是扩展的名称,包括任何包名称。 例如,:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'src/foo1.c'</span><span class="p">,</span> <span class="s1">'src/foo2.c'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>描述了根包中的一个扩展,而::</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="s1">'pkg.foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'src/foo1.c'</span><span class="p">,</span> <span class="s1">'src/foo2.c'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>描述了 <code class="xref py py-mod docutils literal notranslate"><span class="pre">pkg</span></code> 包中的相同扩展。 在这两种情况下,源文件和生成的目标代码是相同的;唯一的区别是所产生的扩展处在文件系统中的何处(相应地在 Python 的命名空间层级结构中处在何处)。</p>
|
||
<p>如果在同一个包中(或在同一基本包下)有多个扩展,请使用 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 的关键字参数 <code class="docutils literal notranslate"><span class="pre">ext_package</span></code>。 例如,:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">ext_package</span><span class="o">=</span><span class="s1">'pkg'</span><span class="p">,</span>
|
||
<span class="n">ext_modules</span><span class="o">=</span><span class="p">[</span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.c'</span><span class="p">]),</span>
|
||
<span class="n">Extension</span><span class="p">(</span><span class="s1">'subpkg.bar'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'bar.c'</span><span class="p">])],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>将把 <code class="file docutils literal notranslate"><span class="pre">foo.c</span></code> 编译为扩展 <code class="xref py py-mod docutils literal notranslate"><span class="pre">pkg.foo</span></code>,把 <code class="file docutils literal notranslate"><span class="pre">bar.c</span></code> 编译为 <code class="xref py py-mod docutils literal notranslate"><span class="pre">pkg.subpkg.bar</span></code>。</p>
|
||
</section>
|
||
<section id="extension-source-files">
|
||
<h3><span class="section-number">2.3.2. </span>扩展的源文件<a class="headerlink" href="#extension-source-files" title="永久链接至标题">¶</a></h3>
|
||
<p><a class="reference internal" href="apiref.html#distutils.core.Extension" title="distutils.core.Extension"><code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code></a> 构造器的第二个参数是源文件列表。 由于 Distutils 目前只支持 C、C++ 和 Objective-C 扩展,因此这些扩展通常是 C/C++/Objective-C 源文件。 (请确保使用适当的扩展名来区分 C++ 源文件: <code class="file docutils literal notranslate"><span class="pre">.cc</span></code> 和 <code class="file docutils literal notranslate"><span class="pre">.cpp</span></code> 看来能够同时被 Unix 和 Windows 编译器所识别。)</p>
|
||
<p>但是,您也可以在列表中包括 SWIG 接口 (<code class="file docutils literal notranslate"><span class="pre">.i</span></code>) 文件;<strong class="command">build_ext</strong> 命令知道如何处理 SWIG 扩展:它将在接口文件上运行 SWIG,并将生成的 C/C++ 文件编译为你的扩展。</p>
|
||
<p>尽管有此警告,SWIG的选项目前可以这样传递</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">ext_modules</span><span class="o">=</span><span class="p">[</span><span class="n">Extension</span><span class="p">(</span><span class="s1">'_foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.i'</span><span class="p">],</span>
|
||
<span class="n">swig_opts</span><span class="o">=</span><span class="p">[</span><span class="s1">'-modern'</span><span class="p">,</span> <span class="s1">'-I../include'</span><span class="p">])],</span>
|
||
<span class="n">py_modules</span><span class="o">=</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>或者在命令行上,像这样</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="n">python</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">build_ext</span> <span class="o">--</span><span class="n">swig</span><span class="o">-</span><span class="n">opts</span><span class="o">=</span><span class="s2">"-modern -I../include"</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>在某些平台上,可以包含由编译器处理并包含在扩展中的非源文件。目前,这只是指Visual C++的Windows消息文本(<code class="file docutils literal notranslate"><span class="pre">.mc</span></code>)文件和资源定义(<code class="file docutils literal notranslate"><span class="pre">.rc</span></code>)。这些文件将被编译为二进制资源(<code class="file docutils literal notranslate"><span class="pre">.res</span></code>)文件,并链接到可执行文件中。</p>
|
||
</section>
|
||
<section id="preprocessor-options">
|
||
<h3><span class="section-number">2.3.3. </span>预处理器选项<a class="headerlink" href="#preprocessor-options" title="永久链接至标题">¶</a></h3>
|
||
<p>如果你需要指定要搜索的include目录或预处理器宏来define/undefine,那么:<code class="xref py py-class docutils literal notranslate"><span class="pre">Extension`的三个可选参数将有所帮助:``include_dirs`</span></code>、<code class="docutils literal notranslate"><span class="pre">define_macros``和``undef_macros</span></code>。</p>
|
||
<p>例如,如果你的扩展需要分发根目录下的 <code class="file docutils literal notranslate"><span class="pre">include</span></code> 目录中的头文件,请使用 <code class="docutils literal notranslate"><span class="pre">include_dirs</span></code> 选项:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.c'</span><span class="p">],</span> <span class="n">include_dirs</span><span class="o">=</span><span class="p">[</span><span class="s1">'include'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>你可以在那里指定绝对目录;如果你知道你的扩展只能在安装到 <code class="file docutils literal notranslate"><span class="pre">/usr</span></code> 的 X11R6 的 Unix 系统上构建,那么你就可以:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'foo.c'</span><span class="p">],</span> <span class="n">include_dirs</span><span class="o">=</span><span class="p">[</span><span class="s1">'/usr/include/X11'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果你计划分发代码,应该避免这种不可移植的用法:最好像这样编写C代码</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1">#include <X11/Xlib.h></span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果你需要包含来自其它 Python 扩展的头文件,你可以利用这样一个事实,即 Distutils <strong class="command">install_headers</strong> 命令以一致的方式安装头文件。 例如,Numerical Python 头文件 (在标准 Unix 安装版上) 会安装到 <code class="file docutils literal notranslate"><span class="pre">/usr/local/include/python1.5/Numerical</span></code> (具体位置将根据你的平台和 Python 安装版而有所不同)。 由于在构建Python 扩展时,Python include 目录 --- 在本例中为 <code class="file docutils literal notranslate"><span class="pre">/usr/local/include/python1.5</span></code> --- 总是会包含在搜索路径中,因此最好的做法是像这样编写 C 代码:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1">#include <Numerical/arrayobject.h></span>
|
||
</pre></div>
|
||
</div>
|
||
<p>但是,如果必须将 <code class="file docutils literal notranslate"><span class="pre">Numerical</span></code> include 目录放在头文件搜索路径中,则可以使用 Distutils <a class="reference internal" href="apiref.html#module-distutils.sysconfig" title="distutils.sysconfig: Low-level access to configuration information of the Python interpreter."><code class="xref py py-mod docutils literal notranslate"><span class="pre">distutils.sysconfig</span></code></a> 模块找到该目录:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">distutils.sysconfig</span> <span class="kn">import</span> <span class="n">get_python_inc</span>
|
||
<span class="n">incdir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">get_python_inc</span><span class="p">(</span><span class="n">plat_specific</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span> <span class="s1">'Numerical'</span><span class="p">)</span>
|
||
<span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">Extension</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">include_dirs</span><span class="o">=</span><span class="p">[</span><span class="n">incdir</span><span class="p">]),</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>尽管这是非常可移植的——无论平台如何,它都可以在任何Python安装中工作——但以合理的方式编写C代码可能更容易。</p>
|
||
<p>您可以使用``define_macros``和``undef_macros``选项 define 和 undefine 预处理器宏。<code class="docutils literal notranslate"><span class="pre">define_macros``采用一个``(name,</span> <span class="pre">value)``元组列表,其中``name``是要定义的宏的名称(字符串),``value``是其值:字符串或“``None</span></code>。(将宏``FOO``定义为``None``相当于C源代码中的空``#define FOO``:对于大多数编译器,这会将``FOO``设置为字符串``1``。)``undef_macros``只是一个undefine的宏列表。</p>
|
||
<p>例如:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">define_macros</span><span class="o">=</span><span class="p">[(</span><span class="s1">'NDEBUG'</span><span class="p">,</span> <span class="s1">'1'</span><span class="p">),</span>
|
||
<span class="p">(</span><span class="s1">'HAVE_STRFTIME'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)],</span>
|
||
<span class="n">undef_macros</span><span class="o">=</span><span class="p">[</span><span class="s1">'HAVE_FOO'</span><span class="p">,</span> <span class="s1">'HAVE_BAR'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>相当于将其放在每个C源文件的顶部</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1">#define NDEBUG 1</span>
|
||
<span class="c1">#define HAVE_STRFTIME</span>
|
||
<span class="c1">#undef HAVE_FOO</span>
|
||
<span class="c1">#undef HAVE_BAR</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="library-options">
|
||
<h3><span class="section-number">2.3.4. </span>库选项<a class="headerlink" href="#library-options" title="永久链接至标题">¶</a></h3>
|
||
<p>你还可以指定在构建扩展时要链接的库,以及搜索这些库的目录。 <code class="docutils literal notranslate"><span class="pre">libraries</span></code> 选项是要链接的库列表,<code class="docutils literal notranslate"><span class="pre">library_dirs</span></code> 是要在链接时搜索库的目录列表,<code class="docutils literal notranslate"><span class="pre">runtime_library_dirs</span></code> 是要在运行时搜索共享(动态加载)库的目录的列表。</p>
|
||
<p>例如,如果你需要链接到目标系统上标准库搜索路径中已知的库</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">libraries</span><span class="o">=</span><span class="p">[</span><span class="s1">'gdbm'</span><span class="p">,</span> <span class="s1">'readline'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果你需要链接到非标准位置的库,则必须将该位置包含在 <code class="docutils literal notranslate"><span class="pre">library_dirs</span></code> 中:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">Extension</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">library_dirs</span><span class="o">=</span><span class="p">[</span><span class="s1">'/usr/X11R6/lib'</span><span class="p">],</span>
|
||
<span class="n">libraries</span><span class="o">=</span><span class="p">[</span><span class="s1">'X11'</span><span class="p">,</span> <span class="s1">'Xt'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(同样,如果你打算分发代码,应该避免这种不可移植的构造。)</p>
|
||
</section>
|
||
<section id="other-options">
|
||
<h3><span class="section-number">2.3.5. </span>其它选项<a class="headerlink" href="#other-options" title="永久链接至标题">¶</a></h3>
|
||
<p>还有一些其它选项可以用于处理特殊情况。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">optional</span></code> 选项是一个布尔值;如果它为真值,则扩展中的生成失败不会中止生成过程,而是简单地不安装失败的扩展。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">extra_objects</span></code> 选项是要传递给链接器的对象文件列表。 这些文件不能有扩展名,因为使用的是编译器的默认扩展名。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">extra_compile_args</span></code> 和 <code class="docutils literal notranslate"><span class="pre">extra_link_args</span></code> 可用于为相应的编译器和链接器命令行指定额外的命令行选项。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">export_symbols</span></code> 仅在 Windows 上适用。 它可以包含要导出的符号(函数或变量)列表。 生成编译的扩展时不需要此选项:Distutils 会自动将 <code class="docutils literal notranslate"><span class="pre">initmodule</span></code> 添加到导出的符号列表中。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">depends</span></code> 选项是扩展所依赖的文件列表(例如头文件)。 build 命令将调用源上的编译器以重新生成扩展(如果自上一次生成以来此文件上的任何扩展已被修改)。</p>
|
||
</section>
|
||
</section>
|
||
<section id="relationships-between-distributions-and-packages">
|
||
<h2><span class="section-number">2.4. </span>分发和软件包之间的关系<a class="headerlink" href="#relationships-between-distributions-and-packages" title="永久链接至标题">¶</a></h2>
|
||
<p>一个分发可能以三种特定方式与软件包相关:</p>
|
||
<ol class="arabic simple">
|
||
<li><p>它可能需要软件包或模块。</p></li>
|
||
<li><p>它可能提供软件包或模块。</p></li>
|
||
<li><p>它可能废弃软件包或模块。</p></li>
|
||
</ol>
|
||
<p>可以使用 <a class="reference internal" href="apiref.html#distutils.core.setup" title="distutils.core.setup"><code class="xref py py-func docutils literal notranslate"><span class="pre">distutils.core.setup()</span></code></a> 函数的关键字参数来指定这些关系。</p>
|
||
<p>可以通过将 <em>requires</em> 关键字参数提供给 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 来指定对其他 Python 模块和包的依赖关系。 其值必须是字符串列表。 每个字符串都指定了所需的软件包,并可以选择哪些版本满足要求。</p>
|
||
<p>要指定需要模块或软件包的任何版本,字符串应该完全由模块或软件包的名称组成。 示例包括 <code class="docutils literal notranslate"><span class="pre">'mymodule'</span></code> 和 <code class="docutils literal notranslate"><span class="pre">'xml.parsers.expat'</span></code>。</p>
|
||
<p>如果需要特定的版本,可以在括号中提供一系列限定符。每个限定符可以由一个比较运算符和一个版本号组成。可接受的比较运算符为:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o"><</span> <span class="o">></span> <span class="o">==</span>
|
||
<span class="o"><=</span> <span class="o">>=</span> <span class="o">!=</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>这些可以通过使用逗号分隔的多个限定符(以及可选的空格)进行组合。在这种情况下,所有限定符都必须匹配;使用逻辑AND来组合评估。</p>
|
||
<p>让我们看一堆例子:</p>
|
||
<table class="docutils align-default">
|
||
<colgroup>
|
||
<col style="width: 35%" />
|
||
<col style="width: 65%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Requires 表达式</p></th>
|
||
<th class="head"><p>说明</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">==1.0</span></code></p></td>
|
||
<td><p>只有``1.0``版本兼容</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">>1.0,</span> <span class="pre">!=1.5.1,</span> <span class="pre"><2.0</span></code></p></td>
|
||
<td><p><code class="docutils literal notranslate"><span class="pre">1.0</span></code> 之后和 <code class="docutils literal notranslate"><span class="pre">2.0</span></code> 之前的任何版本都是兼容的,<code class="docutils literal notranslate"><span class="pre">1.5.1</span></code> 除外</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>既然我们可以指定依赖项,我们还需要能够指定我们提供的其它发行版可能需要的内容。这是通过将 <em>provides</em> 关键字参数用于 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 来完成的。 该关键字的值是一个字符串列表,每个字符串都命名一个Python模块或软件包,并可选择标识版本。 如果未指定版本,则假定与该发行版的版本相匹配。</p>
|
||
<p>一些例子:</p>
|
||
<table class="docutils align-default">
|
||
<colgroup>
|
||
<col style="width: 31%" />
|
||
<col style="width: 69%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Provides 表达式</p></th>
|
||
<th class="head"><p>说明</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">mypkg</span></code></p></td>
|
||
<td><p>Provide <code class="docutils literal notranslate"><span class="pre">mypkg</span></code>, 使用该分发版的版本</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">mypkg</span> <span class="pre">(1.1)</span></code></p></td>
|
||
<td><p>提供版本为 1.1的``mypkg``,不管分发版的版本</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>一个软件包可以使用 <em>obsoletes</em> 关键字参数声明它已经废弃了其它软件包。它的值类似于 <em>requires</em> 关键字的值:一个给出模块或软件包说明符的字符串列表。每个说明符由一个模块或软件包名称组成,后面可选地跟有一个或多个版本限定符。版本限定符在模块或软件包名称后面的括号中给出。</p>
|
||
<p>限定符标识的版本是那些被所描述的分发版本废弃的版本。如果没有给出限定符,那么指定的模块或软件包的所有版本都被认为是废弃的。</p>
|
||
</section>
|
||
<section id="installing-scripts">
|
||
<span id="distutils-installing-scripts"></span><h2><span class="section-number">2.5. </span>安装脚本<a class="headerlink" href="#installing-scripts" title="永久链接至标题">¶</a></h2>
|
||
<p>到目前为止,我们一直在处理纯Python模块和非纯Python模块,它们通常不是自己运行的,而是通过脚本导入的。</p>
|
||
<p>脚本是包含Python源代码的文件,旨在从命令行启动。脚本不需要Distutils来做任何非常复杂的事情。唯一聪明的功能是,如果脚本的第一行以``#!``开头并且包含单词“python”,Distutils将调整第一行以引用当前解释器位置。默认情况下,它被替换为当前解释器位置。选项:option:<cite>!--executable`(或:option:</cite>!-e`)将允许显式覆盖解释器路径。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">scripts</span></code> 选项只是要以这种方式处理的文件列表。 从 PyXML 安装脚本</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">scripts</span><span class="o">=</span><span class="p">[</span><span class="s1">'scripts/xmlproc_parse'</span><span class="p">,</span> <span class="s1">'scripts/xmlproc_val'</span><span class="p">]</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.1 版更改: </span>如果没有提供模板,所有脚本也将被添加到 <code class="docutils literal notranslate"><span class="pre">MANIFEST</span></code> 文件中。请参见 <a class="reference internal" href="sourcedist.html#manifest"><span class="std std-ref">指定要分发的文件</span></a>。</p>
|
||
</div>
|
||
</section>
|
||
<section id="installing-package-data">
|
||
<span id="distutils-installing-package-data"></span><h2><span class="section-number">2.6. </span>安装软件包数据<a class="headerlink" href="#installing-package-data" title="永久链接至标题">¶</a></h2>
|
||
<p>通常,需要将额外的文件安装到软件包中。这些文件通常是与软件包的实现密切相关的数据,或者是包含使用软件包的程序员可能感兴趣的文档的文本文件。这些文件被称为 <em class="dfn">package data</em>。</p>
|
||
<p>可以使用 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 函数的关键字参数 <code class="docutils literal notranslate"><span class="pre">package_data</span></code> 将软件包数据添加到软件包中。 该值必须是从软件包名到应该复制到软件包中的相对路径名列表的映射。 路径被解释为相对于包含软件包的目录(如果合适,将使用来自 <code class="docutils literal notranslate"><span class="pre">package_dir</span></code> 映射的信息);也就是说,这些文件应该是软件包源目录中的一部分。 它们也可能包含 glob 模式。</p>
|
||
<p>路径名称可以包含目录部分;任何必要的目录都将在安装过程中创建。</p>
|
||
<p>例如,如果一个软件包应该包含一个有多个数据文件的子目录,那么这些文件可以在源树中按如下方式排列</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="o">.</span><span class="n">py</span>
|
||
<span class="n">src</span><span class="o">/</span>
|
||
<span class="n">mypkg</span><span class="o">/</span>
|
||
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
|
||
<span class="n">module</span><span class="o">.</span><span class="n">py</span>
|
||
<span class="n">data</span><span class="o">/</span>
|
||
<span class="n">tables</span><span class="o">.</span><span class="n">dat</span>
|
||
<span class="n">spoons</span><span class="o">.</span><span class="n">dat</span>
|
||
<span class="n">forks</span><span class="o">.</span><span class="n">dat</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>对 <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code> 的相应调用可能是</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">packages</span><span class="o">=</span><span class="p">[</span><span class="s1">'mypkg'</span><span class="p">],</span>
|
||
<span class="n">package_dir</span><span class="o">=</span><span class="p">{</span><span class="s1">'mypkg'</span><span class="p">:</span> <span class="s1">'src/mypkg'</span><span class="p">},</span>
|
||
<span class="n">package_data</span><span class="o">=</span><span class="p">{</span><span class="s1">'mypkg'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'data/*.dat'</span><span class="p">]},</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.1 版更改: </span>如果没有提供模板,则所有与 <code class="docutils literal notranslate"><span class="pre">package_data</span></code> 匹配的文件都将添加到 <code class="docutils literal notranslate"><span class="pre">MANIFEST</span></code> 文件中。 请参见 <a class="reference internal" href="sourcedist.html#manifest"><span class="std std-ref">指定要分发的文件</span></a>。</p>
|
||
</div>
|
||
</section>
|
||
<section id="installing-additional-files">
|
||
<span id="distutils-additional-files"></span><h2><span class="section-number">2.7. </span>安装其它文件<a class="headerlink" href="#installing-additional-files" title="永久链接至标题">¶</a></h2>
|
||
<p><code class="docutils literal notranslate"><span class="pre">data_files</span></code> 选项可用于指定模块分发所需的其它文件:配置文件、消息目录、数据文件,以及任何不属于前述类别的文件。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">data_files</span></code> 以如下方式指定 (<em>directory</em>, <em>files</em>) 对的序列:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">data_files</span><span class="o">=</span><span class="p">[(</span><span class="s1">'bitmaps'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'bm/b1.gif'</span><span class="p">,</span> <span class="s1">'bm/b2.gif'</span><span class="p">]),</span>
|
||
<span class="p">(</span><span class="s1">'config'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'cfg/data.cfg'</span><span class="p">])],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>序列中的每队(<em>directory</em>,<em>files</em>)指定安装目录和要在其中安装的文件。</p>
|
||
<p><em>files</em> 中的每个文件名都是相对于软件包源发行版顶部的 <code class="file docutils literal notranslate"><span class="pre">setup.py</span></code> 脚本进行解释的。 请注意,您可以指定安装数据文件的目录,但不能重命名数据文件本身。</p>
|
||
<p><em>directory</em> 应该是一个相对路径。它是相对于安装前缀来解释的(Python 的 <code class="docutils literal notranslate"><span class="pre">sys.prefix</span></code> 用于系统安装;<code class="docutils literal notranslate"><span class="pre">site.USER_BASE</span></code> 用于用户安装)。 Distutils 允许将 <em>directory</em> 作为一个绝对的安装路径,但这是不鼓励的,因为它与 wheel 封装格式不兼容。不使用来自 <em>files</em> 的目录信息来确定已安装文件的最终位置;只使用文件的名称。</p>
|
||
<p>你可以将 <code class="docutils literal notranslate"><span class="pre">data_files</span></code> 选项指定为一个简单的文件序列,而无需指定目标目录,但不建议这样做,在这种情况下,<strong class="command">install</strong> 命令将打印警告。 要将数据文件直接安装到目标目录中,应提供一个空字符串作为目录。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.1 版更改: </span>如果没有提供模板,则所有与 <code class="docutils literal notranslate"><span class="pre">data_files</span></code> 匹配的文件都将添加到 <code class="docutils literal notranslate"><span class="pre">MANIFEST</span></code> 文件中。 请参见 <a class="reference internal" href="sourcedist.html#manifest"><span class="std std-ref">指定要分发的文件</span></a>。</p>
|
||
</div>
|
||
</section>
|
||
<section id="additional-meta-data">
|
||
<span id="meta-data"></span><h2><span class="section-number">2.8. </span>附加元数据<a class="headerlink" href="#additional-meta-data" title="永久链接至标题">¶</a></h2>
|
||
<p>安装脚本可以包括除了名称和版本之外的附加元数据。这些信息包括:</p>
|
||
<table class="docutils align-default">
|
||
<colgroup>
|
||
<col style="width: 30%" />
|
||
<col style="width: 36%" />
|
||
<col style="width: 23%" />
|
||
<col style="width: 11%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>元数据</p></th>
|
||
<th class="head"><p>描述</p></th>
|
||
<th class="head"><p>值</p></th>
|
||
<th class="head"><p>备注</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">name</span></code></p></td>
|
||
<td><p>包名称</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td><p>(1)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">version</span></code></p></td>
|
||
<td><p>此发布的版本</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td><p>(1)(2)</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">author</span></code></p></td>
|
||
<td><p>软件包作者的姓名</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td><p>(3)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">author_email</span></code></p></td>
|
||
<td><p>软件包的作者的电子邮件地址</p></td>
|
||
<td><p>电子邮件地址</p></td>
|
||
<td><p>(3)</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">maintainer</span></code></p></td>
|
||
<td><p>软件包维护者的名字</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td><p>(3)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">maintainer_email</span></code></p></td>
|
||
<td><p>软件包维护者的电子邮件地址</p></td>
|
||
<td><p>电子邮件地址</p></td>
|
||
<td><p>(3)</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">url</span></code></p></td>
|
||
<td><p>软件包的网址</p></td>
|
||
<td><p>网址</p></td>
|
||
<td><p>(1)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">description</span></code></p></td>
|
||
<td><p>软件包的简短摘要说明</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">long_description</span></code></p></td>
|
||
<td><p>软件包的详细说明</p></td>
|
||
<td><p>长字符串</p></td>
|
||
<td><p>(4)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">download_url</span></code></p></td>
|
||
<td><p>可以下载软件包的网址</p></td>
|
||
<td><p>网址</p></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">classifiers</span></code></p></td>
|
||
<td><p>分类列表</p></td>
|
||
<td><p>字符串列表</p></td>
|
||
<td><p>(6)(7)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">platforms</span></code></p></td>
|
||
<td><p>平台清单</p></td>
|
||
<td><p>字符串列表</p></td>
|
||
<td><p>(6)(8)</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">keywords</span></code></p></td>
|
||
<td><p>关键字列表</p></td>
|
||
<td><p>字符串列表</p></td>
|
||
<td><p>(6)(8)</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">license</span></code></p></td>
|
||
<td><p>软件包许可证</p></td>
|
||
<td><p>短字符串</p></td>
|
||
<td><p>(5)</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>注释:</p>
|
||
<ol class="arabic simple">
|
||
<li><p>这些字段是必需的。</p></li>
|
||
<li><p>建议版本采用 <em>major.minor[.patch[.sub]]</em> 的形式。</p></li>
|
||
<li><p>必须确定作者或维护者。如果提供了维护者,distutils 会在 <code class="file docutils literal notranslate"><span class="pre">PKG-INFO</span></code> 中将其列为作者。</p></li>
|
||
<li><p>PyPI在发布软件包时使用``long_description``字段来构建其项目页面。</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">license</span></code> 字段是一个文本,指示软件包中的许可证,其中该许可证不是从 “license” Trove分类器中选择的。请参见 <code class="docutils literal notranslate"><span class="pre">Classifier</span></code> 字段。 请注意,有一个 <code class="docutils literal notranslate"><span class="pre">licence</span></code> 分发选项,该选项已被弃用,但仍充当 <code class="docutils literal notranslate"><span class="pre">license</span></code> 字段的别名。</p></li>
|
||
<li><p>此字段必须是一个列表。</p></li>
|
||
<li><p>有效的分类器在 <a class="reference external" href="https://pypi.org/classifiers">PyPI</a> 上列出。</p></li>
|
||
<li><p>为了保持向后兼容性,此字段还接受一个字符串。如果传递逗号分隔的字符串``'foo, bar'<code class="docutils literal notranslate"><span class="pre">,它将被转换为``['foo',</span> <span class="pre">'bar']</span></code>,否则,它将转换为一个字符串列表。</p></li>
|
||
</ol>
|
||
<dl class="simple">
|
||
<dt>'短字符串'</dt><dd><p>一行文字,不超过200个字符。</p>
|
||
</dd>
|
||
<dt>'长字符串'</dt><dd><p>Multiple lines of plain text in reStructuredText format (see
|
||
<a class="reference external" href="http://docutils.sourceforge.net/">http://docutils.sourceforge.net/</a>).</p>
|
||
</dd>
|
||
<dt>'字符串列表'</dt><dd><p>请参见下文。</p>
|
||
</dd>
|
||
</dl>
|
||
<p>对版本信息进行编码本身就是一门艺术。Python包通常遵循版本格式 <em>major.minor[.patch][sub]</em> 。初始的、实验性的软件版本的主数字是0。对于表示包中主要里程碑的版本,主版本会递增。当重要的新特性添加到包中时,次版本编号会增加。当发布错误修复程序时,补丁编号会增加。附加的尾随版本信息有时用于指示子版本。这些是“a1,a2,…,aN”(对于alpha版本,功能和API可能会更改),“b1,b2,…,bN”(针对beta版本,它只修复了错误)和“pr1,pr2,……,prN”(用于最终的预发布测试)。一些例子:</p>
|
||
<dl class="simple">
|
||
<dt>0.1.0</dt><dd><p>一个软件包的第一个实验性发布</p>
|
||
</dd>
|
||
<dt>1.0.1a2</dt><dd><p>1.0的第一个补丁版本的第二个alpha版本</p>
|
||
</dd>
|
||
</dl>
|
||
<p><code class="docutils literal notranslate"><span class="pre">classifiers</span></code> 必须在列表中指定</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span><span class="o">...</span><span class="p">,</span>
|
||
<span class="n">classifiers</span><span class="o">=</span><span class="p">[</span>
|
||
<span class="s1">'Development Status :: 4 - Beta'</span><span class="p">,</span>
|
||
<span class="s1">'Environment :: Console'</span><span class="p">,</span>
|
||
<span class="s1">'Environment :: Web Environment'</span><span class="p">,</span>
|
||
<span class="s1">'Intended Audience :: End Users/Desktop'</span><span class="p">,</span>
|
||
<span class="s1">'Intended Audience :: Developers'</span><span class="p">,</span>
|
||
<span class="s1">'Intended Audience :: System Administrators'</span><span class="p">,</span>
|
||
<span class="s1">'License :: OSI Approved :: Python Software Foundation License'</span><span class="p">,</span>
|
||
<span class="s1">'Operating System :: MacOS :: MacOS X'</span><span class="p">,</span>
|
||
<span class="s1">'Operating System :: Microsoft :: Windows'</span><span class="p">,</span>
|
||
<span class="s1">'Operating System :: POSIX'</span><span class="p">,</span>
|
||
<span class="s1">'Programming Language :: Python'</span><span class="p">,</span>
|
||
<span class="s1">'Topic :: Communications :: Email'</span><span class="p">,</span>
|
||
<span class="s1">'Topic :: Office/Business'</span><span class="p">,</span>
|
||
<span class="s1">'Topic :: Software Development :: Bug Tracking'</span><span class="p">,</span>
|
||
<span class="p">],</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>现在 <a class="reference internal" href="apiref.html#distutils.core.setup" title="distutils.core.setup"><code class="xref py py-class docutils literal notranslate"><span class="pre">setup</span></code></a> 在 <code class="docutils literal notranslate"><span class="pre">classifiers</span></code>、<code class="docutils literal notranslate"><span class="pre">keywords</span></code> 或 <code class="docutils literal notranslate"><span class="pre">platforms</span></code> 字段未指定为列表或字符串时发出警告。</p>
|
||
</div>
|
||
</section>
|
||
<section id="debugging-the-setup-script">
|
||
<span id="debug-setup-script"></span><h2><span class="section-number">2.9. </span>调试安装脚本<a class="headerlink" href="#debugging-the-setup-script" title="永久链接至标题">¶</a></h2>
|
||
<p>有时会出现问题,并且安装脚本不能执行开发人员想要的操作。</p>
|
||
<p>Distutils在运行安装脚本时捕获任何异常,并在脚本终止前打印一条简单的错误消息。这种行为的动机是为了不让那些对Python不太了解并试图安装软件包的管理员感到困惑。如果他们从Distutils的内部深处得到了一个很长的追溯,他们可能会认为这个软件包或Python安装坏了,因为他们没有一直读到底部,看到这是一个权限问题。</p>
|
||
<p>另一方面,这并不能帮助开发人员找到失败的原因。 为此,<span class="target" id="index-2"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">DISTUTILS_DEBUG</span></code> 环境变量可以设置为除空字符串之外的任何值,distutils 现在将打印有关其正在执行的操作的详细信息,在发生异常时转储完整的回溯,并在外部程序(如 C 编译器)失败时打印整个命令行。</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">2. 编写安装脚本</a><ul>
|
||
<li><a class="reference internal" href="#listing-whole-packages">2.1. 列出全部的包</a></li>
|
||
<li><a class="reference internal" href="#listing-individual-modules">2.2. 列出单独的模块</a></li>
|
||
<li><a class="reference internal" href="#describing-extension-modules">2.3. 描述扩展模块</a><ul>
|
||
<li><a class="reference internal" href="#extension-names-and-packages">2.3.1. 扩展名和软件包</a></li>
|
||
<li><a class="reference internal" href="#extension-source-files">2.3.2. 扩展的源文件</a></li>
|
||
<li><a class="reference internal" href="#preprocessor-options">2.3.3. 预处理器选项</a></li>
|
||
<li><a class="reference internal" href="#library-options">2.3.4. 库选项</a></li>
|
||
<li><a class="reference internal" href="#other-options">2.3.5. 其它选项</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#relationships-between-distributions-and-packages">2.4. 分发和软件包之间的关系</a></li>
|
||
<li><a class="reference internal" href="#installing-scripts">2.5. 安装脚本</a></li>
|
||
<li><a class="reference internal" href="#installing-package-data">2.6. 安装软件包数据</a></li>
|
||
<li><a class="reference internal" href="#installing-additional-files">2.7. 安装其它文件</a></li>
|
||
<li><a class="reference internal" href="#additional-meta-data">2.8. 附加元数据</a></li>
|
||
<li><a class="reference internal" href="#debugging-the-setup-script">2.9. 调试安装脚本</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="introduction.html"
|
||
title="上一章"><span class="section-number">1. </span>Distutils 模块介绍</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="configfile.html"
|
||
title="下一章"><span class="section-number">3. </span>编写设置脚本的配置文件</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/distutils/setupscript.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
>索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="configfile.html" title="3. 编写设置脚本的配置文件"
|
||
>下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="introduction.html" title="1. Distutils 模块介绍"
|
||
>上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >分发 Python 模块(遗留版本)</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
|
||
<br />
|
||
This page is licensed under the Python Software Foundation License Version 2.
|
||
<br />
|
||
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
|
||
<br />
|
||
|
||
<br />
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
<br />
|
||
|
||
最后更新于 12月 09, 2024.
|
||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||
<br />
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |