diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-22 02:59:34 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-22 02:59:34 -0600 |
commit | 6c4cc3653e8dd7668295f3e659b7eb4dc571b67c (patch) | |
tree | a559fd71fc982e35a4f984d85a5c9d92b764ae8c /sipdistutils.py | |
download | sip4-tqt-6c4cc3653e8dd7668295f3e659b7eb4dc571b67c.tar.gz sip4-tqt-6c4cc3653e8dd7668295f3e659b7eb4dc571b67c.zip |
Initial import of SIP4 for Qt3
Diffstat (limited to 'sipdistutils.py')
-rw-r--r-- | sipdistutils.py | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/sipdistutils.py b/sipdistutils.py new file mode 100644 index 0000000..6994989 --- /dev/null +++ b/sipdistutils.py @@ -0,0 +1,148 @@ +# Subclasses disutils.command.build_ext, +# replacing it with a SIP version that compiles .sip -> .cpp +# before calling the original build_ext command. +# Written by Giovanni Bajo <rasky at develer dot com> +# Based on Pyrex.Distutils, written by Graham Fawcett and Darrel Gallion. + +import distutils.command.build_ext +from distutils.dep_util import newer, newer_group +import os +import sys +from hashlib import sha1 + +build_ext_base = distutils.command.build_ext.build_ext + +def replace_suffix(path, new_suffix): + return os.path.splitext(path)[0] + new_suffix + +class build_ext (build_ext_base): + + description = "Compiler SIP descriptions, then build C/C++ extensions (compile/link to build directory)" + + user_options = build_ext_base.user_options[:] + user_options = [opt for opt in user_options if not opt[0].startswith("swig")] + user_options += [ + ('sip-opts=', None, + "list of sip command line options"), + ] + + def initialize_options (self): + build_ext_base.initialize_options(self) + self.sip_opts = None + + def finalize_options (self): + build_ext_base.finalize_options(self) + if self.sip_opts is None: + self.sip_opts = [] + else: + self.sip_opts = self.sip_opts.split(' ') + + def _get_sip_output_list(self, sbf): + """ + Parse the sbf file specified to extract the name of the generated source + files. Make them absolute assuming they reside in the temp directory. + """ + for L in file(sbf): + key, value = L.split("=", 1) + if key.strip() == "sources": + out = [] + for o in value.split(): + out.append(os.path.join(self.build_temp, o)) + return out + + raise RuntimeError("cannot parse SIP-generated '%s'" % sbf) + + def _find_sip(self): + import sipconfig + cfg = sipconfig.Configuration() + if os.name == "nt": + if not os.path.splitext(os.path.basename(cfg.sip_bin))[1]: + return cfg.sip_bin + ".exe" + return cfg.sip_bin + + def _sip_inc_dir(self): + import sipconfig + cfg = sipconfig.Configuration() + return cfg.sip_inc_dir + + def _sip_sipfiles_dir(self): + import sipconfig + cfg = sipconfig.Configuration() + return cfg.default_sip_dir + + def _sip_calc_signature(self): + sip_bin = self._find_sip() + return sha1(open(sip_bin, "rb").read()).hexdigest() + + def _sip_signature_file(self): + return os.path.join(self.build_temp, "sip.signature") + + def build_extension (self, ext): + oldforce = self.force + + if not self.force: + sip_sources = [source for source in ext.sources if source.endswith('.sip')] + if sip_sources: + sigfile = self._sip_signature_file() + if not os.path.isfile(sigfile): + self.force = True + else: + old_sig = open(sigfile).read() + new_sig = self._sip_calc_signature() + if old_sig != new_sig: + self.force = True + + build_ext_base.build_extension(self, ext) + + self.force = oldforce + + def swig_sources (self, sources, extension=None): + if not self.extensions: + return + + # Add the SIP include directory to the include path + if extension is not None: + extension.include_dirs.append(self._sip_inc_dir()) + depends = extension.depends + else: + # pre-2.4 compatibility + self.include_dirs.append(self._sip_inc_dir()) + depends = [] # ? + + # Filter dependencies list: we are interested only in .sip files, + # since the main .sip files can only depend on additional .sip + # files. For instance, if a .h changes, there is no need to + # run sip again. + depends = [f for f in depends if os.path.splitext(f)[1] == ".sip"] + + # Create the temporary directory if it does not exist already + if not os.path.isdir(self.build_temp): + os.makedirs(self.build_temp) + + # Collect the names of the source (.sip) files + sip_sources = [] + sip_sources = [source for source in sources if source.endswith('.sip')] + other_sources = [source for source in sources if not source.endswith('.sip')] + generated_sources = [] + + sip_bin = self._find_sip() + + for sip in sip_sources: + # Use the sbf file as dependency check + sipbasename = os.path.basename(sip) + sbf = os.path.join(self.build_temp, replace_suffix(sipbasename, ".sbf")) + if newer_group([sip]+depends, sbf) or self.force: + self._sip_compile(sip_bin, sip, sbf) + open(self._sip_signature_file(), "w").write(self._sip_calc_signature()) + out = self._get_sip_output_list(sbf) + generated_sources.extend(out) + + return generated_sources + other_sources + + def _sip_compile(self, sip_bin, source, sbf): + self.spawn([sip_bin] + self.sip_opts + + ["-c", self.build_temp, + "-b", sbf, + "-I", self._sip_sipfiles_dir(), + source]) + |