summaryrefslogtreecommitdiffstats
path: root/python/sip/sipdistutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/sip/sipdistutils.py')
-rw-r--r--python/sip/sipdistutils.py90
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])