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
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
-
*) 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.
#
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
EXTRA_DIST += m4/progtest.m4
EXTRA_DIST += m4/stdint_h.m4
EXTRA_DIST += m4/uintmax_t.m4
+EXTRA_DIST += m4/pythonhead.m4
--- /dev/null
+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"
+])
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
--- /dev/null
+# $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
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),
- )
-