123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- ################################################################################
- # 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 setuptools-based packages
- PKG_PYTHON_SETUPTOOLS_ENV = \
- $(PKG_PYTHON_ENV)
- PKG_PYTHON_SETUPTOOLS_CMD = \
- $(if $(wildcard $($(PKG)_BUILDDIR)/setup.py),setup.py,-c 'from setuptools import setup;setup()')
- PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
- $(PKG_PYTHON_SETUPTOOLS_CMD) build
- 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_SETUPTOOLS_CMD) \
- install --no-compile \
- $(PKG_PYTHON_SETUPTOOLS_INSTALL_OPTS) \
- --root=$(TARGET_DIR)
- PKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_CMD = \
- $(PKG_PYTHON_SETUPTOOLS_CMD) \
- install \
- $(PKG_PYTHON_SETUPTOOLS_INSTALL_OPTS) \
- --root=$(STAGING_DIR)
- # Host setuptools-based packages
- HOST_PKG_PYTHON_SETUPTOOLS_ENV = \
- $(HOST_PKG_PYTHON_ENV)
- HOST_PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
- $(PKG_PYTHON_SETUPTOOLS_CMD) build
- HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_CMD = \
- $(PKG_PYTHON_SETUPTOOLS_CMD) \
- install \
- --prefix=$(HOST_DIR) \
- --root=/ \
- --single-version-externally-managed
- # 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)
- # 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 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
- # 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 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)
- # 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)
- # 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)
- # Setuptools based packages will need setuptools for the host Python
- # interpreter (both host and target).
- #
- ifneq ($$(filter setuptools setuptools-rust,$$($(2)_SETUP_TYPE)),)
- $(2)_DEPENDENCIES += host-python-setuptools
- ifeq ($$($(2)_SETUP_TYPE),setuptools-rust)
- $(2)_DEPENDENCIES += host-python-setuptools-rust
- endif
- else ifneq ($$(filter flit maturin pep517,$$($(2)_SETUP_TYPE)),)
- $(2)_DEPENDENCIES += host-python-pypa-build host-python-installer
- ifeq ($$($(2)_SETUP_TYPE),flit)
- $(2)_DEPENDENCIES += host-python-flit-core
- endif
- ifeq ($$($(2)_SETUP_TYPE),maturin)
- $(2)_DEPENDENCIES += host-python-maturin
- endif
- else 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
- 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)
|