Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- python3x/GET | 60 +++++++++++++++++++++++++++ python3x/Makefile | 8 ++++ python3x/README | 13 ++++++ python3x/python.c | 95 +++++++++++++++++++++++++++++++++++++++++++ python3x/usr.manifest | 4 ++ 5 files changed, 180 insertions(+) create mode 100755 python3x/GET create mode 100644 python3x/Makefile create mode 100644 python3x/README create mode 100644 python3x/python.c create mode 100644 python3x/usr.manifest
diff --git a/python3x/GET b/python3x/GET new file mode 100755 index 0000000..af03cb2 --- /dev/null +++ b/python3x/GET @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -e + +BASEDIR=$PWD +ROOTFS=$BASEDIR/ROOTFS + +PYTHON_PREFIX_DIR=`python3 -c 'import sys; print(sys.prefix)'` +PYTHON_MAJOR_VERSION=`python3 -c 'import sys; print(sys.version_info.major)'` +PYTHON_MINOR_VERSION=`python3 -c 'import sys; print(sys.version_info.minor)'` +PYTHON_VERSION="${PYTHON_MAJOR_VERSION}.${PYTHON_MINOR_VERSION}" + +install_shlibs() { +SHLIBS="" +SHLIBS+=" $ROOTFS/python.so " +SHLIBS+=" `find $ROOTFS -iname '*\.so' | grep -v '/site-packages/'` " +set +e +SHLIBS+=" `find $ROOTFS -iname '*\.so[\.0-9]*' | grep -v '/site-packages/'` " +set -e +SHLIBS_COUNT="`echo \"$SHLIBS\" | wc -l`" + +ldd $SHLIBS | grep -Po '(?<=> )/[^ ]+' | sort | uniq | grep -Pv 'lib(c|gcc|dl|m|util|rt|pthread|stdc\+\+|selinux|krb5|gssapi_krb5)\.so' | xargs -I {} install {} $ROOTFS/usr/lib +# ROOTFS/lib/python3.7/config/libpython3.7.so is a symlink to ../../libpython3.7.so, +# so create a valid destination to avoid ldd error due to dangling symlink. +(cd $ROOTFS/lib && ln -sf ../usr/lib/libpython${PYTHON_VERSION}m.so.1.0 libpython${PYTHON_VERSION}m.so) +echo "$SHLIBS_COUNT" +} + +main() { +mkdir -p build/ +gcc -o build/python.so python.c -fPIC -shared -lpython${PYTHON_VERSION}m + +rm -rf "$ROOTFS" +mkdir -p "$ROOTFS/usr/lib" +mkdir -p "$ROOTFS/lib/python${PYTHON_VERSION}" + +cp build/python.so "$ROOTFS" +install_shlibs +for dir in ${PYTHON_PREFIX_DIR}/lib*/python${PYTHON_VERSION}/ +do + rsync -a "$dir" $ROOTFS/lib/python${PYTHON_VERSION}/ --safe-links --exclude test --exclude unittest \ + --exclude '*.pyc' --exclude '*.pyo' --exclude '*.egg-info' +done + +SHLIBS_COUNT4=`install_shlibs` +echo "Python SHLIBS_COUNT4=$SHLIBS_COUNT4" +SHLIBS_COUNT3=`install_shlibs` +echo "Python SHLIBS_COUNT3=$SHLIBS_COUNT3" +SHLIBS_COUNT2=`install_shlibs` +echo "Python SHLIBS_COUNT2=$SHLIBS_COUNT2" +SHLIBS_COUNT1=`install_shlibs` +echo "Python SHLIBS_COUNT1=$SHLIBS_COUNT1" +if [ $SHLIBS_COUNT1 -ne $SHLIBS_COUNT2 ] +then + # if this happens, just add additional calls to install_shlibs() + echo "ERROR some libraries required by python might be missing" + exit 1 +fi +} + +main diff --git a/python3x/Makefile b/python3x/Makefile new file mode 100644 index 0000000..69c151f --- /dev/null +++ b/python3x/Makefile @@ -0,0 +1,8 @@ + +.PHONY: module clean + +module: + ./GET + +clean: + rm -fr ROOTFS build diff --git a/python3x/README b/python3x/README new file mode 100644 index 0000000..51e31f5 --- /dev/null +++ b/python3x/README @@ -0,0 +1,13 @@ +This app builds an image containing the already-compiled Python shared +object for Python 3.x (libpython3.7.so for example) installed on the build macine, +and some of the required libraries from the build machine. + +The python home directory is assumed to be installed under +<sys.prefix>/lib/python<sys.version_info.major>.<sys.version_info.minor>/ +where sys is Python package this script reads the sys.* values from. + +Example usage: + +./scripts/run.py -e "/python3" +./scripts/run.py -e "/python3 -c \"aa={1:22,3:44}; print aa; print 'asdf'\"" +./scripts/run.py --api -e "/python3 -m http.server 8000" diff --git a/python3x/python.c b/python3x/python.c new file mode 100644 index 0000000..51d41df --- /dev/null +++ b/python3x/python.c @@ -0,0 +1,95 @@ +/* Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. + +Copyright (c) 2000 BeOpen.com. All rights reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. All rights reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. + +See the file "LICENSE" for information on the history of this software, terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. + +This Python distribution contains no GNU General Public License (GPL) code, so it may be used in proprietary projects. There are interfaces to some GNU code but these are entirely optional. + +All trademarks referenced herein are property of their respective holders.*/ + +/* Minimal main program -- everything is loaded from the library */ + +//#include "Python.h" +#include <locale.h> +#include <wchar.h> +#include <stdio.h> + +extern void *PyMem_RawMalloc(size_t size); +extern void PyMem_RawFree(void *ptr); +extern char *_PyMem_RawStrdup(const char *str); +extern wchar_t *Py_DecodeLocale(const char* arg, size_t *size); +extern int Py_Main(int argc, wchar_t **argv); + +#ifdef __FreeBSD__ +#include <fenv.h> +#endif + +#ifdef MS_WINDOWS +int +wmain(int argc, wchar_t **argv) +{ + return Py_Main(argc, argv); +} +#else + +int +main(int argc, char **argv) +{ + wchar_t **argv_copy; + /* We need a second copy, as Python might modify the first one. */ + wchar_t **argv_copy2; + int i, res; + char *oldloc; + + argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); + argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); + if (!argv_copy || !argv_copy2) { + fprintf(stderr, "out of memory\n"); + return 1; + } + + /* 754 requires that FP exceptions run in "no stop" mode by default, + * and until C vendors implement C99's ways to control FP exceptions, + * Python requires non-stop mode. Alas, some platforms enable FP + * exceptions by default. Here we disable them. + */ +#ifdef __FreeBSD__ + fedisableexcept(FE_OVERFLOW); +#endif + + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + if (!oldloc) { + fprintf(stderr, "out of memory\n"); + return 1; + } + + setlocale(LC_ALL, ""); + for (i = 0; i < argc; i++) { + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); + if (!argv_copy[i]) { + PyMem_RawFree(oldloc); + fprintf(stderr, "Fatal Python error: " + "unable to decode the command line argument #%i\n", + i + 1); + return 1; + } + argv_copy2[i] = argv_copy[i]; + } + argv_copy2[argc] = argv_copy[argc] = NULL; + + setlocale(LC_ALL, oldloc); + PyMem_RawFree(oldloc); + res = Py_Main(argc, argv_copy); + for (i = 0; i < argc; i++) { + PyMem_RawFree(argv_copy2[i]); + } + PyMem_RawFree(argv_copy); + PyMem_RawFree(argv_copy2); + return res; +} +#endif diff --git a/python3x/usr.manifest b/python3x/usr.manifest new file mode 100644 index 0000000..88b8045 --- /dev/null +++ b/python3x/usr.manifest @@ -0,0 +1,4 @@ +/python3: ->/python.so +/lib64: ->/lib + +/**: ${MODULE_DIR}/ROOTFS/** -- 2.17.1 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.