]> granicus.if.org Git - yasm/commitdiff
Hook Python module into the build (even though it's pretty incomplete),
authorPeter Johnson <peter@tortall.net>
Tue, 4 Apr 2006 06:07:32 +0000 (06:07 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 4 Apr 2006 06:07:32 +0000 (06:07 -0000)
enabled with --enable-python (defaults to auto-detect).

Thanks to some magic in python-yasm/Makefile.inc and setup.py, this actually
plays nicely with automake distcheck.

* m4/pythonhead.m4: Script to find Python.h.
* m4/Makefile.inc: Include it in distfiles.
* configure.ac: Add --enable-python option and Python and Pyrex detection.
* tools/Makefile.inc: Pull tools/python-yasm/Makefile.inc into build.
* python-yasm/Makefile.inc: Add automake build magic for extension.
* setup.py: Likewise.

svn path=/trunk/yasm/; revision=1456

Makefile.am
configure.ac
m4/Makefile.inc
m4/pythonhead.m4 [new file with mode: 0644]
tools/Makefile.inc
tools/python-yasm/Makefile.inc [new file with mode: 0644]
tools/python-yasm/setup.py

index 45e5dde36c140e4ced4f8a985c6f21e4079777d9..d2921e1e783cd88f27de42bba45412cb99aaad11 100644 (file)
@@ -93,8 +93,16 @@ ACLOCAL_AMFLAGS = -I m4
 
 distclean-local:
        -rm -rf results
+if HAVE_PYTHON
+       -rm -rf build
+endif
+
+if HAVE_PYTHON
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) config.h python-build
+install-hook: python-install
+uninstall-hook: python-uninstall
+endif
 
 if BUILD_MAN
 MAINTAINERCLEANFILES = $(dist_man_MANS)
 endif
-
index cdf977ee7b127762a561fe32ec9efd1ad4fcc0f8..95d47b9a8c99505e416b49f0018669e9b295ae87 100644 (file)
@@ -49,6 +49,14 @@ AC_HELP_STRING([--enable-gcov],[Enable gcov code coverage (requires GCC)]),
   *) AC_MSG_ERROR([bad value ${enableval} for --enable-gcov]) ;;
 esac])
 
+AC_ARG_ENABLE(python,
+AC_HELP_STRING([--enable-python],[Build Python bindings]),
+[case "${enableval}" in
+  yes) enable_python="yes" ;;
+  no)  enable_python="no" ;;
+  *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
+esac], enable_python="auto")
+
 #
 # Checks for programs.
 #
@@ -244,6 +252,43 @@ AC_SUBST(CCLD_FOR_BUILD)
 HOST_CC="$CC_FOR_BUILD"
 AC_SUBST(HOST_CC)
 
+# Detect if we can build Python bindings
+# (needs Python, Python headers, and Pyrex)
+if test x$enable_python = xno; then
+    have_python=no
+else
+    AC_MSG_NOTICE([Checking to see if we can build Python bindings])
+    have_python=no
+    AM_PATH_PYTHON(2.4)
+
+    if test -z "$PYTHON" ; then
+        AC_MSG_WARN([Python not found])
+    else
+        AC_CHECK_PROGS(PYREX, pyrexc)
+
+        if test -z "$PYREX" ; then
+            have_pyrex=no
+        else
+            have_pyrex=yes
+        fi
+
+        AM_CHECK_PYTHON_HEADERS(have_python_headers=yes,have_python_headers=no)
+
+       if test x$have_pyrex = xyes -a x$have_python_headers = xyes ; then
+           have_python=yes
+        fi
+    fi
+
+    if test x$have_python = xno ; then
+        if test x$enable_python = xyes ; then
+            AC_MSG_ERROR([Building Python explicitly requested, but can't build Python bindings because either Pyrex, Python headers or a suitable Python version was not found])
+        else
+            AC_MSG_WARN([Couldn't find either Pyrex, the Python headers or a suitable version of Python, not building Python bindings])
+        fi
+    fi               
+fi
+
+AM_CONDITIONAL(HAVE_PYTHON, test x$have_python = xyes)
 
 AC_CONFIG_FILES([Makefile
        po/Makefile.in
index 6cd215223ec332945cbb05ef5531279e9ddb9983..3df185a9708d4e09d4e0666b757567d2be8cc200 100644 (file)
@@ -26,3 +26,4 @@ EXTRA_DIST += m4/longlong.m4
 EXTRA_DIST += m4/progtest.m4
 EXTRA_DIST += m4/stdint_h.m4
 EXTRA_DIST += m4/uintmax_t.m4
+EXTRA_DIST += m4/pythonhead.m4
diff --git a/m4/pythonhead.m4 b/m4/pythonhead.m4
new file mode 100644 (file)
index 0000000..1e0f2b6
--- /dev/null
@@ -0,0 +1,24 @@
+dnl a macro to check for ability to create python extensions
+dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
+dnl function also defines PYTHON_INCLUDES
+AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
+[AC_REQUIRE([AM_PATH_PYTHON])
+AC_MSG_CHECKING(for headers required to compile python extensions)
+dnl deduce PYTHON_INCLUDES
+py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
+py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"`
+PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
+if test "$py_prefix" != "$py_exec_prefix"; then
+  PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
+fi
+AC_SUBST(PYTHON_INCLUDES)
+dnl check if the headers exist:
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
+AC_TRY_CPP([#include <Python.h>],dnl
+[AC_MSG_RESULT(found)
+$1],dnl
+[AC_MSG_RESULT(not found)
+$2])
+CPPFLAGS="$save_CPPFLAGS"
+])
index 264b8e1643022388f0b79e3c0cb42317d1372d1f..56a4697f3344bd4c881ab42ef3420c84eb557d28 100644 (file)
@@ -2,6 +2,8 @@
 
 EXTRA_DIST += tools/re2c/Makefile.inc
 EXTRA_DIST += tools/gap/Makefile.inc
+EXTRA_DIST += tools/python-yasm/Makefile.inc
 
 include tools/re2c/Makefile.inc
 include tools/gap/Makefile.inc
+include tools/python-yasm/Makefile.inc
diff --git a/tools/python-yasm/Makefile.inc b/tools/python-yasm/Makefile.inc
new file mode 100644 (file)
index 0000000..3f0f8f4
--- /dev/null
@@ -0,0 +1,49 @@
+# $Id$
+if HAVE_PYTHON
+
+PYBINDING_DEPS  = tools/python-yasm/bytecode.pxi
+PYBINDING_DEPS += tools/python-yasm/coretype.pxi
+PYBINDING_DEPS += tools/python-yasm/expr.pxi
+PYBINDING_DEPS += tools/python-yasm/floatnum.pxi
+PYBINDING_DEPS += tools/python-yasm/intnum.pxi
+PYBINDING_DEPS += tools/python-yasm/symrec.pxi
+PYBINDING_DEPS += tools/python-yasm/value.pxi
+
+EXTRA_DIST += tools/python-yasm/setup.py
+EXTRA_DIST += tools/python-yasm/yasm.pyx
+EXTRA_DIST += $(PYBINDING_DEPS)
+
+yasm_python.c: $(srcdir)/tools/python-yasm/yasm.pyx $(PYBINDING_DEPS)
+       $(PYREX) -o $@ `test -f tools/python-yasm/yasm.pyx || echo '$(srcdir)/'`tools/python-yasm/yasm.pyx
+
+CLEANFILES += yasm_python.c
+
+# Now the Python build magic...
+python-setup.txt: Makefile
+       echo "includes=${DEFAULT_INCLUDES} ${INCLUDES} ${DEFS}" > python-setup.txt
+       echo "sources=${libyasm_a_SOURCES}" >> python-setup.txt
+       echo "srcdir=${srcdir}" >> python-setup.txt
+
+CLEANFILES += python-setup.txt
+
+.python-build: python-setup.txt yasm_python.c
+       -rm -rf build
+       $(PYTHON) `test -f tools/python-yasm/setup.py || echo '$(srcdir)/'`tools/python-yasm/setup.py build
+       touch .python-build
+python-build: .python-build
+
+CLEANFILES += .python-build
+
+python-install: .python-build
+       $(PYTHON) `test -f tools/python-yasm/setup.py || echo '$(srcdir)/'`tools/python-yasm/setup.py install "--install-lib=$(pythondir)"
+
+python-uninstall:
+       rm -f `$(PYTHON) -c "import sys;sys.path.insert(0, '${pythondir}'); import yasm; print yasm.__file__"`
+
+else
+
+python-build:
+python-install:
+python-uninstall:
+
+endif
index 545a3cad47fd56b5730c1201f7c7bf46792c7e26..53be808270b33d4cbb36ea3e2238081b7b49f977 100644 (file)
@@ -3,27 +3,90 @@
 from distutils.core import setup
 from distutils.extension import Extension
 from Pyrex.Distutils import build_ext
+from os.path import basename, join, exists
+import re
+
+def ReadSetup(filename):
+    """ReadSetup goes through filename and parses out the values stored
+    in the file.  Values need to be stored in a
+    \"key=value format\""""
+
+    #return val
+    opts = {}
+
+    fh = open(filename, 'r')
+    reobj = re.compile(r"([a-z]+)=(.+)")
+    for line in fh.readlines():
+        matchobj = reobj.search(line)
+
+        if matchobj is None:
+            raise "Error:  syntaxt error in setup.txt line: %s"%line
+
+        lab, val = matchobj.groups()
+        opts[lab] = val
+    return opts
+
+def ParseCPPFlags(str):
+    """parse the CPPFlags macro"""
+    incl_dir = []
+    cppflags = []
+
+    tokens = str.split()
+    # go through the list of compile flags.  treat search path args
+    # specially; otherwise just add to "extra_compile_args"
+    for tok in tokens:
+        if tok.startswith("-I"):
+            incl_dir.append(tok[2:])
+        else:
+            cppflags.append(tok)
+
+    return (incl_dir, cppflags)
+
+def ParseSources(str, srcdir):
+    """parse the Sources macro"""
+    sources = []
+
+    tokens = str.split()
+    # go through the list of source filenames
+    # do the dance of detecting if the source file is in the current
+    # directory, and if it's not, prepend srcdir
+    for tok in tokens:
+        fn = None
+        if tok.endswith(".c"):
+            fn = tok
+        elif tok.endswith(".y"):
+            fn = basename(tok)[:-2] + ".c"
+        else:
+            continue
+        if not exists(fn):
+            fn = join(srcdir, fn)
+        sources.append(fn)
+
+    return sources
+
+def RunSetup(incldir, cppflags, sources):
+    setup(
+          name='yasm',
+          version='0.0',
+          description='Python bindings for Yasm',
+          author='Michael Urman',
+          url='http://www.tortall.net/projects/yasm',
+          ext_modules=[
+                       Extension('yasm',
+                                 sources=sources,
+                                 extra_compile_args=cppflags,
+                                 include_dirs=incldir,
+                                 library_dirs=['.'],
+                                 libraries=['yasm'],
+                       ),
+                      ],
+          cmdclass = dict(build_ext=build_ext),
+         )
+
+if __name__ == "__main__":
+    opts = ReadSetup("python-setup.txt")
+    incldir, cppflags = ParseCPPFlags(opts["includes"])
+    sources = ParseSources(opts["sources"], opts["srcdir"])
+    sources.append('yasm_python.c')
+    RunSetup(incldir, cppflags, sources)
 
-setup(
-        name='yasm',
-        version='0.0',
-        description='Python bindings for Yasm',
-        author='Michael Urman',
-        url='http://www.tortall.net/projects/yasm',
-        ext_modules=[
-            Extension('yasm', ['yasm.pyx'],
-                depends=['bytecode.pxi',
-                         'coretype.pxi',
-                         'expr.pxi',
-                         'floatnum.pxi',
-                         'intnum.pxi',
-                         'symrec.pxi',
-                         'value.pxi'],
-                include_dirs=['../..'],
-                library_dirs=['../..'],
-                libraries=['yasm'],
-            ),
-        ],
-        cmdclass = dict(build_ext=build_ext),
-    )
-