summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <jdahlin@async.com.br>2003-01-07 13:07:21 +0000
committerJohan Dahlin <zilch@src.gnome.org>2003-01-07 13:07:21 +0000
commit717914fd814ac64d6896c545a090c2e9e177ee96 (patch)
treece715b1a3497a9dd319fa910f0a5265163172958
parent82463e623f2fd2785f3230c1b547dde11853d894 (diff)
downloadpygtk-717914fd814ac64d6896c545a090c2e9e177ee96.tar.gz
Added distutils support
2003-01-07 Johan Dahlin <jdahlin@async.com.br> * setup.py, MANIFEST.in: Added distutils support * Makefile.am (EXTRA_DIST): Added setup.py and MANIFEST.in here. * .cvsignore: Add build/dist/MANIFEST here
-rw-r--r--.cvsignore4
-rw-r--r--ChangeLog10
-rw-r--r--MANIFEST.in10
-rw-r--r--Makefile.am2
-rwxr-xr-xsetup.py394
5 files changed, 418 insertions, 2 deletions
diff --git a/.cvsignore b/.cvsignore
index 020feb86..c86a44e4 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -32,4 +32,6 @@ pango.c
pygtk-2.0.pc
pygtk.spec
atk.c
-
+build
+dist
+MANIFEST
diff --git a/ChangeLog b/ChangeLog
index b1ba2990..ab705326 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-01-07 Johan Dahlin <jdahlin@async.com.br>
+
+ * setup.py, MANIFEST.in: Added distutils support
+
+ * Makefile.am (EXTRA_DIST): Added setup.py and MANIFEST.in here.
+
+ * .cvsignore: Add build/dist/MANIFEST here
+
2003-01-06 Jon Trowbridge <trow@ximian.com>
* gtk/pygtktreemodel.c (pygtk_generic_tree_model_get_path):
@@ -6,7 +14,7 @@
2003-01-05 Johan Dahlin <jdahlin@async.com.br>
* gtk/libglade.override: protect config.h by an ifdef.
-
+
2003-01-01 Johan Dahlin <jdahlin@async.com.br>
* gtk/gtk.override (_wrap_gtk_text_buffer_insert_at_cursor)
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 00000000..c6005a89
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,10 @@
+exclude atk.c pango.c gtk/gtk.c gtk/gdk.c gtk/libglade.c
+include ChangeLog AUTHORS COPYING MAPPING NEWS README THREADS TODO
+include MANIFEST.in
+include pygobject.h pygobject-private.h
+include *.defs *.override
+include pygtk.py pygtk-2.0.pc.in
+recursive-include gtk *.override *.defs *.h
+recursive-include codegen README.defs *.py pygtk-codegen-2.0.in
+recursive-include examples README *.py *.xpm
+global-exclude */CVS/* .cvsignore
diff --git a/Makefile.am b/Makefile.am
index 5f2481c3..30694421 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,8 @@ EXTRA_DIST += \
THREADS \
config.h.win32 \
makefile.msc \
+ setup.py \
+ MANIFEST.in \
examples/atk/atk-demo.py \
examples/gobject/signal.py \
examples/gobject/properties.py \
diff --git a/setup.py b/setup.py
new file mode 100755
index 00000000..a6302345
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,394 @@
+#!/usr/bin/env python
+#
+# setup.py - distutils configuration for pygtk
+#
+# TODO:
+# pygtk.spec(.in)
+# Use codegen directly instead of os.system
+# Numeric support
+# win32 testing
+# install *.pyc for codegen
+# GtkGL
+"""Python Bindings for the GTK Widget Set.
+
+PyGTK is a set of bindings for the GTK widget set. It provides an object oriented interface that is slightly higher level than the C one. It automatically does all the type casting and reference counting that you would have to do normally with the C API. You can find out more on the official homepage, http://www.daa.com.au/~james/pygtk/"""
+
+from commands import getoutput
+import fnmatch
+import os
+import string
+import sys
+
+from distutils.command.build import build
+from distutils.command.build_ext import build_ext
+from distutils.command.install_lib import install_lib
+from distutils.core import setup
+from distutils.extension import Extension
+
+MAJOR_VERSION = 1
+MINOR_VERSION = 99
+MICRO_VERSION = 14
+
+VERSION = "%d.%d.%d" % (MAJOR_VERSION,
+ MINOR_VERSION,
+ MICRO_VERSION)
+
+GOBJECT_REQUIRED = '2.0.0'
+ATK_REQUIRED = '1.0.0'
+PANGO_REQUIRED = '1.0.0'
+GTK_REQUIRED = '2.0.0'
+LIBGLADE_REQUIRED = '2.0.0'
+
+PYGTK_SUFFIX = '2.0'
+PYGTK_SUFFIX_LONG = 'gtk-' + PYGTK_SUFFIX
+
+GLOBAL_INC = ['.', 'gtk']
+GLOBAL_MACROS = [('VERSION', '"%s"' % VERSION),
+ ('PYGTK_MAJOR_VERSION', MAJOR_VERSION),
+ ('PYGTK_MINOR_VERSION', MINOR_VERSION),
+ ('PYGTK_MICRO_VERSION', MICRO_VERSION)]
+
+DEFS_DIR = 'share/pygtk/%s/defs' % PYGTK_SUFFIX
+CODEGEN_DIR = 'share/pygtk/%s/codegen' % PYGTK_SUFFIX
+INCLUDE_DIR = 'include/pygtk-%s' % PYGTK_SUFFIX
+
+class PyGtkInstallLib(install_lib):
+ local_outputs = []
+ local_inputs = []
+ def run(self):
+ install_dir = self.install_dir
+ self.prefix = os.sep.join(install_dir.split(os.sep)[:-4])
+
+ # Install everything in site-packages/gtk-2.0
+ self.install_dir = os.path.join(self.install_dir, PYGTK_SUFFIX_LONG)
+ install_lib.run(self)
+
+ # Except these three
+ self.install_codegen(install_dir)
+ self.install_pc(install_dir)
+ self.install_pth(install_dir)
+ self.install_pygtk(install_dir)
+
+ def install_template(self, filename, install_dir):
+ """Install template filename into target directory install_dir."""
+ output_file = os.path.split(filename)[-1][:-3]
+ exec_prefix = os.path.join(self.prefix, 'bin')
+ includedir = os.path.join(self.prefix, 'include')
+ datadir = os.path.join(self.prefix, 'share')
+
+ template = open(filename).read()
+ template = template.replace('@datadir@', datadir)
+ template = template.replace('@exec_prefix@', exec_prefix)
+ template = template.replace('@includedir@', includedir)
+ template = template.replace('@prefix@', self.prefix)
+ template = template.replace('@PYTHON@', sys.executable)
+ template = template.replace('@VERSION@', VERSION)
+
+ output = os.path.join(install_dir, output_file)
+ self.mkpath(install_dir)
+ open(output, 'w').write(template)
+ self.local_inputs.append(filename)
+ self.local_outputs.append(output)
+ return output
+
+ def install_codegen(self, install_dir):
+ codegen = os.path.join('codegen', 'pygtk-codegen-2.0.in')
+ file = self.install_template(codegen,
+ os.path.join(self.prefix, 'bin'))
+ os.chmod(file, 0755)
+
+ def install_pc(self, install_dir):
+ install_dir = os.path.join(self.prefix, 'lib', 'pkgconfig')
+ self.install_template('pygtk-2.0.pc.in', install_dir)
+
+ def install_pth(self, install_dir):
+ """Write the pygtk.pth file"""
+ file = os.path.join(install_dir, 'pygtk.pth')
+ open(file, 'w').write(PYGTK_SUFFIX_LONG)
+ self.local_outputs.append(file)
+ self.local_inputs.append('pygtk.pth')
+
+ def install_pygtk(self, install_dir):
+ """install pygtk.py in the right place."""
+ self.copy_file('pygtk.py', install_dir)
+ self.local_outputs.append(os.path.join(install_dir, 'pygtk.py'))
+ self.local_inputs.append('pygtk.py')
+
+ def get_outputs(self):
+ return install_lib.get_outputs(self) + self.local_outputs
+
+ def get_inputs(self):
+ return install_lib.get_inputs(self) + self.local_inputs
+
+class PyGtkBuild(build):
+ pass
+PyGtkBuild.user_options.append(('enable-threading', None,
+ 'enable threading support'))
+
+class PyGtkBuildExt(build_ext):
+ def build_extension(self, ext):
+ # Generate eventual templates before building
+ ext.generate()
+ build_ext.build_extension(self, ext)
+
+class PkgConfigExtension(Extension):
+ can_build_ok = None
+ def __init__(self, **kwargs):
+ name = kwargs['pkc_name']
+ kwargs['include_dirs'] = self.get_include_dirs(name) + GLOBAL_INC
+ kwargs['define_macros'] = GLOBAL_MACROS
+ kwargs['libraries'] = self.get_libraries(name)
+ kwargs['library_dirs'] = self.get_library_dirs(name)
+ self.pkc_name = kwargs['pkc_name']
+ self.pkc_version = kwargs['pkc_version']
+ del kwargs['pkc_name'], kwargs['pkc_version']
+ Extension.__init__(self, **kwargs)
+
+ def get_include_dirs(self, name):
+ output = getoutput('pkg-config --cflags-only-I %s' % name)
+ return output.replace('-I', '').split()
+
+ def get_libraries(self, name):
+ output = getoutput('pkg-config --libs-only-l %s' % name)
+ return output.replace('-l', '').split()
+
+ def get_library_dirs(self, name):
+ output = getoutput('pkg-config --libs-only-L %s' % name)
+ return output.replace('-L', '').split()
+
+ def can_build(self):
+ """If the pkg-config version found is good enough"""
+ if self.can_build_ok != None:
+ return self.can_build_ok
+
+ retval = os.system('pkg-config --exists %s' % self.pkc_name)
+ if retval:
+ print "* Could not find %s." % self.pkc_name
+ self.can_build_ok = 0
+ return 0
+
+ orig_version = getoutput('pkg-config --modversion %s' % self.pkc_name)
+ version = map(int, orig_version.split('.'))
+ pkc_version = map(int, self.pkc_version.split('.'))
+
+ if version >= pkc_version:
+ self.can_build_ok = 1
+ return 1
+ else:
+ print "Warning: Too old version of %s" % self.pkc_name
+ print " Need %s, but %s is installed" % \
+ (self.pkc_version, orig_version)
+ self.can_build_ok = 0
+ return 0
+
+ def generate(self):
+ pass
+
+class Template:
+ def __init__(self, override, output, defs, prefix, register=[]):
+ self.override = override
+ self.defs = defs
+ self.register = register
+ self.output = output
+ self.prefix = prefix
+
+ def check_dates(self):
+ if not os.path.exists(self.output):
+ return 0
+
+ files = self.register[:]
+ files.append(self.override)
+# files.append('setup.py')
+ files.append(self.defs)
+
+ newest = 0
+ for file in files:
+ test = os.stat(file)[8]
+ if test > newest:
+ newest = test
+
+ if newest < os.stat(self.output)[8]:
+ return 1
+ return 0
+
+ def generate(self):
+ if self.check_dates():
+ return
+
+ s = 'python codegen/codegen.py'
+ for item in self.register:
+ s += ' --register %s' % item
+ s += ' --override %s' % self.override
+ s += ' --prefix %s %s' % (self.prefix, self.defs)
+ s += ' > %s ' % self.output
+
+ print '** Generating %s' % self.output
+ os.system(s)
+
+class TemplateExtension(PkgConfigExtension):
+ def __init__(self, **kwargs):
+ name = kwargs['name']
+ defs = kwargs['defs']
+ output = defs[:-5] + '.c'
+ override = kwargs['override']
+ self.templates = []
+ self.templates.append(Template(override, output, defs, 'py' + name,
+ kwargs['register']))
+
+ del kwargs['register'], kwargs['override'], kwargs['defs']
+
+ if kwargs.has_key('output'):
+ kwargs['name'] = kwargs['output']
+ del kwargs['output']
+
+ PkgConfigExtension.__init__(self, **kwargs)
+
+ def generate(self):
+ map(lambda x: x.generate(), self.templates)
+
+def list_files(dir):
+ """List all files in a dir, with filename match support:
+ for example: glade/*.glade will return all files in the glade directory
+ that matches *.glade. It also looks up the full path"""
+ if dir.find(os.sep) != -1:
+ parts = dir.split(os.sep)
+ dir = string.join(parts[:-1], os.sep)
+ pattern = parts[-1]
+ else:
+ pattern = dir
+ dir = '.'
+
+ dir = os.path.abspath(dir)
+ retval = []
+ for file in os.listdir(dir):
+ if fnmatch.fnmatch(file, pattern):
+ retval.append(os.path.join(dir, file))
+ return retval
+
+def have_pkgconfig():
+ """Checks for the existence of pkg-config"""
+ if os.system('pkg-config 2> /dev/null') == 256:
+ return 1
+
+# GObject
+gobject = PkgConfigExtension(name='gobject', pkc_name='gobject-2.0',
+ pkc_version=GOBJECT_REQUIRED,
+ sources=['pygboxed.c',
+ 'pygobject.c',
+ 'pygtype.c',
+ 'gobjectmodule.c'])
+# Atk
+atk = TemplateExtension(name='atk', pkc_name='atk',
+ pkc_version=ATK_REQUIRED,
+ sources=['atkmodule.c', 'atk.c'],
+ register=['atk-types.defs'],
+ override='atk.override',
+ defs='atk.defs')
+# Pango
+pango = TemplateExtension(name='pango', pkc_name='pango',
+ pkc_version=PANGO_REQUIRED,
+ sources=['pango.c', 'pangomodule.c'],
+ register=['pango-types.defs'],
+ override='pango.override',
+ defs='pango.defs')
+# Gdk (template only)
+gdk_template = Template('gtk/gdk.override', 'gtk/gdk.c',
+ defs='gtk/gdk.defs', prefix='pygdk',
+ register=['atk-types.defs',
+ 'pango-types.defs',
+ 'gtk/gdk-types.defs'])
+# Gtk+
+gtk = TemplateExtension(name='gtk', pkc_name='gtk+-2.0',
+ pkc_version=GTK_REQUIRED,
+ output='gtk._gtk',
+ sources=['gtk/gtkmodule.c',
+ 'gtk/gtkobject-support.c',
+ 'gtk/gtk-types.c',
+ 'gtk/pygtktreemodel.c',
+ 'gtk/pygtkcellrenderer.c',
+ 'gtk/gdk.c',
+ 'gtk/gtk.c'],
+ register=['pango-types.defs',
+ 'gtk/gdk-types.defs',
+ 'gtk/gtk-types.defs'],
+ override='gtk/gtk.override',
+ defs='gtk/gtk.defs')
+gtk.templates.append(gdk_template)
+
+# Libglade
+libglade = TemplateExtension(name='libglade', pkc_name='libglade-2.0',
+ pkc_version=LIBGLADE_REQUIRED,
+ output='gtk.glade',
+ defs='gtk/libglade.defs',
+ sources=['gtk/libglademodule.c',
+ 'gtk/libglade.c'],
+ register=['gtk/gtk-types.defs',
+ 'gtk/libglade.defs'],
+ override='gtk/libglade.override')
+
+
+data_files = []
+ext_modules = []
+py_modules = []
+
+if not have_pkgconfig():
+ print "Error, could not find pkg-config"
+ raise SystemExit
+
+if gobject.can_build():
+ ext_modules.append(gobject)
+ data_files.append((INCLUDE_DIR, ('pygobject.h',)))
+ data_files.append((CODEGEN_DIR, list_files('codegen/*.py')))
+else:
+ print
+ print 'ERROR: Nothing to do, gobject could not be found and is essential.'
+ raise SystemExit
+if atk.can_build():
+ ext_modules.append(atk)
+ data_files.append((DEFS_DIR, ('atk.defs', 'atk-types.defs')))
+if pango.can_build():
+ ext_modules.append(pango)
+ data_files.append((DEFS_DIR, ('pango.defs', 'pango-types.defs')))
+if gtk.can_build():
+ ext_modules.append(gtk)
+ data_files.append((INCLUDE_DIR, ('gtk/pygtk.h',)))
+ data_files.append((DEFS_DIR, ('gtk/gdk.defs', 'gtk/gdk-types.defs',
+ 'gtk/gtk.defs', 'gtk/gtk-types.defs',
+ 'gtk/gtk-extrafuncs.defs')))
+ py_modules += ['gtk.compat', 'gtk.keysyms']
+if libglade.can_build():
+ ext_modules.append(libglade)
+ data_files.append((DEFS_DIR, ('gtk/libglade.defs',)))
+
+if '--enable-threading' in sys.argv:
+ try:
+ import thread
+ except ImportError:
+ print "Warning: Could not import thread module, disabling threading"
+ else:
+ GLOBAL_MACROS.append(('ENABLE_PYGTK_THREADING', 1))
+
+ name = 'gthread-2.0'
+ for module in ext_modules:
+ raw = getoutput('pkg-config --libs-only-l %s' % name)
+ module.extra_link_args += raw.split()
+ raw = getoutput('pkg-config --cflags-only-I %s' % name)
+ module.extra_compile_args.append(raw)
+
+doclines = __doc__.split("\n")
+
+setup(name="pygtk",
+ url='http://www.daa.com.au/~james/pygtk/',
+ version=VERSION,
+ license='LGPL',
+ platforms=['yes'],
+ maintainer="James Henstridge",
+ maintainer_email="james@daa.com.au",
+ description = doclines[0],
+ long_description = "\n".join(doclines[2:]),
+ py_modules=py_modules,
+ ext_modules=ext_modules,
+ data_files=data_files,
+ cmdclass={'install_lib': PyGtkInstallLib,
+ 'build_ext': PyGtkBuildExt,
+ 'build': PyGtkBuild})