# Created by: Franz Glasner <fzglas.hg@dom66.de>
# based on the port created by: David Naylor <naylor.b.david@gmail.com>

PORTNAME=	pypy310
DISTVERSION=	7.3.14
CATEGORIES=	lang python
MASTER_SITES=	https://downloads.python.org/pypy/
DISTNAME=	pypy${PYPY_PYTHON_IMPL_VER}-v${DISTVERSION}-src

MAINTAINER=	fzglas.hg@dom66.de
COMMENT=	Fast, compliant implementation of the Python language
WWW=		https://www.pypy.org

LICENSE=	MIT PSFL
LICENSE_COMB=	multi
LICENSE_FILE_MIT=	${WRKSRC}/LICENSE

BROKEN_armv6=		fails to package: pypy_objspace_std.c: Crash in JIT!
BROKEN_armv7=		fails to package: pypy_objspace_std.c: Crash in JIT!
BROKEN_powerpc64=	fails to compile: platcheck_109.c: fatal error: linux/auxvec.h: No such file or directory
ONLY_FOR_ARCHS?=	amd64 armv6 armv7 i386 powerpc64 powerpc64le
ONLY_FOR_ARCHS_REASON?=	PyPy JIT only supported on these architectures

LIB_DEPENDS=	libexpat.so:textproc/expat2 \
		libffi.so:devel/libffi
# Without gdbm is not supported on v7.3.9 any more: no extra package needed
LIB_DEPENDS+=	libgdbm.so:databases/gdbm
# We also need for dbm.ndbm the BerkeleyDB in version 5
LIB_DEPENDS+=	libdb-5.so:databases/db5
TEST_DEPENDS=	${LOCALBASE}/${PYPY_DIR}/lib_pypy/_gdbm_cffi.${PYPY_CFFI_VER}.so:databases/pypy-gdbm \
		${LOCALBASE}/${PYPY_DIR}/lib_pypy/_sqlite3_cffi.${PYPY_CFFI_VER}.so:databases/pypy-sqlite3 \
		${LOCALBASE}/${PYPY_DIR}/lib_pypy/_tkinter/tklib_cffi.${PYPY_CFFI_VER}.so:x11-toolkits/pypy-tkinter

USES=		compiler:c11 gettext-runtime gmake shebangfix ssl tar:bzip2
USE_LDCONFIG=	${PREFIX}/${PYPY_DIR}/bin

OPTIONS_DEFINE=	BYTECOMPILE
OPTIONS_DEFAULT=	BYTECOMPILE PYTHON BCUNCHECKEDHASH
OPTIONS_SINGLE=	TRANS BCSTYLE
OPTIONS_SINGLE_TRANS=	PYTHON PYPY PYPY_MINMEM
OPTIONS_SINGLE_BCSTYLE=	BCTIMESTAMP BCCHECKEDHASH BCUNCHECKEDHASH
OPTIONS_SUB=	yes

BYTECOMPILE_DESC=	Enable to build byte-compiled Python files
TRANS_DESC=	Translation method
BCSTYLE_DESC=	PEP-552 .pyc-File Invalidation Modes
PYTHON_DESC=	Use Python-2.7 to translate (slowest)
PYPY_DESC=	Use PyPy to translate (fastest, highest memory usage)
PYPY_MINMEM_DESC=	Use PyPy to translate (lowest memory usage)
BCTIMESTAMP_DESC=	Traditional timestamp based .pyc file invalidataion
BCCHECKEDHASH_DESC=	Use checked hash based .pyc file invalidataion
BCUNCHECKEDHASH_DESC=	Use unchecked hash based .pyc file invalidataion

PYTHON_BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}pycparser>=2.10:devel/py-pycparser@${PY_FLAVOR}
PYTHON_USES=	python:2.7,build
PYPY_BUILD_DEPENDS=	pypy2:lang/pypy2
PYPY_VARS=	PYTHON_CMD=${LOCALBASE}/bin/pypy
PYPY_MINMEM_BUILD_DEPENDS=	pypy2:lang/pypy2
PYPY_MINMEM_VARS=	PYTHON_CMD="${SETENV} PYPY_GC_MAX_DELTA=200MB ${LOCALBASE}/bin/pypy --jit loop_longevity=300"
BCTIMESTAMP_VARS=	COMPILEALL_INVALIDATIONMODE=timestamp
BCCHECKEDHASH_VARS=	COMPILEALL_INVALIDATIONMODE=checked-hash
BCUNCHECKEDHASH_VARS=	COMPILEALL_INVALIDATIONMODE=unchecked-hash

PYPY_TAG=	pypy
PYPY_DIR=	pypy${PYPY_PYTHON_IMPL_VER_MAJOR}-${DISTVERSION:C|([0-9]+)\.([0-9]+).*|\1.\2|}

PYPY_PYTHON_IMPL_VER=	3.10
PYPY_PYTHON_IMPL_VER_MAJOR=	${PYPY_PYTHON_IMPL_VER:C|([0-9]+)\.[0-9]+|\1|}

PYPY_CFFI_VER=	pypy${PYPY_PYTHON_IMPL_VER:S/.//}-pp${DISTVERSION:S|.||:C|\..*||}-${OPSYS:tl}${OSREL:C|\..*||}
PYPY_LDLIBRARY=	libpypy${PYPY_PYTHON_IMPL_VER}-c.so
PYPY_EXECUTABLE=	pypy${PYPY_PYTHON_IMPL_VER}-c
PYPY_BCTAG=	.pypy${PYPY_PYTHON_IMPL_VER:S/.//}

PYPY_ARGS=

PLIST_SUB+=	PYPY_DIR=${PYPY_DIR} \
		PYPY_CFFI_VER=${PYPY_CFFI_VER} \
		PYPY_LDLIBRARY=${PYPY_LDLIBRARY} \
		PKGNAME=${PKGNAME} \
		PYTHON_IMPL_MINOR=pypy${PYPY_PYTHON_IMPL_VER} \
		PY_VERSION_SHORT=${PYPY_PYTHON_IMPL_VER} \
		PYPY_BCTAG=${PYPY_BCTAG}

ALL_TARGET=	${PYPY_EXECUTABLE}
BUILD_WRKSRC=	${WRKDIR}/build/usession-${PORTNAME}-0/testing_1
MAKE_ENV+=	PYPY_LOCALBASE=${LOCALBASE} LDSHARED="${CC} -shared"
PACKAGE_ARGS=	--without-sqlite3 --without-_tkinter
LLD_UNSAFE=	yes

# shebang configuration
python_CMD=	${LOCALBASE}/bin/pypy${PYPY_PYTHON_IMPL_VER}
SHEBANG_FILES=	\
		lib-python/3/base64.py \
		lib-python/3/cProfile.py \
		lib-python/3/cgi.py \
		lib-python/3/encodings/rot_13.py \
		lib-python/3/keyword.py \
		lib-python/3/idlelib/pyshell.py \
		lib-python/3/lib2to3/pgen2/token.py \
		lib-python/3/lib2to3/tests/data/different_encoding.py \
		lib-python/3/lib2to3/tests/data/false_encoding.py \
		lib-python/3/lib2to3/tests/pytree_idempotency.py \
		lib-python/3/pdb.py \
		lib-python/3/platform.py \
		lib-python/3/profile.py \
		lib-python/3/pydoc.py \
		lib-python/3/quopri.py \
		lib-python/3/smtpd.py \
		lib-python/3/smtplib.py \
		lib-python/3/tabnanny.py \
		lib-python/3/tarfile.py \
		lib-python/3/test/bisect_cmd.py \
		lib-python/3/test/crashers/recursive_call.py \
		lib-python/3/test/curses_tests.py \
		lib-python/3/test/pystone.py \
		lib-python/3/test/re_tests.py \
		lib-python/3/test/regrtest.py \
		lib-python/3/timeit.py \
		lib-python/3/trace.py \
		lib-python/3/turtledemo/bytedesign.py \
		lib-python/3/turtledemo/clock.py \
		lib-python/3/turtledemo/forest.py \
		lib-python/3/turtledemo/fractalcurves.py \
		lib-python/3/turtledemo/lindenmayer.py \
		lib-python/3/turtledemo/minimal_hanoi.py \
		lib-python/3/turtledemo/paint.py \
		lib-python/3/turtledemo/peace.py \
		lib-python/3/turtledemo/penrose.py \
		lib-python/3/turtledemo/planet_and_moon.py \
		lib-python/3/turtledemo/sorting_animate.py \
		lib-python/3/turtledemo/tree.py \
		lib-python/3/turtledemo/yinyang.py \
		lib-python/3/turtledemo/__main__.py \
		lib-python/3/uu.py \
		lib-python/3/webbrowser.py \
		lib_pypy/_cffi_ssl/tools/make_ssl_data.py \
		lib-python/3/test/ziptestdata/header.sh \
		lib-python/3/test/ziptestdata/exe_with_z64 \
		lib-python/3/test/ziptestdata/exe_with_zip

#.include "bsd.pypy.mk"
.include <bsd.port.pre.mk>

.if ${OPSYS} == FreeBSD && ${ARCH} != i386 && ${ARCH} != amd64
PYPY_ARGS=	--withoutmod-_vmprof
.else
LIB_DEPENDS+=	libunwind.so:devel/libunwind
.endif

pre-build:
	if [ ! -f ${BUILD_WRKSRC}/Makefile ]; then \
		${RM} -r ${WRKDIR}/build; \
		${MKDIR} ${WRKDIR}/build; \
		(cd ${WRKSRC}/pypy/goal; \
			${SETENV} ${MAKE_ENV} TMPDIR=${WRKDIR}/build PYPY_USESSION_BASENAME=${PORTNAME} \
			${PYTHON_CMD} ../../rpython/bin/rpython --source --opt=jit targetpypystandalone.py ${PYPY_ARGS}); \
	fi

post-build:
	${CP} ${BUILD_WRKSRC}/${PYPY_EXECUTABLE} ${BUILD_WRKSRC}/${PYPY_LDLIBRARY} ${WRKSRC}/pypy/goal/

do-install:
	(cd ${WRKSRC}; \
		${SETENV} ${MAKE_ENV} TMPDIR=${WRKDIR}/build \
			${PYTHON_CMD} ${WRKSRC}/pypy/tool/release/package.py --builddir ${WRKDIR}/build --archive-name ${PYPY_DIR} \
				${PACKAGE_ARGS})
	${EXTRACT_CMD} -C ${STAGEDIR}${PREFIX} -xf ${WRKDIR}/build/${PYPY_DIR}.tar.bz2
	${MV} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/LICENSE ${STAGEDIR}${PREFIX}/${PYPY_DIR}/LICENSE-${PKGNAME}
	${MV} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/README.rst ${STAGEDIR}${PREFIX}/${PYPY_DIR}/README-${PKGNAME}.rst
	${MV} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/include/README ${STAGEDIR}${PREFIX}/${PYPY_DIR}/include/README-${PKGNAME}
	${RM} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/bin/${PYPY_TAG}
	${RM} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/bin/${PYPY_TAG}${PYPY_PYTHON_IMPL_VER_MAJOR}
	${RM} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/bin/python
	${RM} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/bin/python${PYPY_PYTHON_IMPL_VER_MAJOR}
	${LN} -fs ../${PYPY_DIR}/bin/${PYPY_TAG}${PYPY_PYTHON_IMPL_VER} ${STAGEDIR}${PREFIX}/bin/${PYPY_TAG}${PYPY_PYTHON_IMPL_VER}
	${FIND} ${STAGEDIR}${PREFIX}/${PYPY_DIR}/lib/${PYTHON_IMPL_MINOR} -name '*.so' | ${XARGS} ${STRIP_CMD}
.if ${PORT_OPTIONS:MBYTECOMPILE}
	@${ECHO} Byte-compile the Python standard library for optimization levels 0, 1 and 2 with invalidation mode ${COMPILEALL_INVALIDATIONMODE}
	(cd ${STAGEDIR}${PREFIX}/${PYPY_DIR} && ${SETENV} LD_LIBRARY_PATH=${WRKSRC}/pypy/goal \
		${WRKSRC}/pypy/goal/${PYPY_EXECUTABLE} -B -I -m compileall --invalidation-mode=${COMPILEALL_INVALIDATIONMODE} -q -x '/tests?/' -o 0 -o 1 -o 2 -d "${PREFIX}/${PYPY_DIR}/lib" lib)
.else
	@${ECHO} Distribution of byte-compiled standard library files is deactivated
.endif

do-test:
	# See https://bitbucket.org/pypy/buildbot/src/default/bot2/pypybuildbot/builds.py?at=default#builds.py-386
	# add_translated_tests()
	(cd ${WRKSRC}; \
		${SETENV} ${MAKE_ENV} TMPDIR=${WRKDIR}/build PYTHONPATH=${WRKSRC} \
		${WRKSRC}/pypy/goal/pypy-c testrunner/runner.py --root pypy --logfile=pytest-A.log \
			--parallel-runs ${MAKE_JOBS_NUMBER} \
			--config pypy/pytest-A.cfg --config pypy/pytest-A.py)
.for dir in lib-python pypy/module/pypyjit/test
	(cd ${WRKSRC}; \
		${SETENV} ${MAKE_ENV} TMPDIR=${WRKDIR}/build PYTHONPATH=${WRKSRC} \
		${WRKSRC}/pypy/goal/pypy-c pypy/test_all.py --basetemp ${WRKDIR}/build --pypy pypy/goal/pypy-c \
			${dir} )
.endfor
	(cd ${WRKSRC}/lib-python/2.7/test; \
		${SETENV} ${MAKE_ENV} TMPDIR=${WRKDIR}/build PYTHONPATH=${WRKSRC} \
		${WRKSRC}/pypy/goal/pypy-c regrtest.py -vvu all)

pkg-plist: stage
	${TAR} -tf ${WRKDIR}/build/${PYPY_DIR}.tar.bz2 > ${WRKDIR}/.plist-files-gen
	${REINPLACE_CMD} -e 's|^${PYPY_DIR}|%%PYPY_DIR%%|g' \
		-e 's|${PYPY_CFFI_VER}|%%PYPY_CFFI_VER%%|g' \
		-e 's/\(.*\/__pycache__\)\/$$/@dir \1/g' \
		-e '/\/$$/d' \
			${WRKDIR}/.plist-files-gen
	${ECHO} bin/${PYPY_TAG} > ${WRKDIR}/pkg-plist
	${SORT} ${WRKDIR}/.plist-files-gen | ${GREP} -v '\.orig' >> ${WRKDIR}/pkg-plist
	${CP} ${WRKDIR}/pkg-plist ${.CURDIR}/pkg-plist

.include <bsd.port.post.mk>
