openwrt-packages/lang/python
Hannu Nyman d6583e3d66
Merge pull request #11582 from jefferyto/python-zope-interface-4.7.2
python-zope-interface: Update to 4.7.2, refresh patch
2020-03-16 20:45:44 +02:00
..
Flask treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
Jinja2 Jinja2: update to version 2.10.3 2020-01-19 14:26:39 +01:00
MarkupSafe treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
Werkzeug treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
bcrypt treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
click treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
click-log click-log: fix circular dependency 2019-03-13 14:34:49 -03:00
django django: bump to version 3.0.4 2020-03-10 14:11:48 +02:00
django-appconf django-appconf: Update to 1.0.3 2020-03-14 04:35:00 +08:00
django-compressor django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-constance django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-formtools django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-jsonfield django-jsonfield: Change packaged project 2020-03-14 04:35:00 +08:00
django-picklefield django-picklefield: Update to 2.1.1 2020-03-14 04:35:00 +08:00
django-postoffice django-postoffice: Update to 3.2.1 2020-03-14 04:35:00 +08:00
django-ranged-response django-ranged-response: Fix project URL 2020-03-14 04:35:00 +08:00
django-restframework django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-restframework39 django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-simple-captcha django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django-statici18n django-statici18n: Update to 1.9.0, add missing dependencies 2020-03-14 04:35:00 +08:00
django-webpack-loader django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
django1 django1: Fix byte-compiled db migrations not loaded 2020-03-14 04:35:00 +08:00
flup treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
gunicorn python-packages: Clean up Makefiles 2020-01-30 22:44:26 +08:00
itsdangerous treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
micropython micropython: Update to 1.94 2018-10-06 11:52:51 -07:00
micropython-lib micropython-lib: Update to 1.9.3 2018-10-07 06:03:34 -07:00
openpyxl treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
passlib passlib: Update passlib to 1.7.2 2019-12-28 01:48:35 -05:00
pillow treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
pyjwt treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
pymysql pymysql: make python3-cryptography optional 2020-01-29 09:30:59 +02:00
pyodbc treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python python: Fix float byte order detection 2020-01-30 18:28:49 +08:00
python-aiohttp python-aiohttp: update to version 3.6.1 2020-01-19 14:17:07 +01:00
python-aiohttp-cors treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-appdirs treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-asn1crypto python-asn1crypto: bump to version 1.3.0 + rework 2020-01-06 15:45:14 +02:00
python-astral treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-async-timeout treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-atomicwrites python-atomicwrites: add new package 2019-11-01 10:45:53 +01:00
python-attrs treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-automat python-automat: Update to 20.2.0, refresh patches 2020-02-24 04:41:16 +08:00
python-awscli treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-boto3 treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-botocore treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-cachelib treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-cachetools treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-certifi python-certify: bump to 2019.11.28 2020-01-17 10:58:00 -03:00
python-cffi python-cffi: Update to 1.14.0 2020-02-12 13:40:21 +08:00
python-chardet treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-colorama treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-constantly treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-contextlib2 treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-crcmod treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-crypto treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-cryptodome treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-cryptodomex treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-cryptography treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-curl python-curl: update to version 7.43.0.5 2020-02-05 08:39:56 +01:00
python-dateutil python-dateutil: bump to version 2.8.1 2019-11-19 10:47:02 +02:00
python-decorator treewide: add PKG_CPE_ID for cvescanner 2019-09-24 13:51:22 +02:00
python-defusedxml treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-dns treewide: add PKG_CPE_ID for cvescanner 2019-09-24 13:51:22 +02:00
python-docutils treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-dpkt treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-egenix-mx-base python-egenix-mx-base: Makefile polishing 2019-07-17 07:34:41 +02:00
python-enum34 python-enum34: Update to 1.1.10, refresh patch 2020-03-17 01:49:24 +08:00
python-et_xmlfile treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-evdev python-evdev: bump to version 1.3.0 2020-01-13 09:49:23 +02:00
python-flask-login python-flask-login: update to version 0.5.0 2020-02-19 11:27:08 +01:00
python-futures treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-gmpy2 treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-gnupg treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-hyperlink treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-idna python-idna: Update to 2.9 2020-02-24 04:45:09 +08:00
python-ifaddr treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-incremental treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-influxdb treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-intelhex treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-ipaddress treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-jdcal treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-jmespath treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-jsonpath-ng treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-ldap treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-libmodbus python-libmodbus: update to version 0.5.0 2020-02-11 16:37:01 +02:00
python-lxml python-lxml: bump to version 4.4.2 2019-12-09 09:36:03 +02:00
python-markdown python-markdown: update to version 3.2.1 2020-02-17 21:59:03 +01:00
python-more-itertools python-more-itertools: update to version 8.2.0 2020-02-19 15:01:26 +01:00
python-multidict treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-mysqlclient python-mysqlclient: bump to version 1.4.6 2019-11-28 08:51:20 +02:00
python-netdisco treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-oauthlib treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-packages python-packages: strip quotes around index-url 2019-05-10 16:49:51 +08:00
python-paho-mqtt python-paho-mqtt: Update to version 1.5.0 2019-11-11 23:07:55 +01:00
python-parsley treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-pcapy treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-pip-conf python-pip-conf: split package away from python package 2017-12-10 19:49:23 +02:00
python-ply treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-psycopg2 treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-py python-py: update to version 1.8.1 2020-02-13 12:28:48 +01:00
python-pyasn1 python-pyasn1: Update to 0.4.8 2019-11-18 04:04:35 +08:00
python-pyasn1-modules python-pyasn1-modules: Update to 0.2.8 2020-01-15 05:06:21 +08:00
python-pycparser python-pycparser: Update to 2.20 2020-03-16 22:46:25 +08:00
python-pyopenssl python-pyopenssl: Update to 19.1.0 2019-11-25 03:23:26 +08:00
python-pyotp pyotp: update to version 2.3.0 2020-01-20 20:44:51 +01:00
python-pyparsing python-pyparsing: update to version 2.4.6 2020-02-19 15:40:35 +01:00
python-pyptlib treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-pyrsistent treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-pyserial treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-pytz treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-qrcode treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-rcssmin treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-requests python-requests: update to version 2.23.0 2020-03-02 16:10:46 +01:00
python-requests-oauthlib python-requests-oauthlib: bump to 1.3.0 2019-11-11 08:18:07 -03:00
python-rsa treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-s3transfer treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-schedule treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-schema python-schema: update to version 0.7.1 2019-09-16 14:00:43 +02:00
python-sentry-sdk python-sentry-sdk: Update to version 0.13.5 2019-12-09 04:09:19 +01:00
python-service-identity treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-simplejson python-simplejson: bump to version 3.17.0 2019-11-28 10:53:07 +02:00
python-six python-six: Update to 1.14.0 2020-01-20 23:38:56 +08:00
python-slugify python-slugify: update to version 4.0.0 2020-01-19 14:34:31 +01:00
python-sqlalchemy python-sqlalchemy: update to version 1.3.13 2020-01-27 14:23:07 +01:00
python-stem python-stem: add a new package 2020-02-17 20:50:26 +01:00
python-twisted python-twisted: Update to 19.10.0, refresh patches 2019-11-18 04:33:26 +08:00
python-txsocksx treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-urllib3 python-urllib3: Update to version 1.25.7 2019-12-18 21:46:08 +01:00
python-voluptuous treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-voluptuous-serialize python-voluptuous-serialize: update to version 2.3.0 2020-01-20 19:47:21 +01:00
python-wcwidth python-wcwidth: update to version 0.1.8 2020-02-18 15:04:28 -08:00
python-yaml python-yaml: update to version 5.3 2020-01-20 19:52:16 +01:00
python-yarl treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python-zeroconf python-zeroconf: update to version 0.24.4 2020-01-25 10:17:00 +01:00
python-zipp python-zipp: update to version 3.0.0 2020-02-26 16:02:49 +01:00
python-zope-interface python-zope-interface: Update to 4.7.2, refresh patch 2020-03-17 02:04:38 +08:00
python3 python3: Fix compilation without deprecated APIs 2020-01-14 14:43:58 -08:00
python3-asgiref python3-asgiref: update to 3.2.5 2020-03-11 19:26:52 +01:00
python3-bottle treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
python3-django-cors-headers django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
python3-django-etesync-journal django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
python3-drf-nested-routers django1: Add python3-django1 package 2020-02-13 15:29:59 +08:00
python3-maxminddb python-maxminddb: update to version 1.5.2 2020-01-23 12:01:30 +01:00
python3-netifaces python-packages: Clean up Makefiles 2020-01-30 22:44:26 +08:00
python3-packages python3-packages: port from python-packages 2019-05-10 16:49:51 +08:00
python3-pyroute2 python-packages: Clean up Makefiles 2020-01-30 22:44:26 +08:00
python3-speedtest-cli python3-speedtest-cli: a new package 2020-01-25 03:46:08 +05:30
python3-sqlparse python3-sqlparse: update to 0.3.1 2020-03-11 19:21:26 +01:00
python3-unidecode python-packages: Clean up Makefiles 2020-01-30 22:44:26 +08:00
ruamel-yaml treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
text-unidecode python-text-unidecode: update to version 1.3 2020-01-20 20:40:10 +01:00
vobject treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
xmltodict treewide: Use pypi.mk for Python packages 2019-10-30 23:16:18 +08:00
README.md python: readme: drop from table of contents removed sections 2020-01-27 14:26:07 +01:00
pypi.mk python,python3: Add PYPI_SOURCE_NAME to pypi.mk 2019-10-21 15:27:04 +02:00
python-host.mk python,python3: Update host pip[3] install functions 2019-05-29 21:45:16 +08:00
python-package-install.sh python,python3: add Py[3]Shebang functions & move outside of script 2019-09-20 14:10:00 +03:00
python-package.mk python,python3: add Py[3]Shebang functions & move outside of script 2019-09-20 14:10:00 +03:00
python-version.mk python: Update to 2.7.17, refresh patches 2019-10-21 23:30:53 +08:00
python3-host.mk python,python3: Update host pip[3] install functions 2019-05-29 21:45:16 +08:00
python3-package.mk python,python3: add Py[3]Shebang functions & move outside of script 2019-09-20 14:10:00 +03:00
python3-version.mk python3: Updated to version 3.8.1 2019-12-21 20:04:30 +01:00

README.md

Python packages folder

⚠️ Python 2 will soon be unsupported and removed from the feed - see below ⚠️

Table of contents

  1. Description
  2. Python 2 end-of-life
    1. Transition policy / schedule
  3. Introduction
  4. Using Python[3] in external/other package feeds
  5. Build considerations
  6. General folder structure
  7. Building a Python[3] package
    1. Include python[3]-package.mk
    2. Add Package/<PKG_NAME> OpenWrt definitions
    3. Wrapping things up so that they build
    4. Customizing things
    5. Host-side Python packages for build

Description

This section describes specifics for the Python packages that are present in this repo, and how things are structured.

In terms of license, contributing guide, etc, all of that information is described in the top README.md file, and it applies here as well. This document attempts to cover only technical aspects of Python/Python3 packages, and maybe some explanations about how things are (and why they are as they are).

Python 2 end-of-life

Python 2 will not be maintained past 1 January 2020. As such, we will be transitioning Python 2 programs and libraries to Python 3, and Python 2 packages will be removed in early 2020.

(Discussion for how to handle this transition can be found in #8520.)

Transition policy / schedule

A mass removal event ("The Snap") will occur on 31 March 2020, or 2 weeks before the freeze for a 20.x release, whichever is sooner. The exact date will be confirmed when the 20.x release schedule is known, or by 15 March 2020.

All Python 2 packages (the Python 2 interpreter, programs that depend on Python 2, and Python 2-only libraries) will be removed during this event.

Leading up to "The Snap":

  • In general, new Python 2 packages are no longer accepted

    • Exceptions can be made on a case-by-case basis, given extraordinary circumstances or reasons, until 31 May 2019
    • From 31 May 2019 onward, absolutely no new Python 2 packages will be accepted
  • The Python 2 interpreter will remain in the feed until "The Snap"

    • The interpreter will continue to be updated, including the last release in January 2020 (if there is one)
  • Programs that depend on Python 2 will be transitioned to Python 3 (see #8893)

    • If a program cannot be transitioned, a suitable replacement will be found
    • If a replacement cannot be found, the program will be removed during "The Snap"
  • Python 2 libraries will remain in the feed until "The Snap"

    • For any Python 2-only libraries, a Python 3 version will be added (or a suitable replacement found), if its Python 3 version is a dependency of another package in the feed
    • Python 2 libraries will receive normal updates until 31 October 2019
    • From 31 October 2019 onward:
      • Python 2-only libraries will receive security updates only
      • Python 2 libraries that share the same Makefile as their Python 3 version will continue to receive normal updates

Introduction

This sub-tree came to exist after a number of contributions (Python packages) were made to this repo, and the lang subtree grew to a point where a decision was made to move all Python packages under lang/python.

It contains the 2 Python interpreters (Python & Python3) and Python packages. Most of the Python packages are downloaded from pypi.org. Python packages from pypi.org are typically preferred when adding new packages.

If more packages (than the ones packaged here) are needed, they can be downloaded via pip or pip3. Note that the versions of pip & setuptools [available in this repo] are the ones that are packaged inside the Python & Python3 packages (yes, Python & Python3 come packaged with pip & setuptools).

Using Python[3] in external/other package feeds

In the feeds.conf (or feeds.conf.default file, whatever is preferred), the packages repo should be present.

Example

src-git packages https://git.openwrt.org/feed/packages.git
src-git luci https://git.openwrt.org/project/luci.git
src-git routing https://git.openwrt.org/feed/routing.git
src-git telephony https://git.openwrt.org/feed/telephony.git
#
#
src-git someotherfeed https://github.com/<github-user>/<some-other-package>

Assuming that there are Python packages in the <some-other-package>, they should include python[3]-package.mk like this:

include $(TOPDIR)/feeds/packages/lang/python/python-package.mk
include $(TOPDIR)/feeds/packages/lang/python/python3-package.mk

Same rules apply for python[3]-package.mk as the Python packages in this repo. And if only 1 of python-package.mk or python3-package.mk is needed, then only the needed mk file should be included (though it's not an issue if both are included).

One important consideration:: if the local name is not packages, it's something else, like openwrt-packages. And in feeds.conf[.default] it's:

src-git openwrt-packages https://git.openwrt.org/feed/packages.git

Then, the inclusions also change:

include $(TOPDIR)/feeds/openwrt-packages/lang/python/python-package.mk
include $(TOPDIR)/feeds/openwrt-packages/lang/python/python3-package.mk

Each maintainer[s] of external packages feeds is responsible for the local name, and relative inclusion path back to this feed (which is named packages by default).

In case there is a need/requirement such that the local package feed is named something else than packages, one approach to make the package flexible to change is:

PYTHON_PACKAGE_MK:=$(wildcard $(TOPDIR)/feeds/*/lang/python/python-package.mk)

# verify that there is only one single file returned
ifneq (1,$(words $(PYTHON_PACKAGE_MK)))
ifeq (0,$(words $(PYTHON_PACKAGE_MK)))
$(error did not find python-package.mk in any feed)
else
$(error found multiple python-package.mk files in the feeds)
endif
else
$(info found python-package.mk at $(PYTHON_PACKAGE_MK))
endif

include $(PYTHON_PACKAGE_MK)

Same can be done for python3-package.mk. This should solve the corner-case where the python[3]-package.mk can be in some other feed, or if the packages feed will be named something else locally.

Build considerations

In order to build the Python[3] interpreters, a host Python/Python3 interpreter needs to be built, in order to process some of the build for the target Python/Python3 build. The host Python[3] interpreters are also needed so that Python bytecodes are generated, so the host interpreters need to be the exact versions as on the target. And finally, the host Python[3] interpreters also provide pip & pip3, so that they may be used to install some Python[3] packages that are required to build other Python[3] packages. That's why you'll also see a Python/Python3 build & staging directories.

As you're probably thinking, this sounds [and is] somewhat too much complication [just for packaging], but the status of things is-as-it-is, and it's probably much worse than what's currently visible on the surface [with respect to packaging Python[3] & packages].

As mentioned earlier, Python[3] packages are shipped with bytecodes, and the reason for this is simply performance & size. The thought/discussion matrix derives a bit like this:

  • shipping both Python source-code & bytecodes takes too much space on some devices ; Python source code & byte-code take about similar disk-size
  • shipping only Python source code has a big performance penalty [on some lower end systems] ; something like 500 msecs (Python source-only) -> 70 msecs (Python byte-codes) time reduction for a simple "Hello World" script
  • shipping only Python byte-codes seems like a good trade-off, and this means that python-src & python3-src can be provided for people that want the source code

By default, automatic Python[3] byte-code generation is disabled when running a Python script, in order to prevent a disk from accidentally filling up. Since some disks reside in RAM, this also means not filling up the RAM. If someone wants to convert Python source to byte-code then he/she is free to compile it [directly on the device] manually via the Python interpreter & library.

General folder structure

The basis of all these packages are:

These 2 are normal OpenWrt packages, which will build the Python interpreters. They also provide python[3]-pip & python[3]-setuptools. Each Python or Python3 package is actually split into multiple sub-packages [e.g. python-email, python-sqlite3, etc]. This can be viewed inside lang/python/python/files & lang/python/python3/files.

The reason for this splitting, is purely to offer a way for some people to package Python/Python3 in as-minimal-as-possible-and-still-runable way, and also to be somewhat maintainable when packaging. A standard Python[3] installation can take ~20-30 MBs of disk, which can be somewhat big for some people, so there are the python[3]-base packages which bring that down to ~5 MBs. This seems to be good enough (and interesting) for a number of people.

The Python[3] interpreters are structured like this:

  • python-base (and python3-base), which is just the minimal package to startup Python[3] and run basic commands
  • python (and python3) are meta-packages, which install almost everything (python[3]-base [plus] Python[3] library [minus] some unit-tests & some windows-y things)
  • python-light (and python3-light) are python (and python3) [minus] packages that are in lang/python/python/files or lang/python/python3/files ; the size of these 2 packages may be sensible (and interesting) to another group of people

All other Python & Python3 packages (aside from the 2 intepreters) typically use these files:

  • python[3]-host.mk - this file contains paths and build rules for running the Python[3] interpreters on the host-side; they also provide paths to host interprete, host Python lib-dir & so on
  • python[3]-package.mk
    • includes python[3]-host.mk
    • contains all the default build rules for Python[3] packages; these will be detailed below in the [Building a Python[3] package](#Building a Python[3] package) section

Note that Python/Python3 packages don't need to use these files (i.e. python[3]-package.mk & python[3]-host.mk), but they do provide some ease-of-use & reduction of duplicate code, especially when packaging for both Python & Python3. And they do contain some learned-lessons about packaging Python/Python3 packages, so it's a good idea to use them.

Building a Python[3] package

A Python package can be packaged for either Python or Python3 or both.

This section will describe both, and then it can be inferred which is for which.

Packaging for both Python & Python3 uses the VARIANT mechanism for packaging inside OpenWrt. (#### FIXME: find a link for this later if it exists)

Include python[3]-package.mk

If packaging for Python, add this after include $(INCLUDE_DIR)/package.mk

include ../python-package.mk

If packaging for Python3, add this after include $(INCLUDE_DIR)/package.mk

include ../python3-package.mk

Order doesn't matter between python-package.mk & python3-package.mk.

These will make sure that build rules for Python or Python3 can be specified and picked up for build.

Include pypi.mk (optional)

If the package source code will be downloaded from pypi.org, including pypi.mk can help simplify the package Makefile.

To use pypi.mk, add this before include $(INCLUDE_DIR)/package.mk:

include ../pypi.mk

pypi.mk has several PYPI_* variables that must/can be set (see below); these should be set before pypi.mk is included, i.e. before the include ../pypi.mk line.

pypi.mk also provides default values for PKG_SOURCE and PKG_SOURCE_URL, so these variables may be omitted.

One variable is required:

  • PYPI_NAME: Package name on pypi.org. This should match the PyPI name exactly.

    For example (from the python-yaml package):

    PYPI_NAME:=PyYAML
    

These variables are optional:

  • PYPI_SOURCE_NAME: Package name component of the source tarball filename
    Default: Same value as PYPI_NAME

  • PYPI_SOURCE_EXT: File extension of the source tarball filename
    Default: tar.gz

pypi.mk constructs the default PKG_SOURCE value from these variables (and PKG_VERSION):

PKG_SOURCE?=$(PYPI_SOURCE_NAME)-$(PKG_VERSION).$(PYPI_SOURCE_EXT)

The PYPI_SOURCE_* variables allow this default PKG_SOURCE value to be customized as necessary.

Add Package/<PKG_NAME> OpenWrt definitions

This part is similar to default OpenWrt packages. It's usually recommended to have a Package/<PKG_NAME>/Default section that's common for both Python & Python3.

Example:

define Package/python-lxml/Default
  SECTION:=lang
  CATEGORY:=Languages
  SUBMENU:=Python
  URL:=https://lxml.de
  DEPENDS:=+libxml2 +libxslt +libexslt
endef

Then for each variant do something like:

define Package/python-lxml
$(call Package/python-lxml/Default)
  TITLE:=python-lxml
  DEPENDS+=+PACKAGE_python-lxml:python-light +PACKAGE_python-lxml:python-codecs
  VARIANT:=python
endef

define Package/python3-lxml
$(call Package/python-lxml/Default)
  TITLE:=python3-lxml
  DEPENDS+=+PACKAGE_python3-lxml:python3-light
  VARIANT:=python3
endef

Some considerations here (based on the example above):

  • be sure to make sure that DEPENDS are correct for both variants; as seen in the example above, python-codecs is needed only for python-lxml (see note-encodings)
  • consider adding conditional DEPENDS for each variant ; so for each Python[3] package add +PACKAGE_python-lxml:<dep> as seen in the above example ; the reason for this is build-time reduction ; if you want to build Python3 only packages, this won't build Python & Python packages + dependencies ; this is a known functionality of OpenWrt build deps
    • this should not happen anymore, but if adding +PACKAGE_python-lxml conditional deps creates circular dependencies, then open an issue so this can be resolved again.
  • VARIANT=python or VARIANT=python3 must be added
  • typically each variant package is named Package/python-<something> & Package/python3-<something> ; this convention makes things easier to follow, though it could work without naming things this way
  • TITLE can be something a bit more verbose/neat ; typically the name is short as seen above

note-encodings: That's because some character encodings are needed, which are present in python3-base but not in python-light (but are present in python-codecs) ; this is because Python3 is designed to be more Unicode friendly than Python2 (it's one of the fundamental differences between the 2), and Python3 won't start without those encodings being present.

Following these, 2 more definitions are required:

define Package/python-lxml/description
The lxml XML toolkit is a Pythonic binding
for the C libraries libxml2 and libxslt.
endef

define Package/python3-lxml/description
$(call Package/python-lxml/description)
.
(Variant for Python3)
endef

Typically, the description is the same for both, so just mentioning that one is a variant of the other is sufficient.

Wrapping things up so that they build

If all the above prerequisites have been met, all that's left is:

$(eval $(call PyPackage,python-lxml))
$(eval $(call BuildPackage,python-lxml))

$(eval $(call Py3Package,python3-lxml))
$(eval $(call BuildPackage,python3-lxml))

The $(eval $(call PyPackage,python-lxml)) part will instantiate all the default Python build rules so that the final Python package is packaged into an OpenWrt. And $(eval $(call BuildPackage,python-lxml)) will bind all the rules generated with $(eval $(call PyPackage,python-lxml)) into the OpenWrt build system.

These packages will contain byte-codes and binaries (shared libs & other stuff).

If a user wishes to ship source code, adding 2 more lines creates 2 more packages that ship Python source code:

$(eval $(call PyPackage,python-lxml))
$(eval $(call BuildPackage,python-lxml))
$(eval $(call BuildPackage,python-lxml-src))

$(eval $(call Py3Package,python3-lxml))
$(eval $(call BuildPackage,python3-lxml))
$(eval $(call BuildPackage,python3-lxml-src))

The name *-src must be the Python package name; so for python-lxml-src a equivalent python-lxml name must exist.

Customizing things

Some packages need custom build rules (because they do).

The default package build and install processes are defined in python[3]-package.mk.

Building

The default build process calls setup.py install inside the directory where the Python source package is extracted (PKG_BUILD_DIR). This "installs" the Python package to an intermediate location (PKG_INSTALL_DIR) where it is used by the default install process.

There are several Makefile variables that can be used to customize this process (all optional):

  • PYTHON_PKG_SETUP_DIR / PYTHON3_PKG_SETUP_DIR: Path where setup.py can be found, relative to the package directory (PKG_BUILD_DIR).
    Default: empty value (setup.py is in the package directory)
  • PYTHON_PKG_SETUP_VARS / PYTHON3_PKG_SETUP_VARS: Additional environment variables to set for the call to setup.py. Should be in the form of VARIABLE1=value VARIABLE2=value ....
    Default: empty value
  • PYTHON_PKG_SETUP_GLOBAL_ARGS / PYTHON3_PKG_SETUP_GLOBAL_ARGS: Additional command line arguments to pass to setup.py, before / in front of the install command.
    Default: empty value
  • PYTHON_PKG_SETUP_ARGS / PYTHON3_PKG_SETUP_ARGS: Additional command line arguments to pass to setup.py, after the install command.
    Default: --single-version-externally-managed

Conceptually, these variables are used in this way (using a Python 2 package as an example):

cd $(PKG_BUILD_DIR)/$(PYTHON_PKG_SETUP_DIR)
$(PYTHON_PKG_SETUP_VARS) python setup.py $(PYTHON_PKG_SETUP_GLOBAL_ARGS) install $(PYTHON_PKG_SETUP_ARGS)

The default build process can be completely overridden by defining custom PyBuild/Compile & Py3Build/Compile rules in the package Makefile.

Installing

The default install process copies some/all of the files from PKG_INSTALL_DIR, placed there by the build process, to a location passed to the install rule as the first argument ($(1)). The OpenWrt build system will then take those files and create the actual .ipk package archives.

This default process uses 2 build rules:

  • PyPackage/<package>/filespec & Py3Package/<package>/filespec which are Python library files relative to /usr/lib/pythonX.Y ; by default this is /usr/lib/python$(PYTHON[3]_VERSION)/site-packages (PYTHON[3]_PKG_DIR) ; most Python[3] packages generate files that get installed in this sub-folder
  • PyPackage/<package>/install & Py3Package/<package>/install is similar to Package/<package>/install ; these allow binary (or other files) to be installed on the target

Both the 2 above rules generate a Package/<package>/install build rule, which gets picked up by the build system. Both can be used together (they are not mutually exclusive), and provide a good enough flexibility for specifying Python[3] packages.

The PyPackage/<package>/filespec & Py3Package/<package>/filespec rules contain one or more lines of the following format (whitespace added for clarity):

<one of: +-=> | <file/directory path> | <file permissions>

The initial character controls the action that will be taken:

  • +: Install the given path. If the path is a directory, all files and subdirectories inside are installed.
    • If file permissions is specified (optional), then the file or directory (and all files and subdirectories) are assigned the given permissions; if omitted, then the file or directory retains its original permissions.
  • -: Remove the given path. Useful when most of a directory should be installed except for a few files or subdirectories.
    • File permissions is not used / ignored in this case.
  • =: Assign the given file permissions to the given path. File permissions is required in this case.

As mentioned, the default PyPackage/<package>/filespec & Py3Package/<package>/filespec install PYTHON[3]_PKG_DIR:

define PyPackage/python-example/filespec
+|$(PYTHON_PKG_DIR)
endef

If the package installs a example_package directory inside PYTHON_PKG_DIR, and there is an examples directory and test_*.py files that can be omitted to save space, this can be specified as:

define PyPackage/python-example/filespec
+|$(PYTHON_PKG_DIR)
-|$(PYTHON_PKG_DIR)/example_package/examples
-|$(PYTHON_PKG_DIR)/example_package/test_*.py
endef

Host-side Python packages for build

These can be installed via pip and ideally they should only be installed like this, because it's a bit simpler than running them through the OpenWrt build system. Build variants on the host-side build are more complicated (and nearly impossible to do sanely) in the current OpenWrt build system.

Which is why [for example] if you need python cffi on the host build, it's easier to just add it via:

HOST_PYTHON_PACKAGE_BUILD_DEPENDS:="cffi==$(PKG_VERSION)"
HOST_PYTHON3_PACKAGE_BUILD_DEPENDS:="cffi==$(PKG_VERSION)"

[cffi is one of those packages that needs a host-side package installed for both Python & Python3].

This works reasonably well in the current OpenWrt build system, as binaries get built for this package and get installed in the staging-dir $(STAGING_DIR)/usr/lib/pythonX.Y/site-packages.