mirror of
https://github.com/openbsd/ports.git
synced 2026-06-18 15:33:55 +02:00
6d7b8aa9f8
setuptools opportunistically picks up extensions and builds can fail if dpb junking occurs during build (only really likely on a slower building port with compiled code rather than a pure Python port). it doesn't happen _all_ that often (I've gone months without seeing it in my i386 bulk builds) but isn't that easy to identify from the logs and people that can run more jobs in parallel hit it more frequently, so let's go back to nojunk and see how we go.
401 lines
13 KiB
Makefile
401 lines
13 KiB
Makefile
# python.port.mk - This file is in the public domain.
|
|
# Xavier Santolaria <xavier@santolaria.net>
|
|
# Stuart Henderson <stu@spacehopper.org>
|
|
|
|
CATEGORIES += lang/python
|
|
|
|
# define the default versions
|
|
MODPY_DEFAULT_VERSION_2 = 2.7
|
|
MODPY_DEFAULT_VERSION_3 = 3.12
|
|
MODPY_VERSION ?= ${MODPY_DEFAULT_VERSION_3}
|
|
|
|
# If switching to a new MODPY_DEFAULT_VERSION_3, say 3.x to 3.y:
|
|
# - All ports with PLISTs that depend on the Python version number
|
|
# must be REVISION-bumped.
|
|
# - Keep xenocara/share/mk/bsd.xorg.mk PYTHON_VERSION in sync.
|
|
|
|
# verify if MODPY_VERSION found is correct
|
|
.if ${MODPY_VERSION} == "2.7"
|
|
_MODPY_SUBDIR = 2.7
|
|
.elif ${MODPY_VERSION} == "3.12"
|
|
_MODPY_SUBDIR = 3
|
|
.else
|
|
ERRORS += "Fatal: unknown or unsupported MODPY_VERSION: ${MODPY_VERSION}"
|
|
.endif
|
|
|
|
MODPY_WANTLIB = python${MODPY_VERSION}
|
|
MODPY_RUN_DEPENDS = lang/python/${_MODPY_SUBDIR}
|
|
MODPY_LIB_DEPENDS = lang/python/${_MODPY_SUBDIR}
|
|
_MODPY_BUILD_DEPENDS = lang/python/${_MODPY_SUBDIR}
|
|
MODPY_TKINTER_DEPENDS = lang/python/${_MODPY_SUBDIR},-tkinter
|
|
|
|
MODPY_MAJOR_VERSION = ${MODPY_VERSION:R}
|
|
|
|
.if ${MODPY_MAJOR_VERSION} == 2
|
|
MODPY_PY_PREFIX = py-
|
|
MODPY_PYCACHE =
|
|
MODPY_PYC_MAGIC_TAG =
|
|
MODPY_COMMENT = "@comment "
|
|
MODPY_ABI3SO =
|
|
MODPY_PYOEXTENSION = pyo
|
|
.elif ${MODPY_MAJOR_VERSION} == 3
|
|
# replace py- prefix with py3-
|
|
FULLPKGNAME ?= ${PKGNAME:S/^py-/py3-/}${FLAVOR_EXT}
|
|
MODPY_PY_PREFIX = py3-
|
|
MODPY_PYCACHE = __pycache__/
|
|
MODPY_MAJORMINOR = ${MODPY_VERSION:C/\.//g}
|
|
MODPY_PYC_MAGIC_TAG = cpython-${MODPY_MAJORMINOR}.
|
|
MODPY_COMMENT =
|
|
MODPY_ABI3SO = .abi3
|
|
MODPY_PYOEXTENSION ?= opt-1.pyc
|
|
.endif
|
|
|
|
MODPY_SETUPTOOLS ?=
|
|
MODPY_SETUPUTILS ?=
|
|
MODPY_PYBUILD ?= No
|
|
MODPY_PI ?=
|
|
|
|
# If MODPY_PYTEST_ARGS are set, or if using MODPY_PYBUILD, it implies that
|
|
# we want MODPY_PYTEST = Yes
|
|
MODPY_PYTEST_ARGS ?=
|
|
.if empty(MODPY_PYTEST_ARGS) && ${MODPY_PYBUILD:L} == no
|
|
MODPY_PYTEST ?= No
|
|
.else
|
|
MODPY_PYTEST ?= Yes
|
|
.endif
|
|
|
|
.if ${MODPY_PYTEST:L} == "yes"
|
|
MODPY_TEST_DEPENDS = ${RUN_DEPENDS}
|
|
MODPY_TEST_DEPENDS += devel/py-test
|
|
.else
|
|
MODPY_TEST_DEPENDS = ${MODPY_RUN_DEPENDS}
|
|
.endif
|
|
|
|
.if ${NO_BUILD:L} == "no"
|
|
MODPY_BUILDDEP ?= Yes
|
|
.else
|
|
MODPY_BUILDDEP ?= No
|
|
.endif
|
|
MODPY_RUNDEP ?= Yes
|
|
.if ${NO_TEST:L} == "no"
|
|
MODPY_TESTDEP ?= Yes
|
|
.else
|
|
MODPY_TESTDEP ?= No
|
|
.endif
|
|
|
|
.if ${MODPY_BUILDDEP:L} == "yes"
|
|
BUILD_DEPENDS += ${_MODPY_BUILD_DEPENDS}
|
|
.endif
|
|
|
|
.if ${MODPY_RUNDEP:L} == "yes"
|
|
RUN_DEPENDS += ${MODPY_RUN_DEPENDS}
|
|
.endif
|
|
|
|
.if ${MODPY_TESTDEP:L} == "yes"
|
|
TEST_DEPENDS += ${MODPY_TEST_DEPENDS}
|
|
.endif
|
|
|
|
_MODPY_PRE_BUILD_STEPS = :
|
|
|
|
.if ${MODPY_PYBUILD:L} == "no" && ${MODPY_MAJOR_VERSION} != 2
|
|
# not necessarily an error, but try to draw attention to it. defer printing
|
|
# the warning to fake-install where it's less likely to scroll off the screen.
|
|
_MODPY_PRE_BUILD_STEPS += ; if [ -e ${WRKSRC}/pyproject.toml ] && \
|
|
grep -q ^build-backend ${WRKSRC}/pyproject.toml; then \
|
|
(echo; echo '*** Ports with pyproject.toml should normally use MODPY_PYBUILD'; \
|
|
grep -H ^build-backend ${WRKSRC}/pyproject.toml; echo ) >> \
|
|
${WRKDIR}/.modpy-warn; \
|
|
fi
|
|
.endif
|
|
|
|
_MODPY_USE_CARGO = No
|
|
|
|
.if ${MODPY_SETUPTOOLS:L} == "yes"
|
|
. if ${MODPY_PYBUILD:L} != "no"
|
|
ERRORS += "Fatal: both MODPY_PYBUILD and MODPY_SETUPTOOLS are set. Just use MODPY_PYBUILD."
|
|
. endif
|
|
# For Python 2, setuptools provides a package locator that is required at
|
|
# runtime for pkg_resources to work, so an RDEP is needed.
|
|
# For Python 3, pkg_resources is deprecated - Python core has similar
|
|
# functionality in importlib.metadata.
|
|
# If a py3 port still needs pkg_resources, expect deprecation warnings
|
|
# at runtime, and in that case an RDEP on setuptools should be added
|
|
# manually.
|
|
. if ${MODPY_MAJOR_VERSION} == 2
|
|
MODPY_SETUPUTILS_DEPEND ?= devel/py2-setuptools
|
|
MODPY_RUN_DEPENDS += ${MODPY_SETUPUTILS_DEPEND}
|
|
. else
|
|
MODPY_SETUPUTILS_DEPEND ?= devel/py-setuptools
|
|
. endif
|
|
|
|
BUILD_DEPENDS += ${MODPY_SETUPUTILS_DEPEND}
|
|
MODPY_SETUPUTILS = Yes
|
|
|
|
# The setuptools uses test target
|
|
TEST_TARGET ?= test
|
|
_MODPY_USERBASE =
|
|
_MODPY_PRE_BUILD_STEPS += ;${MODPY_CMD} egg_info || true
|
|
.elif ${MODPY_PYBUILD:L} != no
|
|
BUILD_DEPENDS += devel/py-build \
|
|
devel/py-installer
|
|
. if ${MODPY_PYBUILD} == flit
|
|
BUILD_DEPENDS += devel/py-flit
|
|
. elif ${MODPY_PYBUILD} == flit_core
|
|
BUILD_DEPENDS += devel/py-flit_core
|
|
. elif ${MODPY_PYBUILD} == flit_scm
|
|
BUILD_DEPENDS += devel/py-flit_scm
|
|
. elif ${MODPY_PYBUILD} == hatch-vcs
|
|
BUILD_DEPENDS += devel/py-hatch-vcs
|
|
_MODPY_EXPECTED_BACKEND = hatchling
|
|
. elif ${MODPY_PYBUILD} == hatchling
|
|
BUILD_DEPENDS += devel/py-hatchling
|
|
. elif ${MODPY_PYBUILD} == jupyter_packaging
|
|
BUILD_DEPENDS += devel/py-jupyter_packaging
|
|
_MODPY_EXPECTED_BACKEND = setuptools
|
|
. elif ${MODPY_PYBUILD} == maturin
|
|
BUILD_DEPENDS += devel/maturin
|
|
MODCARGO_CARGO_BIN = maturin
|
|
_MODPY_WHEELSDIR = target/wheels
|
|
_MODPY_USE_CARGO = Yes
|
|
. elif ${MODPY_PYBUILD} == mesonpy
|
|
BUILD_DEPENDS += devel/meson-python
|
|
. elif ${MODPY_PYBUILD} == pbr
|
|
BUILD_DEPENDS += devel/py-pbr \
|
|
devel/py-setuptools \
|
|
devel/py-wheel
|
|
. elif ${MODPY_PYBUILD} == pdm
|
|
BUILD_DEPENDS += devel/py-pdm-backend
|
|
. elif ${MODPY_PYBUILD} == poetry-core
|
|
BUILD_DEPENDS += devel/py-poetry-core
|
|
_MODPY_EXPECTED_BACKEND = poetry.core
|
|
. elif ${MODPY_PYBUILD} == setuptools || \
|
|
${MODPY_PYBUILD} == setuptools_scm || \
|
|
${MODPY_PYBUILD} == setuptools-rust
|
|
BUILD_DEPENDS += devel/py-setuptools \
|
|
devel/py-wheel
|
|
_MODPY_EXPECTED_BACKEND = setuptools
|
|
. if ${MODPY_PYBUILD} == setuptools_scm
|
|
BUILD_DEPENDS += devel/py-setuptools_scm
|
|
. elif ${MODPY_PYBUILD} == setuptools-rust
|
|
BUILD_DEPENDS += devel/py-setuptools-rust
|
|
_MODPY_USE_CARGO = Yes
|
|
. endif
|
|
. elif !${MODPY_PYBUILD:L:Mother}
|
|
ERRORS += "Fatal: unknown MODPY_PYBUILD value (flit, flit_core, flit_scm, hatch-vcs, hatchling, jupyter_packaging, pbr, pdm, maturin, mesonpy, other, poetry-core, setuptools, setuptools_scm, setuptools-rust)"
|
|
. endif
|
|
_MODPY_EXPECTED_BACKEND ?= ${MODPY_PYBUILD}
|
|
_MODPY_WHEELSDIR ?= dist
|
|
. if ${_MODPY_USE_CARGO:L} == yes
|
|
MODCARGO_INSTALL ?= No
|
|
MODCARGO_TEST ?= No
|
|
MODULES += devel/cargo
|
|
. endif
|
|
.else
|
|
MODPY_SETUPUTILS = No
|
|
# Detect the case where a port is capable of building with setup.py
|
|
# via fallback to distutils, but should use py-build instead.
|
|
_MODPY_SETUPUTILS_FAKE_DIR = \
|
|
${WRKDIR}/lib/python${MODPY_VERSION}/site-packages/setuptools
|
|
_MODPY_PRE_BUILD_STEPS += \
|
|
;mkdir -p ${_MODPY_SETUPUTILS_FAKE_DIR} \
|
|
;exec 3>&1 \
|
|
;exec >${_MODPY_SETUPUTILS_FAKE_DIR}/__init__.py \
|
|
;echo 'def setup(*args, **kwargs):' \
|
|
;echo ' msg = "OpenBSD ports: use MODPY_PYBUILD"' \
|
|
;echo ' raise Exception(msg)' \
|
|
;echo 'Extension = Feature = find_packages = setup' \
|
|
;exec 1>&3
|
|
_MODPY_USERBASE = ${WRKDIR}
|
|
.endif
|
|
|
|
.if ${MODPY_SETUPTOOLS:L} == "yes" || ${MODPY_PYBUILD:Msetuptools*}
|
|
# Setuptools opportunistically picks up plugins. If it picks one up that
|
|
# uses finalize_distribution_options (usually setuptools_scm), junking
|
|
# that plugin will cause failure at the end of build.
|
|
# In the absence of a targetted means of disabling this, use a big hammer:
|
|
DPB_PROPERTIES += nojunk
|
|
# XXX if a "nojunk" port fails to build, DPB will no longer junk on that
|
|
# XXX node, likely resulting in running out of disk space in /usr/local.
|
|
.endif
|
|
|
|
# cython picks up pythran at run time in some cases, resulting in
|
|
# DPB failure if junking occurs. Add a dep to avoid this. This is
|
|
# conditional to avoid loops (currently seen with py-numpy).
|
|
MODPY_CYTHON_PYTHRAN_RDEP ?= Yes
|
|
.if defined(BUILD_DEPENDS) && ${BUILD_DEPENDS:Mlang/cython*} && \
|
|
${MODPY_CYTHON_PYTHRAN_RDEP} == Yes
|
|
BUILD_DEPENDS += lang/pythran
|
|
.endif
|
|
|
|
.if ${MODPY_PI:L} == "yes"
|
|
_MODPY_EGG_NAME = ${DISTNAME:S/-${MODPY_DISTV}//}
|
|
MODPY_PI_DIR ?= ${DISTNAME:C/^([a-zA-Z0-9]).*/\1/}/${_MODPY_EGG_NAME}
|
|
SITES = ${SITE_PYPI:=${MODPY_PI_DIR}/}
|
|
HOMEPAGE ?= https://pypi.python.org/pypi/${_MODPY_EGG_NAME}
|
|
.endif
|
|
|
|
MODPY_BIN = ${LOCALBASE}/bin/python${MODPY_VERSION}
|
|
MODPY_INCDIR = ${LOCALBASE}/include/python${MODPY_VERSION}
|
|
MODPY_LIBDIR = ${LOCALBASE}/lib/python${MODPY_VERSION}
|
|
MODPY_SITEPKG = ${MODPY_LIBDIR}/site-packages
|
|
|
|
# usually setup.py but Setup.py can be found too
|
|
MODPY_SETUP ?= setup.py
|
|
|
|
# build or build_ext are commonly used
|
|
MODPY_DISTUTILS_BUILD ?= build --build-base=${WRKBUILD}
|
|
|
|
.if ${MODPY_SETUPUTILS:L} == "yes"
|
|
MODPY_DISTUTILS_INSTALL ?= install --prefix=${TRUEPREFIX} \
|
|
--root=${DESTDIR} \
|
|
--single-version-externally-managed
|
|
.else
|
|
MODPY_DISTUTILS_INSTALL ?= install --prefix=${TRUEPREFIX} \
|
|
--root=${DESTDIR}
|
|
.endif
|
|
|
|
MAKE_ENV += CC=${CC} PYTHONUSERBASE=${_MODPY_USERBASE}
|
|
CONFIGURE_ENV += PYTHON="${MODPY_BIN}"
|
|
.if ${CONFIGURE_STYLE:Mgnu}
|
|
CONFIGURE_ENV += ac_cv_prog_PYTHON="${MODPY_BIN}" \
|
|
ac_cv_path_PYTHON="${MODPY_BIN}"
|
|
.endif
|
|
|
|
_MODPY_RUNBIN = cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${MODPY_BIN}
|
|
|
|
MODPY_CMD = cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
|
|
${MODPY_BIN} ./${MODPY_SETUP} \
|
|
${MODPY_SETUP_ARGS}
|
|
|
|
MODPY_TEST_DIR ?= ${WRKSRC}
|
|
|
|
MODPY_TEST_CMD = cd ${MODPY_TEST_DIR} && ${SETENV} ${ALL_TEST_ENV} ${MODPY_BIN}
|
|
.if ${MODPY_PYTEST:L} == "yes"
|
|
MODPY_PYTEST_USERARGS ?=
|
|
MODPY_TEST_CMD += -m pytest ${MODPY_PYTEST_USERARGS}
|
|
MODPY_TEST_LIBDIR ?= ${WRKINST}${MODPY_SITEPKG}:${WRKSRC}/build/lib:${WRKSRC}/build/lib.openbsd-${OSREV}-${ARCH}-cpython-${MODPY_MAJORMINOR}:${WRKSRC}/lib.openbsd-${OSREV}-${ARCH}-${MODPY_VERSION}
|
|
.else
|
|
MODPY_TEST_CMD += ./${MODPY_SETUP} ${MODPY_SETUP_ARGS}
|
|
.endif
|
|
|
|
MODPY_TEST_LIBDIR ?=
|
|
MODPY_TEST_LOCALE ?= LC_CTYPE=en_US.UTF-8
|
|
TEST_ENV += ${MODPY_TEST_LOCALE}
|
|
|
|
.if !empty(MODPY_TEST_LIBDIR)
|
|
TEST_ENV += PYTHONPATH=${MODPY_TEST_LIBDIR}:lib:src
|
|
.endif
|
|
|
|
SUBST_VARS := MODPY_PYCACHE MODPY_COMMENT MODPY_ABI3SO MODPY_PYC_MAGIC_TAG \
|
|
MODPY_BIN MODPY_DISTV MODPY_VERSION \
|
|
MODPY_PY_PREFIX MODPY_PYOEXTENSION ${SUBST_VARS}
|
|
|
|
UPDATE_PLIST_ARGS += -S MODPY_PYOEXTENSION \
|
|
-I MODPY_ABI3SO -c MODPY_COMMENT -I MODPY_PYCACHE
|
|
|
|
# set MODPY_BIN for executable scripts
|
|
MODPY_BIN_ADJ = perl -pi \
|
|
-e '$$. == 1 && s|^.*env +python.*$$|\#!${MODPY_BIN}|;' \
|
|
-e '$$. == 1 && s|^.*bin/python.*$$|\#!${MODPY_BIN}|;' \
|
|
-e 'close ARGV if eof;' --
|
|
|
|
MODPY_ADJ_FILES ?=
|
|
.if !empty(MODPY_ADJ_FILES)
|
|
MODPYTHON_pre-configure += cd ${WRKSRC} && ${MODPY_BIN_ADJ} ${MODPY_ADJ_FILES}
|
|
.endif
|
|
|
|
.if ${MODPY_VERSION} == ${MODPY_DEFAULT_VERSION_2}
|
|
MODPY_COMPILEALL = ${MODPY_BIN} -m compileall
|
|
.else
|
|
MODPY_COMPILEALL = ${MODPY_BIN} -m compileall -j ${MAKE_JOBS} -s ${WRKINST} -o 0 -o 1
|
|
.endif
|
|
|
|
MODPY_TEST_TARGET =
|
|
MODPY_TEST_LINK_SO ?= No
|
|
.if ${MODPY_TEST_LINK_SO:L} == "yes" && !empty(MODPY_TEST_LIBDIR)
|
|
MODPY_TEST_LINK_SRC ?= ${WRKSRC}
|
|
MODPY_TEST_SO_CMD = for _dir in ${MODPY_TEST_LIBDIR:S,:, ,g}; do \
|
|
if [ -d $${_dir} ]; then \
|
|
cd $${_dir} && \
|
|
find . -name '*.so' -type f \
|
|
-exec ln -sf $${_dir}/{} ${MODPY_TEST_LINK_SRC}/{} \; ;\
|
|
fi; done
|
|
MODPY_TEST_TARGET += ${MODPY_TEST_SO_CMD};
|
|
.endif
|
|
|
|
.if ${MODPY_PYBUILD:L} != no
|
|
. if ! ${MODPY_PYBUILD:Msetuptools_scm} && ! ${BUILD_DEPENDS:Mdevel/py-setuptools_scm}
|
|
_MODPY_PRE_BUILD_STEPS += ; if [ -e ${WRKSRC}/pyproject.toml ] && \
|
|
(grep -A3 '^requires' ${WRKSRC}/pyproject.toml | \
|
|
grep -q 'setuptools[-_]scm'); then \
|
|
(echo; echo '*** Port may need MODPY_PYBUILD=setuptools_scm'; \
|
|
grep -H -e ^build-backend -e '^requires.*setuptools' \
|
|
${WRKSRC}/pyproject.toml; echo ) >> ${WRKDIR}/.modpy-warn; \
|
|
fi
|
|
. endif
|
|
. if ${_MODPY_EXPECTED_BACKEND} != other
|
|
_MODPY_PRE_BUILD_STEPS += ; if [ -e ${WRKSRC}/pyproject.toml ] && \
|
|
grep '^build-backend' ${WRKSRC}/pyproject.toml | \
|
|
grep -qvw ${_MODPY_EXPECTED_BACKEND}; then \
|
|
(echo; echo '*** Check MODPY_PYBUILD setting (currently "${MODPY_PYBUILD}")'; \
|
|
grep -H ^build-backend ${WRKSRC}/pyproject.toml; echo ) >> \
|
|
${WRKDIR}/.modpy-warn; \
|
|
fi
|
|
. endif
|
|
MODPY_PYBUILD_ARGS ?=
|
|
MODPY_BUILD_TARGET = ${_MODPY_PRE_BUILD_STEPS}; \
|
|
${_MODPY_RUNBIN} -sBm build -w --no-isolation ${MODPY_PYBUILD_ARGS}
|
|
MODPY_INSTALL_TARGET = \
|
|
${INSTALL_DATA_DIR} ${WRKINST}${MODPY_LIBDIR}; \
|
|
${_MODPY_RUNBIN} -m installer -d ${WRKINST} ${WRKSRC}/${_MODPY_WHEELSDIR}/*.whl
|
|
MODPY_TEST_TARGET += ${MODPY_TEST_CMD}
|
|
. if ${MODPY_PYTEST:L} == "yes"
|
|
MODPY_TEST_TARGET += ${MODPY_PYTEST_ARGS}
|
|
. endif
|
|
.else
|
|
MODPY_BUILD_TARGET = ${_MODPY_PRE_BUILD_STEPS}; \
|
|
${MODPY_CMD} ${MODPY_DISTUTILS_BUILD} ${MODPY_DISTUTILS_BUILDARGS}
|
|
MODPY_INSTALL_TARGET = \
|
|
${MODPY_CMD} ${MODPY_DISTUTILS_BUILD} ${MODPY_DISTUTILS_BUILDARGS} \
|
|
${MODPY_DISTUTILS_INSTALL} ${MODPY_DISTUTILS_INSTALLARGS}
|
|
|
|
MODPY_TEST_TARGET += ${MODPY_TEST_CMD}
|
|
. if ${MODPY_PYTEST:L} == "yes"
|
|
MODPY_TEST_TARGET += ${MODPY_PYTEST_ARGS}
|
|
. elif ${MODPY_SETUPUTILS:L} == "yes"
|
|
MODPY_TEST_TARGET += ${TEST_TARGET}
|
|
. endif
|
|
.endif
|
|
|
|
MODPY_INSTALL_TARGET += ; if [ -r ${WRKDIR}/.modpy-warn ]; then cat ${WRKDIR}/.modpy-warn; fi
|
|
|
|
.if empty(CONFIGURE_STYLE)
|
|
. if !target(do-configure) && ${_MODPY_USE_CARGO:L} == yes
|
|
do-configure:
|
|
@${MODCARGO_configure}
|
|
. endif
|
|
|
|
. if !target(do-build)
|
|
do-build:
|
|
. if ${_MODPY_USE_CARGO:L} == yes
|
|
@${MODCARGO_BUILD_TARGET}
|
|
. endif
|
|
. if ${MODPY_PYBUILD} != maturin
|
|
@${MODPY_BUILD_TARGET}
|
|
. endif
|
|
. endif
|
|
|
|
# extra documentation or scripts should be installed via post-install
|
|
. if !target(do-install)
|
|
do-install:
|
|
@${MODPY_INSTALL_TARGET}
|
|
. endif
|
|
|
|
. if !target(do-test) && \
|
|
(${MODPY_SETUPUTILS:L} == "yes" || ${MODPY_PYTEST:L} == "yes")
|
|
do-test:
|
|
@${MODPY_TEST_TARGET}
|
|
. endif
|
|
|
|
.endif
|