python-peps/pep-0720/index.html

1109 lines
72 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 720 Cross-compiling Python packages | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0720/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 720 Cross-compiling Python packages | peps.python.org'>
<meta property="og:description" content="This PEP attempts to document the status of cross-compilation of downstream projects.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0720/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="This PEP attempts to document the status of cross-compilation of downstream projects.">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 720</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 720 Cross-compiling Python packages</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Filipe Laíns &lt;lains&#32;&#97;t&#32;riseup.net&gt;</dd>
<dt class="field-even">PEP-Delegate<span class="colon">:</span></dt>
<dd class="field-even"><p></p></dd>
<dt class="field-odd">Status<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Proposal under active discussion and revision">Draft</abbr></dd>
<dt class="field-even">Type<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd>
<dt class="field-odd">Created<span class="colon">:</span></dt>
<dd class="field-odd">01-Jul-2023</dd>
<dt class="field-even">Python-Version<span class="colon">:</span></dt>
<dd class="field-even">3.12</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#analysis">Analysis</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#upstream-support">Upstream support</a><ul>
<li><a class="reference internal" href="#projects-with-decent-cross-build-support">Projects with decent cross-build support</a></li>
</ul>
</li>
<li><a class="reference internal" href="#downstream-approaches">Downstream approaches</a><ul>
<li><a class="reference internal" href="#cross-build-environment">Cross-build environment</a></li>
<li><a class="reference internal" href="#faking-the-target-environment">Faking the target environment</a></li>
</ul>
</li>
<li><a class="reference internal" href="#environment-introspection">Environment introspection</a><ul>
<li><a class="reference internal" href="#cpython-and-similar">CPython (and similar)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#relevant-information">Relevant Information</a><ul>
<li><a class="reference internal" href="#when-should-extensions-be-linked-against-libpython">When should extensions be linked against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>?</a></li>
<li><a class="reference internal" href="#what-are-prefix-exec-prefix-base-prefix-and-base-exec-prefix">What are <code class="docutils literal notranslate"><span class="pre">prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">base_prefix</span></code>, and <code class="docutils literal notranslate"><span class="pre">base_exec_prefix</span></code>?</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#case-studies">Case studies</a><ul>
<li><a class="reference internal" href="#crossenv">crossenv</a></li>
<li><a class="reference internal" href="#conda-forge">conda-forge</a></li>
<li><a class="reference internal" href="#yocto-project">Yocto Project</a></li>
<li><a class="reference internal" href="#buildroot">Buildroot</a></li>
<li><a class="reference internal" href="#pyodide">Pyodide</a></li>
<li><a class="reference internal" href="#beeware">Beeware</a></li>
<li><a class="reference internal" href="#python-for-android">python-for-android</a></li>
<li><a class="reference internal" href="#kivy-ios">kivy-ios</a></li>
<li><a class="reference internal" href="#aidlearning">AidLearning</a></li>
<li><a class="reference internal" href="#qpython">QPython</a></li>
<li><a class="reference internal" href="#pyqtdeploy">pyqtdeploy</a></li>
<li><a class="reference internal" href="#chaquopy">Chaquopy</a></li>
<li><a class="reference internal" href="#edk-ii">EDK II</a></li>
<li><a class="reference internal" href="#activepython">ActivePython</a></li>
<li><a class="reference internal" href="#termux">Termux</a></li>
</ul>
</li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP attempts to document the status of cross-compilation of downstream
projects.</p>
<p>It should give an overview of the approaches currently used by distributors
(Linux distros, WASM environment providers, etc.) to cross-compile downstream
projects (3rd party extensions, etc.).</p>
</section>
<section id="motivation">
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
<p>We write this PEP to express the challenges in cross-compilation and act as a
supporting document in future improvement proposals.</p>
</section>
<section id="analysis">
<h2><a class="toc-backref" href="#analysis" role="doc-backlink">Analysis</a></h2>
<section id="introduction">
<h3><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h3>
<p>There are a couple different approaches being used to tackle this, with
different levels of interaction required from the user, but they all require a
significant amount of effort. This is due to the lack of standardized
cross-compilation infrastructure on the Python packaging ecosystem, which itself
stems from the complexity of cross-builds, making it a huge undertaking.</p>
</section>
<section id="upstream-support">
<h3><a class="toc-backref" href="#upstream-support" role="doc-backlink">Upstream support</a></h3>
<p>Some major projects like CPython, setuptools, etc. provide some support to help
with cross-compilation, but its unofficial and at a best-effort basis. For
example, the <code class="docutils literal notranslate"><span class="pre">sysconfig</span></code> module allows overwriting the data module name via
the <code class="docutils literal notranslate"><span class="pre">_PYTHON_SYSCONFIGDATA_NAME</span></code> environment variable, something that is
required for cross-builds, and setuptools <a class="reference external" href="https://github.com/pypa/distutils/pulls?q=cross">accepts patches</a> <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a> to tweak/fix
its logic to be compatible with popular <a class="reference internal" href="#faking-the-target-environment">“environment faking”</a> workflows <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>.</p>
<p>The lack of first-party support in upstream projects leads to cross-compilation
being fragile and requiring a significant effort from users, but at the same
time, the lack of standardization makes it harder for upstreams to improve
support as theres no clarity on how this feature should be provided.</p>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id3" role="doc-footnote">
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
<dd>At the time of writing (Jun 2023), setuptools compiler interface code,
the component that most of affects cross-compilation, is developed on the
<a class="reference external" href="https://github.com/pypa/distutils">pypa/distutils</a> repository, which gets periodically synced to the
setuptools repository.</aside>
<aside class="footnote brackets" id="id4" role="doc-footnote">
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
<dd>We specifically mention <em>popular</em> workflows, because this is not
standardized. Though, many of the most popular implementations
(<a class="reference internal" href="#crossenv">crossenv</a>, <a class="reference internal" href="#conda-forge">conda-forge</a>s build system, etc.) work similarly, and this
is what we are referring to here. For clarity, the implementations we are
referring to here could be described as <em>crossenv-style</em>.</aside>
</aside>
<section id="projects-with-decent-cross-build-support">
<h4><a class="toc-backref" href="#projects-with-decent-cross-build-support" role="doc-backlink">Projects with decent cross-build support</a></h4>
<p>It seems relevant to point out that there are a few modern Python package
build-backends with, at least, decent cross-compilation support, those being
<a class="reference external" href="https://github.com/scikit-build/scikit-build">scikit-build</a> and <a class="reference external" href="https://github.com/mesonbuild/meson-python">meson-python</a>. Both these projects integrate external mature
build-systems into Python packaging — <a class="reference external" href="https://cmake.org/">CMake</a> and <a class="reference external" href="https://mesonbuild.com/">Meson</a>, respectively — so
cross-build support is inherited from them.</p>
</section>
</section>
<section id="downstream-approaches">
<h3><a class="toc-backref" href="#downstream-approaches" role="doc-backlink">Downstream approaches</a></h3>
<p>Cross-compilation approaches fall in a spectrum that goes from, by design,
requiring extensive user interaction to (ideally) almost none. Usually, theyll
be based on one of two main strategies, using a <a class="reference internal" href="#cross-build-environment">cross-build environment</a>,
or <a class="reference internal" href="#faking-the-target-environment">faking the target environment</a>.</p>
<section id="cross-build-environment">
<span id="approach-cross-environment"></span><h4><a class="toc-backref" href="#cross-build-environment" role="doc-backlink">Cross-build environment</a></h4>
<p>This consists of running the Python interpreter normally and utilizing the
cross-build provided by the projects build-system. However, as we saw above,
upstream support is lacking, so this approach only works for a small-ish set of
projects. When this fails, the usual strategy is to patch the build-system code
to build use the correct toolchain, system details, etc. <a class="footnote-reference brackets" href="#id12" id="id11">[3]</a>.</p>
<p>Since this approach often requires package-specific patching, it requires a lot
of user interaction.</p>
<div class="note admonition">
<p class="admonition-title">Examples</p>
<p><a class="reference internal" href="#python-for-android">python-for-android</a>, <a class="reference internal" href="#kivy-ios">kivy-ios</a>, etc.</p>
</div>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id12" role="doc-footnote">
<dt class="label" id="id12">[<a href="#id11">3</a>]</dt>
<dd>The scope of the build-system patching varies between users and usually
depends on the their goal — some (eg. Linux distributions) may patch the
build-system to support cross-builds, while others might hardcode
compiler paths and system information in the build-system, to simply make
the build work.</aside>
</aside>
</section>
<section id="faking-the-target-environment">
<h4><a class="toc-backref" href="#faking-the-target-environment" role="doc-backlink">Faking the target environment</a></h4>
<p>Aiming to drop the requirement for user input, a popular approach is trying to
fake the target environment. It generally consists of monkeypatching the Python
interpreter to get it to mimic the interpreter on the target system, which
constitutes of changing many of the <code class="docutils literal notranslate"><span class="pre">sys</span></code> module attributes, the <code class="docutils literal notranslate"><span class="pre">sysconfig</span></code>
data, etc. Using this strategy, build-backends do not need to have any
cross-build support, and should just work without any code changes.</p>
<p>Unfortunately, though, it isnt possible to truly fake the target environment.
There are many reasons for this, one of the main ones being that it breaks code
that actually needs to introspect the running interpreter. As a result,
monkeypatching Python to look like target is very tricky — to achieve the less
amount of breakage, we can only patch certain aspects of the interpreter.
Consequently, build-backends may need some code changes, but these are generally
much smaller than the previous approach. This is an inherent limitation of the
technique, meaning this strategy still requires some user interaction.</p>
<p>Nonetheless, this strategy still works out-of-the-box with significantly more
projects than the approach above, and requires much less effort in these cases.
It is successful in decreasing the amount of user interaction needed, even
though it doesnt succeed in being generic.</p>
<div class="note admonition">
<p class="admonition-title">Examples</p>
<p><a class="reference internal" href="#crossenv">crossenv</a>, <a class="reference internal" href="#conda-forge">conda-forge</a>, etc.</p>
</div>
</section>
</section>
<section id="environment-introspection">
<h3><a class="toc-backref" href="#environment-introspection" role="doc-backlink">Environment introspection</a></h3>
<p>As explained above, most build system code is written with the assumption that
the target system is the same as where the build is occurring, so introspection
is usually used to guide the build.</p>
<p>In this section, we try to document most of the ways this is accomplished. It
should give a decent overview of of environment details that are required by
build systems.</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Snippet</th>
<th class="head">Description</th>
<th class="head">Variance</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">EXTENSION_SUFFIXES</span>
<span class="go">[</span>
<span class="go"> &#39;.cpython-311-x86_64-linux-gnu.so&#39;,</span>
<span class="go"> &#39;.abi3.so&#39;,</span>
<span class="go"> &#39;.so&#39;,</span>
<span class="go">]</span>
</pre></div>
</div>
</td>
<td>Extension (native module) suffixes supported by this interpreter.</td>
<td>This is implementation-defined, but it <strong>usually</strong> differs based on the
implementation, system architecture, build configuration, Python
language version, and implementation version — if one exists.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">SOURCE_SUFFIXES</span>
<span class="go">[&#39;.py&#39;]</span>
</pre></div>
</div>
</td>
<td>Source (pure-Python) suffixes supported by this interpreter.</td>
<td>This is implementation-defined, but it <strong>usually</strong> doesnt differ
(outside exotic implementations or systems).</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">importlib</span><span class="o">.</span><span class="n">machinery</span><span class="o">.</span><span class="n">all_suffixes</span><span class="p">()</span>
<span class="go">[</span>
<span class="go"> &#39;.py&#39;,</span>
<span class="go"> &#39;.pyc&#39;,</span>
<span class="go"> &#39;.cpython-311-x86_64-linux-gnu.so&#39;,</span>
<span class="go"> &#39;.abi3.so&#39;,</span>
<span class="go"> &#39;.so&#39;,</span>
<span class="go">]</span>
</pre></div>
</div>
</td>
<td>All module file suffixes supported by this interpreter. It <em>should</em> be the
union of all <code class="docutils literal notranslate"><span class="pre">importlib.machinery.*_SUFFIXES</span></code> attributes.</td>
<td>This is implementation-defined, but it <strong>usually</strong> differs based on the
implementation, system architecture, build configuration, Python
language version, and implementation version — if one exists. See the
entries above for more information.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">abiflags</span>
<span class="go">&#39;&#39;</span>
</pre></div>
</div>
</td>
<td>ABI flags, as specified in <a class="pep reference internal" href="../pep-3149/" title="PEP 3149 ABI version tagged .so files">PEP 3149</a>.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">api_version</span>
<span class="go">1013</span>
</pre></div>
</div>
</td>
<td>C API version.</td>
<td>Differs based on the Python installation.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">base_prefix</span>
<span class="go">/usr</span>
</pre></div>
</div>
</td>
<td>Prefix of the installation-wide directories where platform independent
files are installed.</td>
<td>Differs based on the platform, and installation.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">base_exec_prefix</span>
<span class="go">/usr</span>
</pre></div>
</div>
</td>
<td>Prefix of the installation-wide directories where platform dependent
files are installed.</td>
<td>Differs based on the platform, and installation.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">byteorder</span>
<span class="go">&#39;little&#39;</span>
</pre></div>
</div>
</td>
<td>Native byte order.</td>
<td>Differs based on the platform.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">builtin_module_names</span>
<span class="go">(&#39;_abc&#39;, &#39;_ast&#39;, &#39;_codecs&#39;, ...)</span>
</pre></div>
</div>
</td>
<td>Names of all modules that are compiled into the Python interpreter.</td>
<td>Differs based on the platform, system architecture, and build
configuration.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">exec_prefix</span>
<span class="go">/usr</span>
</pre></div>
</div>
</td>
<td>Prefix of the site-specific directories where platform independent files
are installed. Because it concerns the site-specific directories, in
standard virtual environment implementation, it will be a
virtual-environment-specific path.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">executable</span>
<span class="go">&#39;/usr/bin/python&#39;</span>
</pre></div>
</div>
</td>
<td>Path of the Python interpreter being used.</td>
<td>Differs based on the installation.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">executable</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">header</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="gp">... </span> <span class="k">if</span> <span class="n">is_elf</span> <span class="o">:=</span> <span class="p">(</span><span class="n">header</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x7f</span><span class="s1">ELF&#39;</span><span class="p">):</span>
<span class="gp">... </span> <span class="n">elf_class</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
<span class="gp">... </span> <span class="n">size</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">:</span> <span class="mi">52</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span> <span class="mi">64</span><span class="p">}</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">elf_class</span><span class="p">)</span>
<span class="gp">... </span> <span class="n">elf_header</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">size</span> <span class="o">-</span> <span class="mi">5</span><span class="p">)</span>
</pre></div>
</div>
</td>
<td>Whether the Python interpreter is an ELF file, and the ELF header. This
approach is something used to identify the target architecture of the
installation (<a class="reference external" href="https://github.com/pypa/packaging/blob/2f80de7fd2a8bc199dadf5cf3f5f302a17084792/src/packaging/_manylinux.py#L43-L50">example</a>).</td>
<td>Differs based on the installation.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">float_info</span>
<span class="go">sys.float_info(</span>
<span class="go"> max=1.7976931348623157e+308,</span>
<span class="go"> max_exp=1024,</span>
<span class="go"> max_10_exp=308,</span>
<span class="go"> min=2.2250738585072014e-308,</span>
<span class="go"> min_exp=-1021,</span>
<span class="go"> min_10_exp=-307,</span>
<span class="go"> dig=15,</span>
<span class="go"> mant_dig=53,</span>
<span class="go"> epsilon=2.220446049250313e-16,</span>
<span class="go"> radix=2,</span>
<span class="go"> rounds=1,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Low level information about the float type, as defined by <code class="docutils literal notranslate"><span class="pre">float.h</span></code>.</td>
<td>Differs based on the architecture, and platform.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">getandroidapilevel</span><span class="p">()</span>
<span class="go">21</span>
</pre></div>
</div>
</td>
<td>Integer representing the Android API level.</td>
<td>Differs based on the platform.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">getwindowsversion</span><span class="p">()</span>
<span class="go">sys.getwindowsversion(</span>
<span class="go"> major=10,</span>
<span class="go"> minor=0,</span>
<span class="go"> build=19045,</span>
<span class="go"> platform=2,</span>
<span class="go"> service_pack=&#39;&#39;,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Windows version of the system.</td>
<td>Differs based on the platform.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">hexversion</span>
<span class="go">0x30b03f0</span>
</pre></div>
</div>
</td>
<td>Python version encoded as an integer.</td>
<td>Differs based on the Python language version.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">implementation</span>
<span class="go">namespace(</span>
<span class="go"> name=&#39;cpython&#39;,</span>
<span class="go"> cache_tag=&#39;cpython-311&#39;,</span>
<span class="go"> version=sys.version_info(</span>
<span class="go"> major=3,</span>
<span class="go"> minor=11,</span>
<span class="go"> micro=3,</span>
<span class="go"> releaselevel=&#39;final&#39;,</span>
<span class="go"> serial=0,</span>
<span class="go"> ),</span>
<span class="go"> hexversion=0x30b03f0,</span>
<span class="go"> _multiarch=&#39;x86_64-linux-gnu&#39;,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Interpreter implementation details.</td>
<td>Differs based on the interpreter implementation, Python language
version, and implementation version — if one exists. It may also include
architecture-dependent information, so it may also differ based on the
system architecture.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">int_info</span>
<span class="go">sys.int_info(</span>
<span class="go"> bits_per_digit=30,</span>
<span class="go"> sizeof_digit=4,</span>
<span class="go"> default_max_str_digits=4300,</span>
<span class="go"> str_digits_check_threshold=640,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Low level information about Pythons internal integer representation.</td>
<td>Differs based on the architecture, platform, implementation, build, and
runtime flags.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span>
<span class="go">0x7fffffffffffffff</span>
</pre></div>
</div>
</td>
<td>Maximum value a variable of type <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> can take.</td>
<td>Differs based on the architecture, platform, and implementation.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">maxunicode</span>
<span class="go">0x10ffff</span>
</pre></div>
</div>
</td>
<td>Value of the largest Unicode code point.</td>
<td>Differs based on the implementation, and on Python versions older than
3.3, the build.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">platform</span>
<span class="go">linux</span>
</pre></div>
</div>
</td>
<td>Platform identifier.</td>
<td>Differs based on the platform.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">prefix</span>
<span class="go">/usr</span>
</pre></div>
</div>
</td>
<td>Prefix of the site-specific directories where platform dependent files
are installed. Because it concerns the site-specific directories, in
standard virtual environment implementation, it will be a
virtual-environment-specific path.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">platlibdir</span>
<span class="go">lib</span>
</pre></div>
</div>
</td>
<td>Platform-specific library directory.</td>
<td>Differs based on the platform, and vendor.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">version_info</span>
<span class="go">sys.version_info(</span>
<span class="go"> major=3,</span>
<span class="go"> minor=11,</span>
<span class="go"> micro=3,</span>
<span class="go"> releaselevel=&#39;final&#39;,</span>
<span class="go"> serial=0,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Python language version implemented by the interpreter.</td>
<td>Differs if the target Python version is not the same <a class="footnote-reference brackets" href="#id17" id="id13">[4]</a>.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">thread_info</span>
<span class="go">sys.thread_info(</span>
<span class="go"> name=&#39;pthread&#39;,</span>
<span class="go"> lock=&#39;semaphore&#39;,</span>
<span class="go"> version=&#39;NPTL 2.37&#39;,</span>
<span class="go">)</span>
</pre></div>
</div>
</td>
<td>Information about the thread implementation.</td>
<td>Differs based on the platform, and implementation.</td>
</tr>
<tr class="row-odd"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">winver</span>
<span class="go">3.8-32</span>
</pre></div>
</div>
</td>
<td>Version number used to form Windows registry keys.</td>
<td>Differs based on the platform, and implementation.</td>
</tr>
<tr class="row-even"><td><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_vars</span><span class="p">()</span>
<span class="go">{ ... }</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_var</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="gp">...</span>
</pre></div>
</div>
</td>
<td>Python distribution configuration variables. It includes a set of
variables <a class="footnote-reference brackets" href="#id18" id="id14">[5]</a> — like <code class="docutils literal notranslate"><span class="pre">prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code>, etc. — based on the
running context <a class="footnote-reference brackets" href="#id19" id="id15">[6]</a>, and may include some extra variables based on the
Python implementation and system.<p>In CPython and most other implementations that use the same
build-system, the “extra” variables mention above are: on POSIX, all
variables from the <code class="docutils literal notranslate"><span class="pre">Makefile</span></code> used to build the interpreter, and on
Windows, it usually only includes a small subset of the those <a class="footnote-reference brackets" href="#id20" id="id16">[7]</a>
like <code class="docutils literal notranslate"><span class="pre">EXT_SUFFIX</span></code>, <code class="docutils literal notranslate"><span class="pre">BINDIR</span></code>, etc.</p>
</td>
<td>This is implementation-defined, but it <strong>usually</strong> differs between
non-identical builds. Please refer to the
<a class="reference internal" href="#sysconfig-configuration-variables">sysconfig configuration variables</a> table for a overview of the different
configuration variable that are usually present.</td>
</tr>
</tbody>
</table>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id17" role="doc-footnote">
<dt class="label" id="id17">[<a href="#id13">4</a>]</dt>
<dd>Ideally, you want to perform cross-builds with the same Python version
and implementation, however, this is often not the case. It should not
be very problematic as long as the major and minor versions dont
change.</aside>
<aside class="footnote brackets" id="id18" role="doc-footnote">
<dt class="label" id="id18">[<a href="#id14">5</a>]</dt>
<dd>The set of config variables that will always be present mostly consists
of variables needed to calculate the installation scheme paths.</aside>
<aside class="footnote brackets" id="id19" role="doc-footnote">
<dt class="label" id="id19">[<a href="#id15">6</a>]</dt>
<dd>The context we refer here consists of the “path initialization”, which is
a process that happens in the interpreter startup and is responsible for
figuring out which environment it is being run — eg. global environment,
virtual environment, etc. — and setting <code class="docutils literal notranslate"><span class="pre">sys.prefix</span></code> and other
attributes accordingly.</aside>
<aside class="footnote brackets" id="id20" role="doc-footnote">
<dt class="label" id="id20">[<a href="#id16">7</a>]</dt>
<dd>This is because Windows builds may not use the <code class="docutils literal notranslate"><span class="pre">Makefile</span></code>, and instead
<a class="reference external" href="https://docs.python.org/3/using/configure.html#debug-build">use the Visual Studio build system</a>. A subset of the most relevant
<code class="docutils literal notranslate"><span class="pre">Makefile</span></code> variables is provided to make user code that uses them
simpler.</aside>
</aside>
<section id="cpython-and-similar">
<h4><a class="toc-backref" href="#cpython-and-similar" role="doc-backlink">CPython (and similar)</a></h4>
<table class="docutils align-default" id="sysconfig-configuration-variables">
<caption><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code> configuration variables</span></caption>
<colgroup>
<col style="width: 20.0%" />
<col style="width: 20.0%" />
<col style="width: 30.0%" />
<col style="width: 30.0%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head">Name</th>
<th class="head">Example Value</th>
<th class="head">Description</th>
<th class="head">Variance</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">SOABI</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">cpython-311-x86_64-linux-gnu</span></code></td>
<td>ABI string — defined by <a class="pep reference internal" href="../pep-3149/" title="PEP 3149 ABI version tagged .so files">PEP 3149</a>.</td>
<td>Differs based on the implementation, system architecture, Python
language version, and implementation version — if one exists.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">SHLIB_SUFFIX</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">.so</span></code></td>
<td>Shared library suffix.</td>
<td>Differs based on the platform.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">EXT_SUFFIX</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">.cpython-311-x86_64-linux-gnu.so</span></code></td>
<td>Interpreter-specific Python extension (native module) suffix — generally
defined as <code class="docutils literal notranslate"><span class="pre">.{SOABI}.{SHLIB_SUFFIX}</span></code>.</td>
<td>Differs based on the implementation, system architecture, Python
language version, and implementation version — if one exists.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">LDLIBRARY</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">libpython3.11.so</span></code></td>
<td>Shared <code class="docutils literal notranslate"><span class="pre">libpython</span></code> library name — if available. If unavailable <a class="footnote-reference brackets" href="#id27" id="id23">[8]</a>,
the variable will be empty, if available, the library should be located
in <code class="docutils literal notranslate"><span class="pre">LIBDIR</span></code>.</td>
<td>Differs based on the implementation, system architecture, build
configuration, Python language version, and implementation version — if
one exists.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">PY3LIBRARY</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">libpython3.so</span></code></td>
<td>Shared Python 3 only (major version bound only) <a class="footnote-reference brackets" href="#id28" id="id24">[9]</a> <code class="docutils literal notranslate"><span class="pre">libpython</span></code>
library name — if available. If unavailable <a class="footnote-reference brackets" href="#id27" id="id25">[8]</a>, the variable will be
empty, if available, the library should be located in <code class="docutils literal notranslate"><span class="pre">LIBDIR</span></code>.</td>
<td>Differs based on the implementation, system architecture, build
configuration, Python language version, and implementation version — if
one exists.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">LIBRARY</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">libpython3.11.a</span></code></td>
<td>Static <code class="docutils literal notranslate"><span class="pre">libpython</span></code> library name — if available. If unavailable <a class="footnote-reference brackets" href="#id27" id="id26">[8]</a>,
the variable will be empty, if available, the library should be located
in <code class="docutils literal notranslate"><span class="pre">LIBDIR</span></code>.</td>
<td>Differs based on the implementation, system architecture, build
configuration, Python language version, and implementation version — if
one exists.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">Py_DEBUG</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">0</span></code></td>
<td>Whether this is a <a class="reference external" href="https://docs.python.org/3/c-api/intro.html#debugging-builds">debug build</a>.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">WITH_PYMALLOC</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">1</span></code></td>
<td>Whether this build has <a class="reference external" href="https://docs.python.org/3/c-api/memory.html#pymalloc">pymalloc</a> support.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">Py_TRACE_REFS</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">0</span></code></td>
<td>Whether reference tracing (debug build only) is enabled.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">Py_UNICODE_SIZE</span></code></td>
<td></td>
<td>Size of the <code class="docutils literal notranslate"><span class="pre">Py_UNICODE</span></code> object, in bytes. This variable is only
present in CPython versions older than 3.3, and was commonly used to
detect if the build uses UCS2 or UCS4 for unicode objects — before
<a class="pep reference internal" href="../pep-0393/" title="PEP 393 Flexible String Representation">PEP 393</a>.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">Py_ENABLE_SHARED</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">1</span></code></td>
<td>Whether a shared <code class="docutils literal notranslate"><span class="pre">libpython</span></code> is available.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">PY_ENABLE_SHARED</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">1</span></code></td>
<td>Whether a shared <code class="docutils literal notranslate"><span class="pre">libpython</span></code> is available.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">CC</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">gcc</span></code></td>
<td>The C compiler used to build the Python distribution.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">CXX</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">g++</span></code></td>
<td>The C compiler used to build the Python distribution.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">CFLAGS</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">-DNDEBUG</span> <span class="pre">-g</span> <span class="pre">-fwrapv</span> <span class="pre">...</span></code></td>
<td>The C compiler flags used to build the Python distribution.</td>
<td>Differs based on the build configuration.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">py_version</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">3.11.3</span></code></td>
<td>Full form of the Python version.</td>
<td>Differs based on the Python language version.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">py_version_short</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">3.11</span></code></td>
<td>Custom form of the Python version, containing only the major and minor
numbers.</td>
<td>Differs based on the Python language version.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">py_version_nodot</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">311</span></code></td>
<td>Custom form of the Python version, containing only the major and minor
numbers, and no dots.</td>
<td>Differs based on the Python language version.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">prefix</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.prefix</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">base</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.prefix</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.exec_prefix</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">platbase</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.exec_prefix</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, installation, and environment.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">installed_base</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.base_prefix</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, and installation.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">installed_platbase</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">/usr</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.base_exec_prefix</span></code>, please refer to the entry in table
above.</td>
<td>Differs based on the platform, and installation.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">platlibdir</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">lib</span></code></td>
<td>Same as <code class="docutils literal notranslate"><span class="pre">sys.platlibdir</span></code>, please refer to the entry in table above.</td>
<td>Differs based on the platform, and vendor.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">SIZEOF_*</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">4</span></code></td>
<td>Size of a certain C type (<code class="docutils literal notranslate"><span class="pre">double</span></code>, <code class="docutils literal notranslate"><span class="pre">float</span></code>, etc.).</td>
<td>Differs based on the system architecture, and build details.</td>
</tr>
</tbody>
</table>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id27" role="doc-footnote">
<dt class="label" id="id27">[8]<em> (<a href='#id23'>1</a>, <a href='#id25'>2</a>, <a href='#id26'>3</a>) </em></dt>
<dd>Due to Python bring compiled without shared or static <code class="docutils literal notranslate"><span class="pre">libpython</span></code>
support, respectively.</aside>
<aside class="footnote brackets" id="id28" role="doc-footnote">
<dt class="label" id="id28">[<a href="#id24">9</a>]</dt>
<dd>This is the <code class="docutils literal notranslate"><span class="pre">libpython</span></code> library that users of the <a class="reference external" href="https://docs.python.org/3/c-api/stable.html#stable-application-binary-interface">stable ABI</a> should
link against, if they need to link against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>.</aside>
</aside>
</section>
</section>
<section id="relevant-information">
<h3><a class="toc-backref" href="#relevant-information" role="doc-backlink">Relevant Information</a></h3>
<p>There are some bits of information required by build systems — eg. platform
particularities — scattered across many places, and it often is difficult to
identify code with assumptions based on them. In this section, we try to
document the most relevant cases.</p>
<section id="when-should-extensions-be-linked-against-libpython">
<h4><a class="toc-backref" href="#when-should-extensions-be-linked-against-libpython" role="doc-backlink">When should extensions be linked against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>?</a></h4>
<dl class="simple">
<dt>Short answer</dt><dd>Yes, on Windows. No on POSIX platforms, except Android, Cygwin, and other
Windows-based POSIX-like platforms.</dd>
</dl>
<p>When building extensions for dynamic loading, depending on the target platform,
they may need to be linked against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>.</p>
<p>On Windows, extensions need to link against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>, because all symbols
must be resolvable at link time. POSIX-like platforms based on Windows — like
Cygwin, MinGW, or MSYS — will also require linking against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>.</p>
<p>On most POSIX platforms, it is not necessary to link against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>, as
the symbols will already be available in the due to the interpreter — or, when
embedding, the executable/library in question — already linking to
<code class="docutils literal notranslate"><span class="pre">libpython</span></code>. Not linking an extension module against <code class="docutils literal notranslate"><span class="pre">libpython</span></code> will allow
it to be loaded by static Python builds, so when possible, it is desirable to do
so (see <a class="reference external" href="https://github.com/python/cpython/issues/65735">GH-65735</a>).</p>
<p>This might not be the case on all POSIX platforms, so make sure you check. One
example is Android, where only the main executable and <code class="docutils literal notranslate"><span class="pre">LD_PRELOAD</span></code> entries
are considered to be <code class="docutils literal notranslate"><span class="pre">RTLD_GLOBAL</span></code> (meaning dependencies are <code class="docutils literal notranslate"><span class="pre">RTLD_LOCAL</span></code>)
<a class="footnote-reference brackets" href="#id33" id="id32">[10]</a>, which causes the <code class="docutils literal notranslate"><span class="pre">libpython</span></code> symbols be unavailable when loading the
extension.</p>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id33" role="doc-footnote">
<dt class="label" id="id33">[<a href="#id32">10</a>]</dt>
<dd>Refer to <a class="reference external" href="https://man.archlinux.org/man/dlopen.3">dlopens man page</a> for more information.</aside>
</aside>
</section>
<section id="what-are-prefix-exec-prefix-base-prefix-and-base-exec-prefix">
<h4><a class="toc-backref" href="#what-are-prefix-exec-prefix-base-prefix-and-base-exec-prefix" role="doc-backlink">What are <code class="docutils literal notranslate"><span class="pre">prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">base_prefix</span></code>, and <code class="docutils literal notranslate"><span class="pre">base_exec_prefix</span></code>?</a></h4>
<p>These are <code class="docutils literal notranslate"><span class="pre">sys</span></code> attributes <a class="reference external" href="https://github.com/python/cpython/blob/6a70edf24ca217c5ed4a556d0df5748fc775c762/Modules/getpath.py">set in the Python initialization</a> that describe
the running environment. They refer to the prefix of directories where
installation/environment files are installed, according to the table below.</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Name</th>
<th class="head">Target files</th>
<th class="head">Environment Scope</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">prefix</span></code></td>
<td>platform independent (eg. pure Python)</td>
<td>site-specific</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code></td>
<td>platform dependent (eg. native code)</td>
<td>site-specific</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">base_prefix</span></code></td>
<td>platform independent (eg. pure Python)</td>
<td>installation-wide</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">base_exec_prefix</span></code></td>
<td>platform dependent (eg. native code)</td>
<td>installation-wide</td>
</tr>
</tbody>
</table>
<p>Because the site-specific prefixes will be different inside virtual
environments, checking <code class="docutils literal notranslate"><span class="pre">sys.prexix</span> <span class="pre">!=</span> <span class="pre">sys.base_prefix</span></code> is commonly used to
check if we are in a virtual environment.</p>
</section>
</section>
</section>
<section id="case-studies">
<h2><a class="toc-backref" href="#case-studies" role="doc-backlink">Case studies</a></h2>
<section id="crossenv">
<h3><a class="toc-backref" href="#crossenv" role="doc-backlink">crossenv</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Virtual Environments for Cross-Compiling Python Extension Modules.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/benfogle/crossenv">https://github.com/benfogle/crossenv</a></dd>
</dl>
<p><code class="docutils literal notranslate"><span class="pre">crossenv</span></code> is a tool to create a virtual environment with a monkeypatched
Python installation that tries to emulate the target machine in certain
scenarios. More about this approach can be found in the
<a class="reference internal" href="#faking-the-target-environment">Faking the target environment</a> section.</p>
</section>
<section id="conda-forge">
<h3><a class="toc-backref" href="#conda-forge" role="doc-backlink">conda-forge</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">A community-led collection of recipes, build infrastructure and distributions for the conda package manager.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://conda-forge.org/">https://conda-forge.org/</a></dd>
</dl>
<p>XXX: Jaime will write a quick summary once the PEP draft is public.</p>
<p>XXX
Uses a modified crossenv.</p>
</section>
<section id="yocto-project">
<h3><a class="toc-backref" href="#yocto-project" role="doc-backlink">Yocto Project</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">The Yocto Project is an open source collaboration project that helps developers create custom Linux-based systems regardless of the hardware architecture.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://www.yoctoproject.org/">https://www.yoctoproject.org/</a></dd>
</dl>
<p>XXX: Sent email to the mailing list.</p>
<p>TODO</p>
</section>
<section id="buildroot">
<h3><a class="toc-backref" href="#buildroot" role="doc-backlink">Buildroot</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Buildroot is a simple, efficient and easy-to-use tool to generate embedded Linux systems through cross-compilation.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://buildroot.org/">https://buildroot.org/</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="pyodide">
<h3><a class="toc-backref" href="#pyodide" role="doc-backlink">Pyodide</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Pyodide is a Python distribution for the browser and Node.js based on WebAssembly.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://pyodide.org/en/stable/">https://pyodide.org/en/stable/</a></dd>
</dl>
<p>XXX: Hood should review/expand this section.</p>
<p><code class="docutils literal notranslate"><span class="pre">Pyodide</span></code> is a provides a Python distribution compiled to <a class="reference external" href="https://webassembly.org/">WebAssembly</a>
using the <a class="reference external" href="https://emscripten.org/">Emscripten</a> toolchain.</p>
<p>It patches several aspects of the CPython installation and some external
components. A custom package manager — <a class="reference external" href="https://micropip.pyodide.org/">micropip</a> — supporting both Pure and
wasm32/Emscripten wheels, is also provided as a part of the distribution. On top
of this, a repo with a <a class="reference external" href="https://pyodide.org/en/stable/usage/packages-in-pyodide.html">selected set of 3rd party packages</a> is also provided
and enabled by default.</p>
</section>
<section id="beeware">
<h3><a class="toc-backref" href="#beeware" role="doc-backlink">Beeware</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">BeeWare allows you to write your app in Python and release it on multiple platforms.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://beeware.org/">https://beeware.org/</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="python-for-android">
<h3><a class="toc-backref" href="#python-for-android" role="doc-backlink">python-for-android</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Turn your Python application into an Android APK.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/kivy/python-for-android">https://github.com/kivy/python-for-android</a></dd>
</dl>
<p>resource <a class="reference external" href="https://github.com/Android-for-Python/Android-for-Python-Users">https://github.com/Android-for-Python/Android-for-Python-Users</a></p>
<p><code class="docutils literal notranslate"><span class="pre">python-for-android</span></code> is a tool to package Python apps on Android. It creates a
Python distribution with your app and its dependencies.</p>
<p>Pure-Python dependencies are handled automatically and in a generic way, but
native dependencies need <a class="reference external" href="https://python-for-android.readthedocs.io/en/latest/recipes/">recipes</a>. A set of recipes for
<a class="reference external" href="https://github.com/kivy/python-for-android/tree/develop/pythonforandroid/recipes">popular dependencies</a> is provided, but users need to provide their own
recipes for any other native dependencies.</p>
</section>
<section id="kivy-ios">
<h3><a class="toc-backref" href="#kivy-ios" role="doc-backlink">kivy-ios</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Toolchain for compiling Python / Kivy / other libraries for iOS.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/kivy/kivy-ios">https://github.com/kivy/kivy-ios</a></dd>
</dl>
<p><code class="docutils literal notranslate"><span class="pre">kivy-ios</span></code> is a tool to package Python apps on iOS. It provides a toolchain to
build a Python distribution with your app and its dependencies, as well as a CLI
to create and manage Xcode projects that integrate with the toolchain.</p>
<p>It uses the same approach as <a class="reference internal" href="#python-for-android">python-for-android</a> (also maintained by the
<a class="reference external" href="https://kivy.org">Kivy project</a>) for app dependencies — pure-Python dependencies are handled
automatically, but native dependencies need <a class="reference external" href="https://python-for-android.readthedocs.io/en/latest/recipes/">recipes</a>, and the project provides
recipes for <a class="reference external" href="https://github.com/kivy/kivy-ios/tree/master/kivy_ios/recipes">popular dependencies</a>.</p>
</section>
<section id="aidlearning">
<h3><a class="toc-backref" href="#aidlearning" role="doc-backlink">AidLearning</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">AI, Android, Linux, ARM: AI application development platform based on Android+Linux integrated ecology.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/aidlearning/AidLearning-FrameWork">https://github.com/aidlearning/AidLearning-FrameWork</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="qpython">
<h3><a class="toc-backref" href="#qpython" role="doc-backlink">QPython</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">QPython is the Python engine for android.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/qpython-android/qpython">https://github.com/qpython-android/qpython</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="pyqtdeploy">
<h3><a class="toc-backref" href="#pyqtdeploy" role="doc-backlink">pyqtdeploy</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">pyqtdeploy is a tool for deploying PyQt applications.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://www.riverbankcomputing.com/software/pyqtdeploy/">https://www.riverbankcomputing.com/software/pyqtdeploy/</a></dd>
</dl>
<p>contact <a class="reference external" href="https://www.riverbankcomputing.com/pipermail/pyqt/2023-May/thread.html">https://www.riverbankcomputing.com/pipermail/pyqt/2023-May/thread.html</a>
contacted Phil, the maintainer</p>
<p>TODO</p>
</section>
<section id="chaquopy">
<h3><a class="toc-backref" href="#chaquopy" role="doc-backlink">Chaquopy</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Chaquopy provides everything you need to include Python components in an Android app.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://chaquo.com/chaquopy/">https://chaquo.com/chaquopy/</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="edk-ii">
<h3><a class="toc-backref" href="#edk-ii" role="doc-backlink">EDK II</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">EDK II is a modern, feature-rich, cross-platform firmware development environment for the UEFI and PI specifications.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://github.com/tianocore/edk2-libc/tree/master/AppPkg/Applications/Python">https://github.com/tianocore/edk2-libc/tree/master/AppPkg/Applications/Python</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="activepython">
<h3><a class="toc-backref" href="#activepython" role="doc-backlink">ActivePython</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Commercial-grade, quality-assured Python distribution focusing on easy installation and cross-platform compatibility on Windows, Linux, Mac OS X, Solaris, HP-UX and AIX.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://www.activestate.com/products/python/">https://www.activestate.com/products/python/</a></dd>
</dl>
<p>TODO</p>
</section>
<section id="termux">
<h3><a class="toc-backref" href="#termux" role="doc-backlink">Termux</a></h3>
<dl class="field-list simple">
<dt class="field-odd">Description<span class="colon">:</span></dt>
<dd class="field-odd">Termux is an Android terminal emulator and Linux environment app that works directly with no rooting or setup required.</dd>
<dt class="field-even">URL<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://termux.dev/en/">https://termux.dev/en/</a></dd>
</dl>
<p>TODO</p>
</section>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0720.rst">https://github.com/python/peps/blob/main/peps/pep-0720.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0720.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#analysis">Analysis</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#upstream-support">Upstream support</a><ul>
<li><a class="reference internal" href="#projects-with-decent-cross-build-support">Projects with decent cross-build support</a></li>
</ul>
</li>
<li><a class="reference internal" href="#downstream-approaches">Downstream approaches</a><ul>
<li><a class="reference internal" href="#cross-build-environment">Cross-build environment</a></li>
<li><a class="reference internal" href="#faking-the-target-environment">Faking the target environment</a></li>
</ul>
</li>
<li><a class="reference internal" href="#environment-introspection">Environment introspection</a><ul>
<li><a class="reference internal" href="#cpython-and-similar">CPython (and similar)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#relevant-information">Relevant Information</a><ul>
<li><a class="reference internal" href="#when-should-extensions-be-linked-against-libpython">When should extensions be linked against <code class="docutils literal notranslate"><span class="pre">libpython</span></code>?</a></li>
<li><a class="reference internal" href="#what-are-prefix-exec-prefix-base-prefix-and-base-exec-prefix">What are <code class="docutils literal notranslate"><span class="pre">prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">exec_prefix</span></code>, <code class="docutils literal notranslate"><span class="pre">base_prefix</span></code>, and <code class="docutils literal notranslate"><span class="pre">base_exec_prefix</span></code>?</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#case-studies">Case studies</a><ul>
<li><a class="reference internal" href="#crossenv">crossenv</a></li>
<li><a class="reference internal" href="#conda-forge">conda-forge</a></li>
<li><a class="reference internal" href="#yocto-project">Yocto Project</a></li>
<li><a class="reference internal" href="#buildroot">Buildroot</a></li>
<li><a class="reference internal" href="#pyodide">Pyodide</a></li>
<li><a class="reference internal" href="#beeware">Beeware</a></li>
<li><a class="reference internal" href="#python-for-android">python-for-android</a></li>
<li><a class="reference internal" href="#kivy-ios">kivy-ios</a></li>
<li><a class="reference internal" href="#aidlearning">AidLearning</a></li>
<li><a class="reference internal" href="#qpython">QPython</a></li>
<li><a class="reference internal" href="#pyqtdeploy">pyqtdeploy</a></li>
<li><a class="reference internal" href="#chaquopy">Chaquopy</a></li>
<li><a class="reference internal" href="#edk-ii">EDK II</a></li>
<li><a class="reference internal" href="#activepython">ActivePython</a></li>
<li><a class="reference internal" href="#termux">Termux</a></li>
</ul>
</li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0720.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>