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.

Reply via email to