Instead of compiling python from source, we reuse libpythonX.Y.so from the build system. Only the python executable is recompiled as shared object.
While python 2.7, 3.3, 3.4 and 3.5 can be compiled, only the 2.7 actually works. The 3.Y executables require additional symbols/functions from OSv. A list for 3.5: ./scripts/check-libcfunc-avail.sh debug apps/python/ROOTFS/usr/lib/libpython3.5m.so.1.0 mkfifoat not found sched_getscheduler not found flistxattr not found unlinkat not found __wcscat_chk not found fsetxattr not found llistxattr not found fremovexattr not found lgetxattr not found listxattr not found sched_getparam not found sched_setscheduler not found sigtimedwait not found readlinkat not found fexecve not found mkdirat not found __wcsncpy_chk not found __wcscpy_chk not found lsetxattr not found clock_settime not found fgetxattr not found sched_rr_get_interval not found __xmknodat not found linkat not found removexattr not found getgrouplist not found sigpending not found sched_setparam not found fchownat not found getxattr not found renameat not found setxattr not found symlinkat not found waitid not found lremovexattr not found The GET file includes all required shared libraries. The install_shlibs() is called 4 times, until no new libs are required (actually, it only checks that no new libs were added - should be good enough). usr.manifest adds symlink /lib64 to /lib. This is required to run python simply as: ./scripts/run.py -e "/python" ./scripts/run.py -e "/python -c \"aa={1:22,3:44}; print aa; print 'asdf'\"" Otherwise, it was required to set PYTHONPATH, (like in ./scripts/run.py -e "--env=PYTHONPATH=/lib/python2.7/ /python"). Signed-off-by: Justin Cinkelj <justin.cink...@xlab.si> --- python/.gitignore | 2 ++ python/GET | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ python/Makefile | 10 ++++++ python/Python-2.7.h | 9 +++++ python/Python-3.3.h | 16 +++++++++ python/Python-3.4.h | 15 ++++++++ python/Python-3.5.h | 16 +++++++++ 7 files changed, 168 insertions(+) create mode 100644 python/.gitignore create mode 100755 python/GET create mode 100644 python/Makefile create mode 100644 python/Python-2.7.h create mode 100644 python/Python-3.3.h create mode 100644 python/Python-3.4.h create mode 100644 python/Python-3.5.h diff --git a/python/.gitignore b/python/.gitignore new file mode 100644 index 0000000..b807de2 --- /dev/null +++ b/python/.gitignore @@ -0,0 +1,2 @@ +build +usr.manifest diff --git a/python/GET b/python/GET new file mode 100755 index 0000000..4371560 --- /dev/null +++ b/python/GET @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +set -e + +#VERSION=2.7 +BASEDIR=$PWD +ROOTFS=$BASEDIR/ROOTFS + +case "$VERSION" in +2.7) + PYTHON_C_URL="https://raw.githubusercontent.com/python/cpython/$VERSION/Modules/python.c" + PYLIB_VERSION="2.7" + ;; +3.3) + PYTHON_C_URL="https://raw.githubusercontent.com/python/cpython/$VERSION/Modules/python.c" + PYLIB_VERSION="3.3m" + ;; +3.4) + PYTHON_C_URL="https://raw.githubusercontent.com/python/cpython/$VERSION/Modules/python.c" + PYLIB_VERSION="3.4m" + ;; +3.5) + PYTHON_C_URL="https://raw.githubusercontent.com/python/cpython/$VERSION/Programs/python.c" + # we have to link agains libpython3.5m.so.1.0 + PYLIB_VERSION="3.5m" + ;; +*) + echo "Unknown python version" + exit 1 +esac + +install_shlibs() { +SHLIBS="" +SHLIBS+=" $ROOTFS/python$VERSION.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/python2.7/config/libpython2.7.so is a symlink to ../../libpython2.7.so, +# so create a valid destination to avoid ldd error due to dangling symlink. +(cd $ROOTFS/lib && ln -sf ../usr/lib/libpython$PYLIB_VERSION.so.1.0 libpython$PYLIB_VERSION.so) +echo "$SHLIBS_COUNT" +} + +main() { +mkdir -p build/ + +# compile python executable +wget $PYTHON_C_URL -O build/python-$VERSION.c +sed -i "s|Python.h|../Python-$VERSION.h|" build/python-$VERSION.c +gcc -o build/python$VERSION.so build/python-$VERSION.c -fPIC -shared -lpython${PYLIB_VERSION} + +# copy python executable, required .so libs and .py files to ROOTFS +rm -rf "$ROOTFS" +mkdir -p "$ROOTFS/usr/lib" +mkdir -p "$ROOTFS/lib/python$VERSION" + +cp build/python$VERSION.so "$ROOTFS" +install_shlibs +# TODO /lib64/python2.7/ should not be hardcoded? +# FIXME /lib64/python$VERSION/ can contain additional python packeges - +# I doubt /lib64/python2.7/{idlelib,distutils,email,bsddb} are part of minimal +# python installation. Especially as I don't see them in /lib64/python3.3 just +# after "dnf install python33". For minimal image size, build system should have +# clean python instalation. +PY_LIB1=/lib64/python$VERSION/ +rsync -a $PY_LIB1 $ROOTFS/lib/python$VERSION/ --exclude test --exclude unittest \ + --exclude site-packages --exclude pydoc_data \ + --exclude '*.pyc' --exclude '*.pyo' --exclude '*.egg-info' + +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 +} + +# generate usr.manifest +# /lib63 -> /lib symlink is added to remove need for --env=PYTHONPATH=/lib/python2.7/, +# as _my_ build system has python .py files in /lib64/python2.7/ +cat <<EOF > usr.manifest + +/python: ->/python$VERSION.so +/python$VERSION: ->/python$VERSION.so +/lib64: ->/lib +/**: \${MODULE_DIR}/ROOTFS/** +EOF + +main diff --git a/python/Makefile b/python/Makefile new file mode 100644 index 0000000..88215ff --- /dev/null +++ b/python/Makefile @@ -0,0 +1,10 @@ + +.PHONY: module clean + +# Only version 2.7 actualy works. The 3.[345] require additional libc functions. +module: + VERSION=2.7 ./GET + +clean: + rm -fr ROOTFS build usr.manifest + rm -f python-[23].[0-9].c diff --git a/python/Python-2.7.h b/python/Python-2.7.h new file mode 100644 index 0000000..9240010 --- /dev/null +++ b/python/Python-2.7.h @@ -0,0 +1,9 @@ +#include <wchar.h> +#include <wctype.h> +#include <stdio.h> + +// from Include/pyport.h +#define PyAPI_FUNC(RTYPE) RTYPE +#define PyAPI_DATA(RTYPE) extern RTYPE + +PyAPI_FUNC(int) Py_Main(int argc, char **argv); diff --git a/python/Python-3.3.h b/python/Python-3.3.h new file mode 100644 index 0000000..47c1164 --- /dev/null +++ b/python/Python-3.3.h @@ -0,0 +1,16 @@ +#include <wchar.h> +#include <wctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// from Include/pyport.h +#define PyAPI_FUNC(RTYPE) RTYPE +#define PyAPI_DATA(RTYPE) extern RTYPE + +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); +PyAPI_FUNC(void *) PyMem_Malloc(size_t); +PyAPI_FUNC(void) PyMem_Free(void *); +PyAPI_FUNC(wchar_t *) _Py_char2wchar( + const char *arg, + size_t *size); diff --git a/python/Python-3.4.h b/python/Python-3.4.h new file mode 100644 index 0000000..5a3c3f1 --- /dev/null +++ b/python/Python-3.4.h @@ -0,0 +1,15 @@ +#include <wchar.h> +#include <wctype.h> +#include <stdio.h> + +// from Include/pyport.h +#define PyAPI_FUNC(RTYPE) RTYPE +#define PyAPI_DATA(RTYPE) extern RTYPE + +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); +PyAPI_FUNC(wchar_t *) _Py_char2wchar( + const char *arg, + size_t *size); diff --git a/python/Python-3.5.h b/python/Python-3.5.h new file mode 100644 index 0000000..ccd7383 --- /dev/null +++ b/python/Python-3.5.h @@ -0,0 +1,16 @@ +#include <wchar.h> +#include <wctype.h> +#include <stdio.h> + +// from Include/pyport.h +#define PyAPI_FUNC(RTYPE) RTYPE +#define PyAPI_DATA(RTYPE) extern RTYPE + +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); +PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt); +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); +PyAPI_FUNC(wchar_t *) Py_DecodeLocale( + const char *arg, + size_t *size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); -- 2.9.4 -- 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.