kumquat-buildroot/package/pkg-python.mk
James Hilliard 8937db8dd5 package/pkg-python.mk: migrate setuptools to pep517
Now that setuptools and its dependencies are using pep517 we can
migrate the setuptools infrastructure itself to use the pep517
build frontend.

As part of this we need to migrate the all python packages using
_BUILD_OPTS to the new config settings format used by the pep517
build frontend.

We need to use a setup.cfg file to pass the pg_config path when
building python-psycopg2 as this package needs the pg_config
path for all internal build stages while -C--build-option= only
passes the flag to the internal bdist_wheel stage.

Use new setup type variables to define setup type specific
dependencies instead of using the conditional block.

In python-m2crypto, the --openssl option is a build_ext option
so we need to add -C--build-option build_ext in front of it.

We also need to set --skip-dependency-check for the following
packages which specify build dependencies that are not actually
required:
 - python-lxml
 - python-matplotlib
 - python-msgpack
 - python-pymupdf
 - python-uvloop
 - python-wsaccel

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Reviewed-by: Yegor Yefremov <yegorslists@googlemail.com>
[Arnout: fix indentation in python-pyzmq]
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
2024-04-01 22:12:57 +02:00

418 lines
12 KiB
Makefile

################################################################################
# Python package infrastructure
#
# This file implements an infrastructure that eases development of
# package .mk files for Python packages. It should be used for all
# packages that use Python setup.py/setuptools as their build system.
#
# See the Buildroot documentation for details on the usage of this
# infrastructure
#
# In terms of implementation, this Python infrastructure requires the
# .mk file to only specify metadata information about the package:
# name, version, download URL, etc.
#
# We still allow the package .mk file to override what the different
# steps are doing, if needed. For example, if <PKG>_BUILD_CMDS is
# already defined, it is used as the list of commands to perform to
# build the package, instead of the default Python behaviour. The
# package can also define some post operation hooks.
#
################################################################################
ifeq ($(BR2_arm)$(BR2_armeb),y)
PKG_PYTHON_ARCH = arm
else
PKG_PYTHON_ARCH = $(ARCH)
endif
PKG_PYTHON_HOST_PLATFORM = linux-$(PKG_PYTHON_ARCH)
# basename does not evaluate if a file exists, so we must check to ensure
# the _sysconfigdata__linux_*.py file exists. The "|| true" is added to return
# an empty string if the file does not exist.
PKG_PYTHON_SYSCONFIGDATA_PATH = $(PYTHON3_PATH)/_sysconfigdata__linux_*.py
PKG_PYTHON_SYSCONFIGDATA_NAME = `{ [ -e $(PKG_PYTHON_SYSCONFIGDATA_PATH) ] && basename $(PKG_PYTHON_SYSCONFIGDATA_PATH) .py; } || true`
# Target python packages
PKG_PYTHON_ENV = \
_PYTHON_HOST_PLATFORM="$(PKG_PYTHON_HOST_PLATFORM)" \
_PYTHON_PROJECT_BASE="$(PYTHON3_DIR)" \
_PYTHON_SYSCONFIGDATA_NAME="$(PKG_PYTHON_SYSCONFIGDATA_NAME)" \
PATH=$(BR_PATH) \
$(TARGET_CONFIGURE_OPTS) \
PYTHONPATH="$(PYTHON3_PATH)" \
PYTHONNOUSERSITE=1 \
_python_sysroot=$(STAGING_DIR) \
_python_prefix=/usr \
_python_exec_prefix=/usr
# Host python packages
HOST_PKG_PYTHON_ENV = \
PATH=$(BR_PATH) \
PYTHONNOUSERSITE=1 \
$(HOST_CONFIGURE_OPTS)
# Target pep517-based packages
PKG_PYTHON_PEP517_ENV = \
$(PKG_PYTHON_ENV)
PKG_PYTHON_PEP517_BUILD_CMD = \
-m build -n -w
PKG_PYTHON_PEP517_INSTALL_OPTS = \
--interpreter=/usr/bin/python \
--script-kind=posix
PKG_PYTHON_PEP517_INSTALL_TARGET_CMD = \
$(TOPDIR)/support/scripts/pyinstaller.py \
dist/* \
$(PKG_PYTHON_PEP517_INSTALL_OPTS) \
--purelib=$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
--headers=$(TARGET_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \
--scripts=$(TARGET_DIR)/usr/bin \
--data=$(TARGET_DIR)/usr
PKG_PYTHON_PEP517_INSTALL_STAGING_CMD = \
$(TOPDIR)/support/scripts/pyinstaller.py \
dist/* \
$(PKG_PYTHON_PEP517_INSTALL_OPTS) \
--purelib=$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
--headers=$(STAGING_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \
--scripts=$(STAGING_DIR)/usr/bin \
--data=$(STAGING_DIR)/usr
PKG_PYTHON_PEP517_DEPENDENCIES = \
host-python-pypa-build \
host-python-installer
# Host pep517-based packages
HOST_PKG_PYTHON_PEP517_ENV = \
$(HOST_PKG_PYTHON_ENV)
HOST_PKG_PYTHON_PEP517_BUILD_CMD = \
-m build -n -w
HOST_PKG_PYTHON_PEP517_INSTALL_CMD = \
$(TOPDIR)/support/scripts/pyinstaller.py \
dist/* \
--interpreter=$(HOST_DIR)/bin/python \
--script-kind=posix \
--purelib=$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
--headers=$(HOST_DIR)/include/python$(PYTHON3_VERSION_MAJOR) \
--scripts=$(HOST_DIR)/bin \
--data=$(HOST_DIR)
# Target setuptools-based packages
PKG_PYTHON_SETUPTOOLS_ENV = \
$(PKG_PYTHON_PEP517_ENV)
PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
$(PKG_PYTHON_PEP517_BUILD_CMD)
PKG_PYTHON_SETUPTOOLS_INSTALL_OPTS = \
--install-headers=/usr/include/python$(PYTHON3_VERSION_MAJOR) \
--prefix=/usr \
--executable=/usr/bin/python \
--single-version-externally-managed
PKG_PYTHON_SETUPTOOLS_INSTALL_TARGET_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
PKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
PKG_PYTHON_SETUPTOOLS_DEPENDENCIES = \
$(PKG_PYTHON_PEP517_DEPENDENCIES) \
host-python-setuptools
# Host setuptools-based packages
HOST_PKG_PYTHON_SETUPTOOLS_ENV = \
$(HOST_PKG_PYTHON_PEP517_ENV)
HOST_PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
$(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_CMD = \
$(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
# Target setuptools-rust-based packages
PKG_PYTHON_SETUPTOOLS_RUST_ENV = \
$(PKG_PYTHON_SETUPTOOLS_ENV) \
$(PKG_CARGO_ENV) \
PYO3_CROSS_LIB_DIR="$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)"
PKG_PYTHON_SETUPTOOLS_RUST_BUILD_CMD = \
$(PKG_PYTHON_SETUPTOOLS_BUILD_CMD)
PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_TARGET_CMD = \
$(PKG_PYTHON_SETUPTOOLS_INSTALL_TARGET_CMD)
PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_STAGING_CMD = \
$(PKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_CMD)
PKG_PYTHON_SETUPTOOLS_RUST_DEPENDENCIES = \
$(PKG_PYTHON_SETUPTOOLS_DEPENDENCIES) \
host-python-setuptools-rust
# Host setuptools-rust-based packages
HOST_PKG_PYTHON_SETUPTOOLS_RUST_ENV = \
$(HOST_PKG_PYTHON_SETUPTOOLS_ENV) \
$(HOST_PKG_CARGO_ENV) \
PYO3_CROSS_LIB_DIR="$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)"
HOST_PKG_PYTHON_SETUPTOOLS_RUST_BUILD_CMD = \
$(HOST_PKG_PYTHON_SETUPTOOLS_BUILD_CMD)
HOST_PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_CMD = \
$(HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_CMD)
# Target flit packages
PKG_PYTHON_FLIT_ENV = \
$(PKG_PYTHON_PEP517_ENV)
PKG_PYTHON_FLIT_BUILD_CMD = \
$(PKG_PYTHON_PEP517_BUILD_CMD)
PKG_PYTHON_FLIT_INSTALL_TARGET_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
PKG_PYTHON_FLIT_INSTALL_STAGING_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
PKG_PYTHON_FLIT_DEPENDENCIES = \
$(PKG_PYTHON_PEP517_DEPENDENCIES) \
host-python-flit-core
# Host flit packages
HOST_PKG_PYTHON_FLIT_ENV = \
$(HOST_PKG_PYTHON_PEP517_ENV)
HOST_PKG_PYTHON_FLIT_BUILD_CMD = \
$(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
HOST_PKG_PYTHON_FLIT_INSTALL_CMD = \
$(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
# Host flit-bootstrap packages
HOST_PKG_PYTHON_FLIT_BOOTSTRAP_ENV = \
$(HOST_PKG_PYTHON_PEP517_ENV)
HOST_PKG_PYTHON_FLIT_BOOTSTRAP_BUILD_CMD = \
-m flit_core.wheel
HOST_PKG_PYTHON_FLIT_BOOTSTRAP_INSTALL_CMD = \
$(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
# Target maturin packages
PKG_PYTHON_MATURIN_ENV = \
$(PKG_PYTHON_PEP517_ENV) \
$(PKG_CARGO_ENV) \
PYO3_CROSS_LIB_DIR="$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)"
PKG_PYTHON_MATURIN_BUILD_CMD = \
$(PKG_PYTHON_PEP517_BUILD_CMD)
PKG_PYTHON_MATURIN_INSTALL_TARGET_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
PKG_PYTHON_MATURIN_INSTALL_STAGING_CMD = \
$(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
PKG_PYTHON_MATURIN_DEPENDENCIES = \
$(PKG_PYTHON_PEP517_DEPENDENCIES) \
host-python-maturin
# Host maturin packages
HOST_PKG_PYTHON_MATURIN_ENV = \
$(HOST_PKG_PYTHON_PEP517_ENV) \
$(HOST_PKG_CARGO_ENV) \
PYO3_CROSS_LIB_DIR="$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)"
HOST_PKG_PYTHON_MATURIN_BUILD_CMD = \
$(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
HOST_PKG_PYTHON_MATURIN_INSTALL_CMD = \
$(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
################################################################################
# inner-python-package -- defines how the configuration, compilation
# and installation of a Python package should be done, implements a
# few hooks to tune the build process and calls the generic package
# infrastructure to generate the necessary make targets
#
# argument 1 is the lowercase package name
# argument 2 is the uppercase package name, including a HOST_ prefix
# for host packages
# argument 3 is the uppercase package name, without the HOST_ prefix
# for host packages
# argument 4 is the type (target or host)
################################################################################
define inner-python-package
ifndef $(2)_SETUP_TYPE
ifdef $(3)_SETUP_TYPE
$(2)_SETUP_TYPE = $$($(3)_SETUP_TYPE)
else
$$(error "$(2)_SETUP_TYPE must be set")
endif
endif
$(2)_SETUP_TYPE_UPPER = $$(call UPPERCASE,$$($(2)_SETUP_TYPE))
ifneq ($$(filter-out setuptools setuptools-rust pep517 flit flit-bootstrap maturin,$$($(2)_SETUP_TYPE)),)
$$(error "Invalid $(2)_SETUP_TYPE. Valid options are 'maturin', 'setuptools', 'setuptools-rust', 'pep517' or 'flit'.")
endif
ifeq ($(4)-$$($(2)_SETUP_TYPE),target-flit-bootstrap)
$$(error flit-bootstrap setup type only supported for host packages)
endif
# We need to vendor the Cargo crates at download time for pyo3 based
# packages.
#
ifneq ($$(filter maturin setuptools-rust,$$($(2)_SETUP_TYPE)),)
ifeq ($(4),target)
$(2)_DL_ENV = $$(PKG_CARGO_ENV)
else
$(2)_DL_ENV = $$(HOST_PKG_CARGO_ENV)
endif
ifndef $(2)_CARGO_MANIFEST_PATH
ifdef $(3)_CARGO_MANIFEST_PATH
$(2)_DL_ENV += BR_CARGO_MANIFEST_PATH=$$($(3)_CARGO_MANIFEST_PATH)
else
ifneq ($$($(2)_SUBDIR),)
$(2)_DL_ENV += BR_CARGO_MANIFEST_PATH=$$($(2)_SUBDIR)/Cargo.toml
endif
endif
else
$(2)_DL_ENV += BR_CARGO_MANIFEST_PATH=$$($(2)_CARGO_MANIFEST_PATH)
endif
endif
# Target packages need both the python interpreter on the target (for
# runtime) and the python interpreter on the host (for
# compilation). However, host packages only need the python
# interpreter on the host.
#
ifeq ($(4),target)
$(2)_DEPENDENCIES += host-python3 python3
else
$(2)_DEPENDENCIES += host-python3
endif # ($(4),target)
# Setup type specific dependencies are the same whether we are
# building for the host or the target.
#
ifeq ($$($(2)_SETUP_TYPE),flit-bootstrap)
# Don't add dependency on host-python-installer for
# host-python-installer itself, and its dependencies.
ifeq ($$(filter host-python-flit-core host-python-installer,$(1)),)
$(2)_DEPENDENCIES += host-python-installer
endif
else
$(2)_DEPENDENCIES += $$(PKG_PYTHON_$$($(2)_SETUP_TYPE_UPPER)_DEPENDENCIES)
endif
# Pyo3 based packages(setuptools-rust and maturin) will need rust
# toolchain dependencies for the host Python interpreter (both host
# and target).
#
ifneq ($$(filter maturin setuptools-rust,$$($(2)_SETUP_TYPE)),)
$(2)_DEPENDENCIES += host-rustc
$(2)_DOWNLOAD_POST_PROCESS = cargo
$(2)_DOWNLOAD_DEPENDENCIES = host-rustc
endif # SETUP_TYPE
ifeq ($(4),target)
#
# Build step. Only define it if not already defined by the package .mk
# file.
#
ifndef $(2)_BUILD_CMDS
define $(2)_BUILD_CMDS
(cd $$($$(PKG)_BUILDDIR)/; \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
$$($$(PKG)_ENV) \
$$(HOST_DIR)/bin/python3 \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_BUILD_CMD) \
$$($$(PKG)_BUILD_OPTS))
endef
endif
#
# Target installation step. Only define it if not already defined by
# the package .mk file.
#
ifndef $(2)_INSTALL_TARGET_CMDS
define $(2)_INSTALL_TARGET_CMDS
(cd $$($$(PKG)_BUILDDIR)/; \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
$$($$(PKG)_ENV) \
$$(HOST_DIR)/bin/python3 \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_TARGET_CMD) \
$$($$(PKG)_INSTALL_TARGET_OPTS))
endef
endif
#
# Staging installation step. Only define it if not already defined by
# the package .mk file.
#
ifndef $(2)_INSTALL_STAGING_CMDS
define $(2)_INSTALL_STAGING_CMDS
(cd $$($$(PKG)_BUILDDIR)/; \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
$$($$(PKG)_ENV) \
$$(HOST_DIR)/bin/python3 \
$$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_STAGING_CMD) \
$$($$(PKG)_INSTALL_STAGING_OPTS))
endef
endif
else # host
#
# Host build step. Only define it if not already defined by the package .mk
# file.
#
ifndef $(2)_BUILD_CMDS
define $(2)_BUILD_CMDS
(cd $$($$(PKG)_BUILDDIR)/; \
$$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
$$($$(PKG)_ENV) \
$$(HOST_DIR)/bin/python3 \
$$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_BUILD_CMD) \
$$($$(PKG)_BUILD_OPTS))
endef
endif
#
# Host installation step. Only define it if not already defined by the
# package .mk file.
#
ifndef $(2)_INSTALL_CMDS
define $(2)_INSTALL_CMDS
(cd $$($$(PKG)_BUILDDIR)/; \
$$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
$$($$(PKG)_ENV) \
$$(HOST_DIR)/bin/python3 \
$$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_CMD) \
$$($$(PKG)_INSTALL_OPTS))
endef
endif
endif # host / target
# Call the generic package infrastructure to generate the necessary
# make targets
$(call inner-generic-package,$(1),$(2),$(3),$(4))
endef
################################################################################
# python-package -- the target generator macro for Python packages
################################################################################
python-package = $(call inner-python-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target)
host-python-package = $(call inner-python-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host)