Hello, I'm working so that people wanting to use SIP as a binding generator do not have to play with the custom build engine (which is required only by PyQt). I already contributed sipdistutils.py which lets compile SIP-generated bindings with distutils.
The next step is to compile SIP itself with distutils, and this is what the attached setup.py does. It's almost complete: - It builds and installs SIP correctly. Compared to the custom build system, the main differences is that the sip executable is put into the python scripts directory (by default: /usr/bin under Linux, c:\python\scripts under Windows), and the sip header file is put within the per-package python include directory (by default: /usr/include/python2.4/sip/sip.h under Linux, c:\python\include\sip\sip.h under Windows). - Of course, we now have all the fancy distutils options, so "setup.py bdist_wininst" will generate "sip-snapshot-20051130.win32-py2.4.exe" as expected, and "setup.py bdist_rpm" will generate "sip-snapshot_20051130-1.i386.rpm" and "sip-snapshot_20051130-1.src.rpm", and they all work correctly: $ rpm -qpl sip-snapshot_20051130-1.i386.rpm /usr/bin/sip /usr/include/python2.4/sip/sip.h /usr/lib/python2.4/site-packages/sip.so /usr/lib/python2.4/site-packages/sipdistutils.py /usr/lib/python2.4/site-packages/sipdistutils.pyc - I had to work around a couple of issues in distutils, and to add support for building native scripts (that is, executables). Not too bad though, as the compiler abstraction class in distutils already had a "link_executable" method, it's just that it was not hooked up everywhere as needed. - It's incomplete, as in it still does not generate sipconfig.py, but that's easy to add. It's the last step though, I wanted to make sure that everything else is OK. Phil, I'd appreciate if you (or others) could give this a go and confirm that it mostly works. I'll add support for generation of sipconfig.py in the next few days. -- Giovanni Bajo
#!/usr/bin/env python from distutils.core import setup, Extension from distutils.command.build_ext import build_ext from distutils.command.build import build from distutils.command.sdist import sdist from distutils.command.bdist_rpm import bdist_rpm from distutils.command.install import install from distutils.command.install_scripts import install_scripts from distutils.dist import Distribution import sys, os import glob sip_version = 0x040300 sip_version_str = "snapshot-20051130" desc = "SIP - Python C/C++ Bindings Generator" long_desc = """\ SIP is a tool for automatically generating Python bindings for C and C++ libraries. Bindings are fast to load, have minimum memory consumption. SIP features automatic conversion between standard Python and C/C++ data types, supports function and methods overloading, allows to derive Python classes from C++ classes, (re)implementation virtual methods, C++ exceptions (and their conversion into Python exceptions), explicit ownership semantic of objects, and full support for the Python cyclic garbage collector.""" class _Distribution(Distribution): def __init__(self, *args, **kwargs): self.native_scripts = [] Distribution.__init__(self, *args, **kwargs) def has_native_scripts(self): return len(self.native_scripts) > 0 def is_pure(self): return Distribution.is_pure(self) and not self.has_native_scripts() # Redefine the build class so that "setup.py build" will also run "build_native_scripts" class _build(build): def has_native_scripts(self): return self.distribution.has_native_scripts() sub_commands = build.sub_commands + [ ('build_native_scripts', has_native_scripts) ] # Redefine install so that install_scripts will be run even if there are # native scripts. class _install(install): def has_scripts(self): return install.has_scripts(self) or self.distribution.has_native_scripts() sub_commands = install.sub_commands[:] for i, (name, cond) in enumerate(sub_commands): if name == "install_scripts": sub_commands[i] = (name, has_scripts) # Redefine the install_scripts class so that "setup.py build_native_scripts" will # be automatically run. class _install_scripts(install_scripts): def run(self, *args, **kwargs): if not self.skip_build: self.run_command('build_native_scripts') install_scripts.run(self, *args, **kwargs) # Redefine sdist so that it includes native script source files by default. # Also add dependencies for both native scripts and extensions (this is # a distutil missing feature already added to setuptools). class _sdist(sdist): def __get_depends(self, b): deps = [] for e in b.extensions: if e.depends: deps.extend(e.depends) return deps def add_defaults(self, *args, **kwargs): sdist.add_defaults(self, *args, **kwargs) if self.distribution.has_native_scripts(): build_native_scripts = self.get_finalized_command('build_native_scripts') self.filelist.extend(build_native_scripts.get_source_files()) self.filelist.extend(self.__get_depends(build_native_scripts)) if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') self.filelist.extend(self.__get_depends(build_ext)) # Redefine bdist_rpm to fix a bug when the version number contains hypens ("-"). # This is a bug in disutils shipped with Python 2.4.2, which I reported to # the distutils-sig mailing list. class _bdist_rpm(bdist_rpm): def run_command(self, cmd, *args, **kwargs): if cmd == "sdist": old_version = self.distribution.metadata.version if self.distribution.metadata.version is not None: self.distribution.metadata.version = old_version.replace("-", "_") print self.distribution.get_version() bdist_rpm.run_command(self, cmd, *args, **kwargs) self.distribution.metadata.version = old_version return bdist_rpm.run_command(self, cmd, *args, **kwargs) class build_native_scripts(build_ext): description = "Compile scripts in the form of native executables" user_options = build_ext.user_options[:] for i,opt in enumerate(user_options): if opt[0] == "build-lib=": del user_options[i] break else: assert 0, "build-lib not found?" user_options = [ ('build-lib=', 'b', "directory for compiled scripts"), ] + user_options def finalize_options(self, *args, **kwargs): self.set_undefined_options('build', ('build_scripts', 'build_lib')) build_ext.finalize_options(self, *args, **kwargs) # We must build things marked as native scripts self.extensions = self.distribution.native_scripts def build_extension(self, *args, **kwargs): # piggy-back the executable linking function def fake_link_shared_object(*args, **kwargs): del kwargs["export_symbols"] del kwargs["build_temp"] return self.compiler.link_executable(*args, **kwargs) self.compiler.link_shared_object = fake_link_shared_object build_ext.build_extension(self, *args, **kwargs) def get_ext_filename(self, *args, **kwargs): from distutils.sysconfig import get_config_var fn = build_ext.get_ext_filename(self, *args, **kwargs) # Remove .pyd, and no need to put an extension, as link_executable # will automatically take care of it. return os.path.splitext(fn)[0] setup( name = 'sip', version = sip_version_str, description = desc, long_description = long_desc, author = "Riverbank Computing Ltd.", author_email = "[EMAIL PROTECTED]", url = "http://www.riverbankcomputing.co.uk/sip/", download_url = "http://www.riverbankcomputing.co.uk/sip/download.php", license = "Python (MIT style)", platforms = "Python 2.3 and later.", classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Python Software Foundation License", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: C" "Programming Language :: C++", "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Libraries :: Python Modules", ], py_modules=[ "sipdistutils", ], ext_modules=[ Extension("sip", glob.glob(os.path.join("siplib", "*.c")) + glob.glob(os.path.join("siplib", "*.cpp")), include_dirs=["."], depends=glob.glob(os.path.join("siplib", "*.h"))), ], native_scripts=[ Extension("sip", glob.glob(os.path.join("sipgen", "*.c")) + glob.glob(os.path.join("sipgen", "*.cpp")), include_dirs=["."], depends=glob.glob(os.path.join("sipgen", "*.h"))), ], headers = [ "sipgen/sip.h" ], distclass = _Distribution, cmdclass = { 'build': _build, 'build_native_scripts': build_native_scripts, 'install': _install, 'install_scripts': _install_scripts, 'sdist': _sdist, 'bdist_rpm': _bdist_rpm, }, )
MANIFEST.in
Description: Binary data
_______________________________________________ PyKDE mailing list PyKDE@mats.imk.fraunhofer.de http://mats.imk.fraunhofer.de/mailman/listinfo/pykde