support Python 2.7
authorPatrick Ohly <patrick.ohly@intel.com>
Fri, 20 Jun 2014 08:39:55 +0000 (10:39 +0200)
committerPatrick Ohly <patrick.ohly@intel.com>
Mon, 30 Jun 2014 13:57:23 +0000 (15:57 +0200)
Module initialization was done differently in Python 2.x.

The code should also work with different Python versions. What ties it
to 2.7 at the moment is only the dlopen(RTLD_GLOBAL) hack that is also
tying it to 3.3 instead of some arbitrary 3.x version.

The latest available Python developer files are picked by configure.
This can be overriden by passing "-D python_version=2.7/3.3".

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
configure
pycrosswalk.gyp
src/pycrosswalk.c

index 6371d52..5bcf78f 100755 (executable)
--- a/configure
+++ b/configure
@@ -10,4 +10,13 @@ fi
 
 echo To build use: ninja -C out/Default
 
-GYP_GENERATORS=ninja gyp $@ --depth=. pycrosswalk.gyp
+# Use most recent Python version. Can be overridden by passing
+# -D python_version=<version> to configure as argument.
+python_version=`pkg-config --list-all | grep '^python-[0-9]*\.[0-9]* ' | sed -e 's/python-//' -e 's/ .*//' | sort | tail -1`
+
+if [ ! "$python_version" ]; then
+   echo -e "\nPlease make sure that Python development files are found by pkg-config."
+   exit 1
+fi
+
+GYP_GENERATORS=ninja gyp -D python_version=$python_version $@ --depth=. pycrosswalk.gyp
index fb98273..93f01f8 100644 (file)
         'xwalk/XW_Extension_SyncMessage.h',
       ],
       'cflags': [
-        '<!@(pkg-config --cflags python-3.3)',
+        '<!@(pkg-config --cflags python-<(python_version))',
+        '-g',
         '-fPIC',
       ],
       'link_settings': {
         'ldflags': [
-          '<!@(pkg-config --libs-only-L --libs-only-other python-3.3)',
+          '<!@(pkg-config --libs-only-L --libs-only-other python-<(python_version))',
+          '-g',
         ],
         'libraries': [
-          '<!@(pkg-config --libs-only-l python-3.3) -lcallback',
+          '<!@(pkg-config --libs-only-l python-<(python_version)) -lcallback',
         ],
       },
     },
index 6c73ed8..4b30118 100644 (file)
@@ -50,11 +50,15 @@ static PyMethodDef PyXWalkMethods[] = {
   {NULL, NULL, 0, NULL}
 };
 
+static const char PY_XWALK_MODULE_NAME[] = "xwalk";
+
+#if PY_MAJOR_VERSION >= 3
 static struct PyModuleDef PyXWalkModule = {
   PyModuleDef_HEAD_INIT,
-  "xwalk", "", -1, PyXWalkMethods,
+  PY_XWALK_MODULE_NAME, "", -1, PyXWalkMethods,
   NULL, NULL, NULL, NULL
 };
+#endif
 
 static PyObject* py_post_message(PyObject* self, PyObject* args) {
   int instance;
@@ -186,7 +190,13 @@ static char* py_handle_message(XW_Instance instance,
 
   char* pass_string = NULL;
 
-  char* result_string = PyUnicode_AsUTF8(result_object);
+#if PY_MAJOR_VERSION >= 3
+  char* result_string = result_object != Py_None ? PyUnicode_AsUTF8(result_object) : NULL;
+#else
+  PyObject* str = result_object != Py_None ? PyUnicode_AsUTF8String(result_object) : NULL;
+  char* result_string = str ? PyBytes_AsString(str) : NULL;
+#endif
+      ;
   if (result_string)
     pass_string = strdup(result_string);
 
@@ -305,7 +315,13 @@ static void instance_closure(PyObject* callback, va_alist args) {
 int32_t XW_Initialize(XW_Extension extension, XW_GetInterface get_interface) {
   // Hack to avoid missing symbols if the python script we are loading tries
   // to do something funny with cpython.
-  void* handle = dlopen("libpython3.3m.so.1", RTLD_LAZY | RTLD_GLOBAL);
+  void* handle = dlopen(
+#if PY_MAJOR_VERSION >= 3
+                        "libpython3.3m.so.1",
+#else
+                        "libpython2.7.so.1",
+#endif
+                        RTLD_LAZY | RTLD_GLOBAL);
   if (!handle) {
     fprintf(stderr, "Could not load python shared library.\n");
     return XW_ERROR;
@@ -314,8 +330,12 @@ int32_t XW_Initialize(XW_Extension extension, XW_GetInterface get_interface) {
 
   Py_Initialize();
 
+#if PY_MAJOR_VERSION >= 3
   PyObject* xwalk_module = PyModule_Create(&PyXWalkModule);
-  PyDict_SetItemString(PyImport_GetModuleDict(), PyXWalkModule.m_name, xwalk_module);
+#else
+  PyObject *xwalk_module = Py_InitModule(PY_XWALK_MODULE_NAME, PyXWalkMethods);
+#endif
+  PyDict_SetItemString(PyImport_GetModuleDict(), PY_XWALK_MODULE_NAME, xwalk_module);
 
   if (!load_python_extension(extension, get_interface))
       return XW_ERROR;