diff --git a/Makefile.in b/Makefile.in index 1e1c179..468608d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -96,6 +96,7 @@ INSTALL_LIBRARY = @INSTALL_LIBRARY@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PYTHON_VERSION = @PYTHON_VERSION@ +PYTHON_SHARED = @PYTHON_SHARED@ CC = @CC@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ CFLAGS_WARNING = @CFLAGS_WARNING@ @@ -455,10 +456,18 @@ uninstall-binaries: # tohil python stuff # build-python-module: - python3 setup.py build + @if test "$(PYTHON_SHARED)" = "1"; then \ + python3 setup.py build; \ + else \ + echo "Skipping setup.py build for static Python"; \ + fi install-python-module: - python3 setup.py install + @if test "$(PYTHON_SHARED)" = "1"; then \ + python3 setup.py install; \ + else \ + echo "Skipping setup.py install for static Python"; \ + fi clean-python-module: rm -rf build/ dist/ pysrc/tohil.egg-info/ tests/__pycache__/ diff --git a/configure.ac b/configure.ac index 0cc8148..a0fd024 100644 --- a/configure.ac +++ b/configure.ac @@ -80,7 +80,7 @@ AC_ARG_WITH(python-version, --with-python-version python version (like 3 need_python_config="" if test "${with_python_include+set}" = "set"; then - PYTHON_INCLUDES="-I'${with_python_include}'" + PYTHON_INCLUDES="-I${with_python_include}" AC_MSG_RESULT([using python includes of... "$PYTHON_INCLUDES"]) else need_python_config="1" @@ -120,6 +120,37 @@ if test "$need_python_config" = "1"; then fi fi +# Check for pyconfig.h and Py_ENABLE_SHARED + +python_save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" + +AC_CHECK_HEADER( + [pyconfig.h], [ + AC_MSG_CHECKING([whether Python is built as a shared library]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + #ifndef Py_ENABLE_SHARED + #error "Python not built with shared library support" + #endif + ]], [])], + [ + AC_MSG_RESULT([yes]) + PYTHON_SHARED=1 + ], + [ + AC_MSG_RESULT([no]) + PYTHON_SHARED=0 + ]) + + ], [AC_MSG_ERROR([Cannot find pyconfig.h from $PYTHON_INCLUDES])] +) + +CPPFLAGS="$python_save_CPPFLAGS" + +AC_SUBST(PYTHON_SHARED) AC_SUBST(PYTHON_INCLUDES) AC_SUBST(PYTHON_LIB_DIR) AC_SUBST(PYTHON_VERSION) diff --git a/generic/tohil.c b/generic/tohil.c index 277ae7d..ab9093a 100644 --- a/generic/tohil.c +++ b/generic/tohil.c @@ -18,7 +18,10 @@ #include #include -#include + +#ifdef Py_ENABLE_SHARED +# include +#endif #include #include @@ -1023,7 +1026,7 @@ TohilCall_Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons PyObject *pObjParent = NULL; PyObject *pObj = pMainModule; PyObject *pObjStr = NULL; - char *dot = index(objandfn, '.'); + char *dot = strchr(objandfn, '.'); while (dot != NULL) { pObjParent = pObj; @@ -1047,7 +1050,7 @@ TohilCall_Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons } objandfn = dot + 1; - dot = index(objandfn, '.'); + dot = strchr(objandfn, '.'); } PyObject *pFn = PyObject_GetAttrString(pObj, objandfn); @@ -2886,7 +2889,7 @@ tclobj_nb_unaryop(PyObject *v, enum tclobj_unary_op operator) } else { switch (operator) { case Abs: - return PyLong_FromLongLong(labs(wideV)); + return PyLong_FromLongLong(llabs(wideV)); case Negative: return PyLong_FromLongLong(-wideV); @@ -4582,6 +4585,8 @@ static struct PyModuleDef TohilModule = { /* Shared initialisation begins here */ +PyMODINIT_FUNC PyInit__tohil(void); + // // this is the entry point called when the tcl interpreter loads the tohil shared library // @@ -4622,6 +4627,7 @@ Tohil_Init(Tcl_Interp *interp) } } +#ifdef Py_ENABLE_SHARED // NB without this ugly hack then on linux if tcl starts // python then python gets errors loading C shared libraries // such as "import sqlite3", where loading the shared library @@ -4631,7 +4637,14 @@ Tohil_Init(Tcl_Interp *interp) if (dlopen(python_lib, RTLD_GLOBAL | RTLD_LAZY) == NULL) { // fprintf(stderr, "load %s failed\n", python_lib); } - +#else + // This structure will be added to the list of built-in modules + static struct _inittab tohil_inittab[] = { + {"tohil", PyInit__tohil}, + {NULL, NULL} // Sentinel + }; + PyImport_ExtendInittab(tohil_inittab); +#endif // initialize python but since tcl is the parent, // pass 0 for initsigs, so python will not register // signal handlers