diff options
Diffstat (limited to 'python/sip/sipdistutils.py')
-rw-r--r-- | python/sip/sipdistutils.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/python/sip/sipdistutils.py b/python/sip/sipdistutils.py new file mode 100644 index 00000000..1c2ab7ed --- /dev/null +++ b/python/sip/sipdistutils.py @@ -0,0 +1,90 @@ +# 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 + +def replace_suffix(path, new_suffix): + return os.path.splitext(path)[0] + new_suffix + +class build_ext (distutils.command.build_ext.build_ext): + + description = "Compiler SIP descriptions, then build C/C++ extensions (compile/link to build directory)" + + 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() + return cfg.sip_bin + + def _sip_inc_dir(self): + import sipconfig + cfg = sipconfig.Configuration() + return cfg.sip_inc_dir + + 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) + 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, + "-c", self.build_temp, + "-b", sbf, + source]) |