|
|
@@ -10,157 +10,169 @@
|
|
|
{% include "references.md" %}
|
|
|
|
|
|
|
|
|
-# Developers corner
|
|
|
+# Developers' corner
|
|
|
|
|
|
-Python [AppImages][APPIMAGE] are built with the `python-appimage` utility,
|
|
|
-available from [PyPI][PYPI]. This utility can also help packaging Python based
|
|
|
-applications as AppImages, using an existing Python AppImage and a recipe
|
|
|
+Python [AppImages][APPIMAGE] are created using the `python-appimage` utility,
|
|
|
+which is available on [PyPI][PYPI]. This utility can also be used to package
|
|
|
+Python-based applications as AppImages using an existing AppImage and a recipe
|
|
|
folder.
|
|
|
|
|
|
!!! Caution
|
|
|
The `python-appimage` utility can only package applications that can be
|
|
|
- directly installed with `pip`. For more advanced usage, one needs to extract
|
|
|
- the Python AppImage and to edit it, e.g. as explained in the [Advanced
|
|
|
- installation](index.md#advanced-installation) section. Additional details
|
|
|
- on this use case are provided [below](#advanced-packaging).
|
|
|
+ installed directly with `pip`. For more advanced usage, it is necessary to
|
|
|
+ extract and edit the Python AppImage, as explained in the [Advanced
|
|
|
+ installation](index.md#advanced-installation) section. Further details on
|
|
|
+ this use case can be found [below](#advanced-packaging).
|
|
|
|
|
|
|
|
|
## Building a Python AppImage
|
|
|
|
|
|
-The primary scope of `python-appimage` is to relocate an existing Python
|
|
|
-installation inside an AppDir, and to build the corresponding AppImage. For
|
|
|
-example, the following
|
|
|
+The primary purpose of `python-appimage` is to relocate an existing Python
|
|
|
+installation to an AppDir and build the corresponding AppImage. For example, the
|
|
|
+command
|
|
|
|
|
|
```bash
|
|
|
python-appimage build local -p $(which python2)
|
|
|
```
|
|
|
|
|
|
-should build an AppImage of your local Python 2 installation, provided that it
|
|
|
+should create an AppImage of your local Python installation, provided that it
|
|
|
exists.
|
|
|
|
|
|
!!! Tip
|
|
|
- Help on available arguments and options to `python-appimage` can be obtained
|
|
|
- with the `-h` flag. For example, `python-appimage build local -h` provides
|
|
|
- help on local builds.
|
|
|
+ Help on the available arguments and options for `python-appimage` can be
|
|
|
+ obtained by using the `-h` flag. For example, running
|
|
|
+ `python-appimage build local -h` provides help on local builds.
|
|
|
|
|
|
|
|
|
{{ begin(".capsule") }}
|
|
|
### Auxiliary tools
|
|
|
|
|
|
The `python-appimage` utility relies on auxiliary tools that are downloaded and
|
|
|
-installed at runtime, on need. Those are [appimagetool][APPIMAGETOOL] for
|
|
|
-building AppImages, and [patchelf][PATCHELF] in order to edit ELFs runtime paths
|
|
|
-(`RPATH`). Auxiliary tools are installed to the the user space. One can get
|
|
|
-their location with the `which` command word. For example,
|
|
|
+installed on demand during application execution. These are
|
|
|
+[appimagetool][APPIMAGETOOL], which is used to build AppImages, and
|
|
|
+[patchelf][PATCHELF], which is used to edit runtime paths (`RPATH`) in ELF
|
|
|
+files. These auxiliary tools are installed in the application cache. Their
|
|
|
+location can be found using the `which` command. For example, the command
|
|
|
|
|
|
```bash
|
|
|
python-appimage which appimagetool
|
|
|
```
|
|
|
|
|
|
-returns the location of `appimagetool`, if it has been installed. If not, the
|
|
|
-`install` command word can be used in order to trigger its installation.
|
|
|
+returns the location of [appimagetool][APPIMAGETOOL] if it has been installed.
|
|
|
+If not, the `install` command can be used to trigger its installation.
|
|
|
{{ end(".capsule") }}
|
|
|
|
|
|
|
|
|
## Manylinux Python AppImages
|
|
|
|
|
|
-AppImages of your local `python` are unlikely to be portable, except if you run
|
|
|
-an ancient Linux distribution. Indeed, a core component preventing portability
|
|
|
-across Linuses is the use of different versions of the `glibc` system library.
|
|
|
-Hopefully, `glibc` is highly backward compatible. Therefore, a simple
|
|
|
-work-around is to compile binaries using the oldest Linux distro you can afford
|
|
|
-to. This is the strategy used for creating portable AppImages, as well as for
|
|
|
-distributing Python site packages as ready-to-use binary [wheels][WHEELS].
|
|
|
+AppImages of your local `python` are unlikely to be portable, unless you are
|
|
|
+running an outdated Linux distribution. A core component that prevents
|
|
|
+portability across Linux distributions is the use of different versions of the
|
|
|
+`glibc` system library. Fortunately, `glibc` is highly backward compatible.
|
|
|
+Therefore, a simple workaround is to compile binaries using the oldest Linux
|
|
|
+distribution you can. This strategy is used to create portable AppImages and to
|
|
|
+distribute Python site packages as ready-to-use binary [wheels][WHEELS].
|
|
|
|
|
|
The Python Packaging Authority (PyPA) has defined standard platform tags for
|
|
|
-building Python site packages, labelled [manylinux][MANYLINUX]. These build
|
|
|
-platforms are available as Docker images with various versions of Python already
|
|
|
-installed. The `python-appimage` utility can be used to package those installs
|
|
|
-as AppImages. For example, the following command
|
|
|
+building Python site packages labelled [Manylinux][MANYLINUX]. These build
|
|
|
+platforms are available as Docker images, with different versions of Python
|
|
|
+already installed. The `python-appimage` utility can be used to package these
|
|
|
+installations as AppImages. For example, the following command
|
|
|
|
|
|
```bash
|
|
|
-python-appimage build manylinux 2014_x86_64 cp310-cp310
|
|
|
+python-appimage build manylinux 2014_x86_64 cp313-cp313
|
|
|
```
|
|
|
|
|
|
-should build an AppImage of Python 3.10 using the CPython (_cp310-cp310_)
|
|
|
-install found in the `manylinux2014_x86_64` Docker image.
|
|
|
+should build an AppImage of Python __3.13__ using the CPython (__cp313-cp313__)
|
|
|
+installation found in the `manylinux2014_x86_64` Docker image.
|
|
|
|
|
|
!!! Note
|
|
|
- Docker needs to be already installed on your system in order to build
|
|
|
- Manylinux Python images. However, the command above can be run on the host.
|
|
|
- That is, you need **not** to explictly shell inside the manylinux Docker
|
|
|
- image.
|
|
|
+ From version `1.4.0` of `python-appimage` onwards, Docker is **no longer**
|
|
|
+ required to build the Manylinux Python images. Cross-building is also
|
|
|
+ supported, for example producing an `aarch64` Python image from an `x86_64`
|
|
|
+ host.
|
|
|
+
|
|
|
+!!! Warning
|
|
|
+ Creating multiple Manylinux Python images can significantly increase the
|
|
|
+ size of the application cache. This can be managed using the
|
|
|
+ `python-appimage cache` command.
|
|
|
|
|
|
!!! Tip
|
|
|
- A compilation of ready-to-use Manylinux Python AppImages is available from
|
|
|
- the [releases][RELEASES] area of the `python-appimage` [GitHub
|
|
|
+ A compilation of ready-to-use Manylinux Python AppImages is available in the
|
|
|
+ [releases][RELEASES] section of the `python-appimage` [GitHub
|
|
|
repository][GITHUB]. These AppImages are updated weekly, on every Sunday.
|
|
|
|
|
|
+!!! Tip
|
|
|
+ Instead of an AppImage, the `python-appimage build manylinux` command can
|
|
|
+ produce either an `AppDir` or a bare tarball (i.e. without the AppImage
|
|
|
+ layer) of a Manylinux Python installation. See the `-b` and `-n` command
|
|
|
+ line options for more information.
|
|
|
|
|
|
## Simple packaging
|
|
|
|
|
|
-The `python-appimage` utility can also be used in order to build simple
|
|
|
-applications, that can be `pip` installed. The syntax is
|
|
|
+The `python-appimage` utility can also be used to package simple AppImage
|
|
|
+applications, whose dependencies can be installed using `pip`. The syntax is
|
|
|
|
|
|
```bash
|
|
|
-python-appimage build app -p 3.10 /path/to/recipe/folder
|
|
|
+python-appimage build app -p 3.13 /path/to/recipe/folder
|
|
|
```
|
|
|
|
|
|
-in order to build a Python 3.10 based application from a recipe folder.
|
|
|
-Examples of recipes can be found on GitHub in the [applications][APPLICATIONS]
|
|
|
-folder. The recipe folder contains:
|
|
|
+to build a Python 3.13-based application from a recipe folder. Examples of
|
|
|
+recipes can be found in the [applications][APPLICATIONS] folder on GitHub. The
|
|
|
+recipe folder contains
|
|
|
|
|
|
- the AppImage metadata (`application.xml` and `application.desktop`),
|
|
|
- an application icon (e.g. `application.png`),
|
|
|
-- a Python requirements file (`requirements.txt`)
|
|
|
+- a Python requirements file (`requirements.txt`),
|
|
|
- an entry point script (`entrypoint.sh`).
|
|
|
|
|
|
-Additional information on metadata can be found in the AppImage documentation.
|
|
|
-That is, for [desktop][APPIMAGE_DESKTOP] and [AppStream XML][APPIMAGE_XML]
|
|
|
-files. The `requirements.txt` file allows to specify additional site packages
|
|
|
-to be bundled in the AppImage, using `pip`.
|
|
|
+Further information on metadata can be found in the AppImage documentation
|
|
|
+(e.g., regarding [desktop][APPIMAGE_DESKTOP] and [AppStream XML][APPIMAGE_XML]
|
|
|
+files). The `requirements.txt` file enables additional site packages to be
|
|
|
+specified for bundling in the AppImage using `pip`.
|
|
|
|
|
|
!!! Caution
|
|
|
- For the application to be portable, site packages bundled in the AppImage,
|
|
|
- as well as their dependencies, must must be available as binary wheels, or
|
|
|
- be pure Python packages.
|
|
|
+ In order for the application to be portable, the site packages bundled in
|
|
|
+ the AppImage and their dependencies must be available as binary wheels or
|
|
|
+ pure Python packages.
|
|
|
|
|
|
- If a **C extension** is bundled from **source**, then it will likely **not
|
|
|
- be portable**, as further discussed in the [Advanced
|
|
|
+ If a **C extension** is bundled from **source**, it will likely **not be
|
|
|
+ portable**; this is discussed further in the [Advanced
|
|
|
packaging](#advanced-packaging) section.
|
|
|
|
|
|
!!! Tip
|
|
|
- Some site packages are available only for specific Manylinux tags. This can
|
|
|
- be cross-checked by browsing the `Download files` section on the package's
|
|
|
- PyPI page.
|
|
|
+ Some site packages are only available for specific Manylinux tags. You can
|
|
|
+ check this by browsing the `Download files` section on the package's PyPI
|
|
|
+ page.
|
|
|
|
|
|
!!! Tip
|
|
|
- Since version 1.2, `python-appimage` allows to specify local requirements as
|
|
|
- well, using the `local+` tag (see
|
|
|
- [PR49](https://github.com/niess/python-appimage/pull/49)). Note however that
|
|
|
- this performs a direct copy of the local package, which has several
|
|
|
- limitations.
|
|
|
+ Since version 1.2, `python-appimage` allows local requirements to be
|
|
|
+ specified using the `local+` tag (see
|
|
|
+ [PR49](https://github.com/niess/python-appimage/pull/49)). Please note,
|
|
|
+ however, that this involves directly copying the local package, which has
|
|
|
+ several limitations.
|
|
|
|
|
|
{{ begin(".capsule") }}
|
|
|
### Entry point script
|
|
|
|
|
|
{% raw %}
|
|
|
-The entry point script deserves some additional explanations. This script allows
|
|
|
-to customize the startup of your application. A typical `entrypoint.sh` script
|
|
|
-would look like
|
|
|
+The entry point script deserves some additional explanations. This script lets
|
|
|
+you customise your application's startup. A typical `entrypoint.sh` script would
|
|
|
+look like this
|
|
|
|
|
|
```bash
|
|
|
{{ python-executable }} ${APPDIR}/opt/python{{ python-version }}/bin/my_app.py "$@"
|
|
|
```
|
|
|
|
|
|
-where `my_app.py` is the application startup script, installed by `pip`. As can
|
|
|
-be seen from the previous example, the `entrypoint.sh` script recognises some
|
|
|
-particular variables, nested between double curly braces, `{{ }}`. Those
|
|
|
-variables are listed in the table hereafter. In addition, usual [AppImage
|
|
|
-environement variables][APPIMAGE_ENV] can be used as well, if needed. For
|
|
|
-example, `$APPDIR` points to the AppImage mount point at runtime.
|
|
|
+where `my_app.py` is the application startup script installed by `pip`. As can
|
|
|
+be seen from the previous example, the `entrypoint.sh` script recognises
|
|
|
+particular variables nested between double curly braces (`{{}}`). These
|
|
|
+variables are listed in the table below. In addition, the usual [AppImage
|
|
|
+environement variables][APPIMAGE_ENV] can be used if needed. For instance,
|
|
|
+`$APPDIR` points to the AppImage mount point at runtime.
|
|
|
{% endraw %}
|
|
|
|
|
|
+
|
|
|
| variable | Description |
|
|
|
|----------------------|---------------------------------------------------------------|
|
|
|
| `architecture` | The AppImage architecture, e.g. `x86_64`. |
|
|
|
@@ -173,20 +185,20 @@ example, `$APPDIR` points to the AppImage mount point at runtime.
|
|
|
|
|
|
{% raw %}
|
|
|
!!! Note
|
|
|
- By default, Python AppImages are not isolated from the user space, nor from
|
|
|
- Python specific environment variables, the like `PYTHONPATH`. Depending on
|
|
|
- your use case, this can be problematic.
|
|
|
+ By default, Python AppImages are not isolated from user space or
|
|
|
+ Python-specific environment variables such as `PYTHONPATH`. Depending on
|
|
|
+ your use case, this can cause problems.
|
|
|
|
|
|
- The runtime isolation level can be changed by adding the `-E`, `-s` or `-I`
|
|
|
- options, when invoking the runtime. For example,
|
|
|
- `{{ python-executable }} -I` starts a fully isolated Python instance.
|
|
|
+ You can change the isolation level by adding the `-E`, `-s` or `-I` options
|
|
|
+ when invoking the runtime. For example, `{{ python-executable }} -I` starts
|
|
|
+ a fully isolated Python instance.
|
|
|
{% endraw %}
|
|
|
|
|
|
### Bundling data files
|
|
|
|
|
|
-`python-appimage` is also capable of bundling in auxilliary data files directly
|
|
|
-into the resulting AppImage. `-x/--extra-data` switch exists for that task.
|
|
|
-Consider following example.
|
|
|
+`python-appimage` is also capable of bundling auxiliary data files directly into
|
|
|
+the resulting AppImage. The `-x/--extra-data` switch is used for this purpose.
|
|
|
+Consider the following example.
|
|
|
|
|
|
```bash
|
|
|
echo -n "foo" > foo
|
|
|
@@ -195,10 +207,10 @@ echo -n "baz" > bar/baz
|
|
|
python-appimage [your regular parameters] -x foo bar/*
|
|
|
```
|
|
|
|
|
|
-User data included in such a way becomes accessible to the Python code
|
|
|
-contained within the AppImage in a form of regular files under the directory
|
|
|
-pointed to by `APPDIR` environment variable. Example of Python 3 script
|
|
|
-that reads these exemplary files is presented below.
|
|
|
+In this way, user data becomes accessible to the Python code contained within
|
|
|
+the AppImage as regular files under the directory pointed to by the `APPDIR`
|
|
|
+environment variable. An example of a Python 3 script that reads these files is
|
|
|
+presented below.
|
|
|
|
|
|
```python
|
|
|
import os, pathlib
|
|
|
@@ -206,7 +218,7 @@ for fileName in ("foo", "baz"):
|
|
|
print((pathlib.Path(os.getenv("APPDIR")) / fileName).read_text())
|
|
|
```
|
|
|
|
|
|
-Above code, when executed, would print following output.
|
|
|
+When executed, the above code would produce the following output.
|
|
|
|
|
|
```bash
|
|
|
foo
|
|
|
@@ -215,37 +227,36 @@ baz
|
|
|
|
|
|
## Advanced packaging
|
|
|
|
|
|
-In more complex cases, e.g. if your application relies on external C libraries
|
|
|
-not bundled with the Python runtime, then the simple packaging scheme described
|
|
|
-previously will fail. Indeed, this falls out of the scope of `python-appimage`,
|
|
|
-whose main purpose it to relocate an existing Python install. In this case, you
|
|
|
-might rather refer to the initial AppImage [Packaging
|
|
|
-Guide][APPIMAGE_PACKAGING], and use alternative tools like
|
|
|
+In more complex cases, for example if your application relies on external C
|
|
|
+libraries that are not bundled with the Python runtime, the simple packaging
|
|
|
+scheme described previously will not work. This falls outside the scope of
|
|
|
+`python-appimage`, which is primarily intended for relocating an existing Python
|
|
|
+installation. In this case, you may wish to refer to the initial AppImage
|
|
|
+[Packaging Guide][APPIMAGE_PACKAGING], and use alternative tools such as
|
|
|
[linuxdeploy][LINUXDEPLOY].
|
|
|
|
|
|
-However, `python-appimage` can still be of use in more complex cases by
|
|
|
-extracting its AppImages to an AppDir, as discussed in the [Advanced
|
|
|
-installation](index.md#advanced-installation) section. The extracted AppImages
|
|
|
-contain a relocatable Python runtime, that can be used as a starting base for
|
|
|
-building more complex AppImages.
|
|
|
+However, `python-appimage` can still be useful in more complex cases, as it can
|
|
|
+generate a base AppDir containing a relocatable Python runtime (e.g., using the
|
|
|
+`-n` option). This can then serve as a starting point to create more complex
|
|
|
+AppImages.
|
|
|
|
|
|
!!! Tip
|
|
|
- In some cases, a simple workaround to missing external libraries can be to
|
|
|
- fetch portable versions of those from a Manylinux distro, and to bundle them
|
|
|
- under `AppDir/usr/lib`. You might also need to edit their dynamic section,
|
|
|
- e.g. using [`patchelf`][PATCHELF], which is installed by `python-appimage`.
|
|
|
+ In some cases, a simple workaround for missing external libraries is to
|
|
|
+ download portable versions of them from a Manylinux distribution and bundle
|
|
|
+ them in `AppDir/usr/lib`. You may also need to edit the dynamic section
|
|
|
+ using [`patchelf`][PATCHELF], which is installed by `python-appimage`.
|
|
|
|
|
|
|
|
|
{{ begin(".capsule") }}
|
|
|
### C extension modules
|
|
|
|
|
|
-If your application relies on C extension modules, they need to be compiled on a
|
|
|
-Manylinux distro in order to be portable. In addition, their dependencies need
|
|
|
-to be bundled as well. In this case, you might better start by building a binary
|
|
|
-wheel of your package, using tools like [Auditwheel][AUDITWHEEL] which can
|
|
|
-automate some parts of the packaging process. Note that `auditwheel` is already
|
|
|
+If your application relies on C extension modules, these must be compiled on a
|
|
|
+Manylinux distribution in order to be portable. Their dependencies also need to
|
|
|
+be bundled. In this case, it would be better to start by building a binary wheel
|
|
|
+of your package using tools like [Auditwheel][AUDITWHEEL], which can automate
|
|
|
+some parts of the packaging process. Please note that `auditwheel` is already
|
|
|
installed on the Manylinux Docker images.
|
|
|
|
|
|
-Once you have built a binary wheel of your package, it can be used with
|
|
|
-`python-appimage` in order to package your application as an AppImage.
|
|
|
+Once you have built a binary wheel of your package, you can use it with
|
|
|
+`python-appimage` to package your application as an AppImage.
|
|
|
{{ end(".capsule") }}
|