diff DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/command/build_src.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/command/build_src.py	Wed Feb 25 14:05:22 2015 +0000
@@ -0,0 +1,806 @@
+""" Build swig, f2py, pyrex sources.
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import shlex
+import copy
+
+from distutils.command import build_ext
+from distutils.dep_util import newer_group, newer
+from distutils.util import get_platform
+from distutils.errors import DistutilsError, DistutilsSetupError
+
+def have_pyrex():
+    try:
+        import Pyrex.Compiler.Main
+        return True
+    except ImportError:
+        return False
+
+# this import can't be done here, as it uses numpy stuff only available
+# after it's installed
+#import numpy.f2py
+from numpy.distutils import log
+from numpy.distutils.misc_util import fortran_ext_match, \
+     appendpath, is_string, is_sequence, get_cmd
+from numpy.distutils.from_template import process_file as process_f_file
+from numpy.distutils.conv_template import process_file as process_c_file
+
+def subst_vars(target, source, d):
+    """Substitute any occurence of @foo@ by d['foo'] from source file into
+    target."""
+    var = re.compile('@([a-zA-Z_]+)@')
+    fs = open(source, 'r')
+    try:
+        ft = open(target, 'w')
+        try:
+            for l in fs:
+                m = var.search(l)
+                if m:
+                    ft.write(l.replace('@%s@' % m.group(1), d[m.group(1)]))
+                else:
+                    ft.write(l)
+        finally:
+            ft.close()
+    finally:
+        fs.close()
+
+class build_src(build_ext.build_ext):
+
+    description = "build sources from SWIG, F2PY files or a function"
+
+    user_options = [
+        ('build-src=', 'd', "directory to \"build\" sources to"),
+        ('f2py-opts=', None, "list of f2py command line options"),
+        ('swig=', None, "path to the SWIG executable"),
+        ('swig-opts=', None, "list of SWIG command line options"),
+        ('swig-cpp', None, "make SWIG create C++ files (default is autodetected from sources)"),
+        ('f2pyflags=', None, "additional flags to f2py (use --f2py-opts= instead)"), # obsolete
+        ('swigflags=', None, "additional flags to swig (use --swig-opts= instead)"), # obsolete
+        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+        ('inplace', 'i',
+         "ignore build-lib and put compiled extensions into the source " +
+         "directory alongside your pure Python modules"),
+        ]
+
+    boolean_options = ['force', 'inplace']
+
+    help_options = []
+
+    def initialize_options(self):
+        self.extensions = None
+        self.package = None
+        self.py_modules = None
+        self.py_modules_dict = None
+        self.build_src = None
+        self.build_lib = None
+        self.build_base = None
+        self.force = None
+        self.inplace = None
+        self.package_dir = None
+        self.f2pyflags = None # obsolete
+        self.f2py_opts = None
+        self.swigflags = None # obsolete
+        self.swig_opts = None
+        self.swig_cpp = None
+        self.swig = None
+
+    def finalize_options(self):
+        self.set_undefined_options('build',
+                                   ('build_base', 'build_base'),
+                                   ('build_lib', 'build_lib'),
+                                   ('force', 'force'))
+        if self.package is None:
+            self.package = self.distribution.ext_package
+        self.extensions = self.distribution.ext_modules
+        self.libraries = self.distribution.libraries or []
+        self.py_modules = self.distribution.py_modules or []
+        self.data_files = self.distribution.data_files or []
+
+        if self.build_src is None:
+            plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+            self.build_src = os.path.join(self.build_base, 'src'+plat_specifier)
+
+        # py_modules_dict is used in build_py.find_package_modules
+        self.py_modules_dict = {}
+
+        if self.f2pyflags:
+            if self.f2py_opts:
+                log.warn('ignoring --f2pyflags as --f2py-opts already used')
+            else:
+                self.f2py_opts = self.f2pyflags
+            self.f2pyflags = None
+        if self.f2py_opts is None:
+            self.f2py_opts = []
+        else:
+            self.f2py_opts = shlex.split(self.f2py_opts)
+
+        if self.swigflags:
+            if self.swig_opts:
+                log.warn('ignoring --swigflags as --swig-opts already used')
+            else:
+                self.swig_opts = self.swigflags
+            self.swigflags = None
+
+        if self.swig_opts is None:
+            self.swig_opts = []
+        else:
+            self.swig_opts = shlex.split(self.swig_opts)
+
+        # use options from build_ext command
+        build_ext = self.get_finalized_command('build_ext')
+        if self.inplace is None:
+            self.inplace = build_ext.inplace
+        if self.swig_cpp is None:
+            self.swig_cpp = build_ext.swig_cpp
+        for c in ['swig', 'swig_opt']:
+            o = '--'+c.replace('_', '-')
+            v = getattr(build_ext, c, None)
+            if v:
+                if getattr(self, c):
+                    log.warn('both build_src and build_ext define %s option' % (o))
+                else:
+                    log.info('using "%s=%s" option from build_ext command' % (o, v))
+                    setattr(self, c, v)
+
+    def run(self):
+        log.info("build_src")
+        if not (self.extensions or self.libraries):
+            return
+        self.build_sources()
+
+    def build_sources(self):
+
+        if self.inplace:
+            self.get_package_dir = \
+                     self.get_finalized_command('build_py').get_package_dir
+
+        self.build_py_modules_sources()
+
+        for libname_info in self.libraries:
+            self.build_library_sources(*libname_info)
+
+        if self.extensions:
+            self.check_extensions_list(self.extensions)
+
+            for ext in self.extensions:
+                self.build_extension_sources(ext)
+
+        self.build_data_files_sources()
+        self.build_npy_pkg_config()
+
+    def build_data_files_sources(self):
+        if not self.data_files:
+            return
+        log.info('building data_files sources')
+        from numpy.distutils.misc_util import get_data_files
+        new_data_files = []
+        for data in self.data_files:
+            if isinstance(data, str):
+                new_data_files.append(data)
+            elif isinstance(data, tuple):
+                d, files = data
+                if self.inplace:
+                    build_dir = self.get_package_dir('.'.join(d.split(os.sep)))
+                else:
+                    build_dir = os.path.join(self.build_src, d)
+                funcs = [f for f in files if hasattr(f, '__call__')]
+                files = [f for f in files if not hasattr(f, '__call__')]
+                for f in funcs:
+                    if f.__code__.co_argcount==1:
+                        s = f(build_dir)
+                    else:
+                        s = f()
+                    if s is not None:
+                        if isinstance(s, list):
+                            files.extend(s)
+                        elif isinstance(s, str):
+                            files.append(s)
+                        else:
+                            raise TypeError(repr(s))
+                filenames = get_data_files((d, files))
+                new_data_files.append((d, filenames))
+            else:
+                raise TypeError(repr(data))
+        self.data_files[:] = new_data_files
+
+
+    def _build_npy_pkg_config(self, info, gd):
+        import shutil
+        template, install_dir, subst_dict = info
+        template_dir = os.path.dirname(template)
+        for k, v in gd.items():
+            subst_dict[k] = v
+
+        if self.inplace == 1:
+            generated_dir = os.path.join(template_dir, install_dir)
+        else:
+            generated_dir = os.path.join(self.build_src, template_dir,
+                    install_dir)
+        generated = os.path.basename(os.path.splitext(template)[0])
+        generated_path = os.path.join(generated_dir, generated)
+        if not os.path.exists(generated_dir):
+            os.makedirs(generated_dir)
+
+        subst_vars(generated_path, template, subst_dict)
+
+        # Where to install relatively to install prefix
+        full_install_dir = os.path.join(template_dir, install_dir)
+        return full_install_dir, generated_path
+
+    def build_npy_pkg_config(self):
+        log.info('build_src: building npy-pkg config files')
+
+        # XXX: another ugly workaround to circumvent distutils brain damage. We
+        # need the install prefix here, but finalizing the options of the
+        # install command when only building sources cause error. Instead, we
+        # copy the install command instance, and finalize the copy so that it
+        # does not disrupt how distutils want to do things when with the
+        # original install command instance.
+        install_cmd = copy.copy(get_cmd('install'))
+        if not install_cmd.finalized == 1:
+            install_cmd.finalize_options()
+        build_npkg = False
+        gd = {}
+        if self.inplace == 1:
+            top_prefix = '.'
+            build_npkg = True
+        elif hasattr(install_cmd, 'install_libbase'):
+            top_prefix = install_cmd.install_libbase
+            build_npkg = True
+
+        if build_npkg:
+            for pkg, infos in self.distribution.installed_pkg_config.items():
+                pkg_path = self.distribution.package_dir[pkg]
+                prefix = os.path.join(os.path.abspath(top_prefix), pkg_path)
+                d = {'prefix': prefix}
+                for info in infos:
+                    install_dir, generated = self._build_npy_pkg_config(info, d)
+                    self.distribution.data_files.append((install_dir,
+                        [generated]))
+
+    def build_py_modules_sources(self):
+        if not self.py_modules:
+            return
+        log.info('building py_modules sources')
+        new_py_modules = []
+        for source in self.py_modules:
+            if is_sequence(source) and len(source)==3:
+                package, module_base, source = source
+                if self.inplace:
+                    build_dir = self.get_package_dir(package)
+                else:
+                    build_dir = os.path.join(self.build_src,
+                                             os.path.join(*package.split('.')))
+                if hasattr(source, '__call__'):
+                    target = os.path.join(build_dir, module_base + '.py')
+                    source = source(target)
+                if source is None:
+                    continue
+                modules = [(package, module_base, source)]
+                if package not in self.py_modules_dict:
+                    self.py_modules_dict[package] = []
+                self.py_modules_dict[package] += modules
+            else:
+                new_py_modules.append(source)
+        self.py_modules[:] = new_py_modules
+
+    def build_library_sources(self, lib_name, build_info):
+        sources = list(build_info.get('sources', []))
+
+        if not sources:
+            return
+
+        log.info('building library "%s" sources' % (lib_name))
+
+        sources = self.generate_sources(sources, (lib_name, build_info))
+
+        sources = self.template_sources(sources, (lib_name, build_info))
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     self.package, h_files)
+
+        #for f in h_files:
+        #    self.distribution.headers.append((lib_name,f))
+
+        build_info['sources'] = sources
+        return
+
+    def build_extension_sources(self, ext):
+
+        sources = list(ext.sources)
+
+        log.info('building extension "%s" sources' % (ext.name))
+
+        fullname = self.get_ext_fullname(ext.name)
+
+        modpath = fullname.split('.')
+        package = '.'.join(modpath[0:-1])
+
+        if self.inplace:
+            self.ext_target_dir = self.get_package_dir(package)
+
+        sources = self.generate_sources(sources, ext)
+
+        sources = self.template_sources(sources, ext)
+
+        sources = self.swig_sources(sources, ext)
+
+        sources = self.f2py_sources(sources, ext)
+
+        sources = self.pyrex_sources(sources, ext)
+
+        sources, py_files = self.filter_py_files(sources)
+
+        if package not in self.py_modules_dict:
+            self.py_modules_dict[package] = []
+        modules = []
+        for f in py_files:
+            module = os.path.splitext(os.path.basename(f))[0]
+            modules.append((package, module, f))
+        self.py_modules_dict[package] += modules
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     package, h_files)
+        #for f in h_files:
+        #    self.distribution.headers.append((package,f))
+
+        ext.sources = sources
+
+    def generate_sources(self, sources, extension):
+        new_sources = []
+        func_sources = []
+        for source in sources:
+            if is_string(source):
+                new_sources.append(source)
+            else:
+                func_sources.append(source)
+        if not func_sources:
+            return new_sources
+        if self.inplace and not is_sequence(extension):
+            build_dir = self.ext_target_dir
+        else:
+            if is_sequence(extension):
+                name = extension[0]
+            #    if 'include_dirs' not in extension[1]:
+            #        extension[1]['include_dirs'] = []
+            #    incl_dirs = extension[1]['include_dirs']
+            else:
+                name = extension.name
+            #    incl_dirs = extension.include_dirs
+            #if self.build_src not in incl_dirs:
+            #    incl_dirs.append(self.build_src)
+            build_dir = os.path.join(*([self.build_src]\
+                                       +name.split('.')[:-1]))
+        self.mkpath(build_dir)
+        for func in func_sources:
+            source = func(extension, build_dir)
+            if not source:
+                continue
+            if is_sequence(source):
+                [log.info("  adding '%s' to sources." % (s,)) for s in source]
+                new_sources.extend(source)
+            else:
+                log.info("  adding '%s' to sources." % (source,))
+                new_sources.append(source)
+
+        return new_sources
+
+    def filter_py_files(self, sources):
+        return self.filter_files(sources, ['.py'])
+
+    def filter_h_files(self, sources):
+        return self.filter_files(sources, ['.h', '.hpp', '.inc'])
+
+    def filter_files(self, sources, exts = []):
+        new_sources = []
+        files = []
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext in exts:
+                files.append(source)
+            else:
+                new_sources.append(source)
+        return new_sources, files
+
+    def template_sources(self, sources, extension):
+        new_sources = []
+        if is_sequence(extension):
+            depends = extension[1].get('depends')
+            include_dirs = extension[1].get('include_dirs')
+        else:
+            depends = extension.depends
+            include_dirs = extension.include_dirs
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.src':  # Template file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                self.mkpath(target_dir)
+                target_file = os.path.join(target_dir, os.path.basename(base))
+                if (self.force or newer_group([source] + depends, target_file)):
+                    if _f_pyf_ext_match(base):
+                        log.info("from_template:> %s" % (target_file))
+                        outstr = process_f_file(source)
+                    else:
+                        log.info("conv_template:> %s" % (target_file))
+                        outstr = process_c_file(source)
+                    fid = open(target_file, 'w')
+                    fid.write(outstr)
+                    fid.close()
+                if _header_ext_match(target_file):
+                    d = os.path.dirname(target_file)
+                    if d not in include_dirs:
+                        log.info("  adding '%s' to include_dirs." % (d))
+                        include_dirs.append(d)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def pyrex_sources(self, sources, extension):
+        new_sources = []
+        ext_name = extension.name.split('.')[-1]
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyx':
+                target_file = self.generate_a_pyrex_source(base, ext_name,
+                                                           source,
+                                                           extension)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def generate_a_pyrex_source(self, base, ext_name, source, extension):
+        if self.inplace or not have_pyrex():
+            target_dir = os.path.dirname(base)
+        else:
+            target_dir = appendpath(self.build_src, os.path.dirname(base))
+        target_file = os.path.join(target_dir, ext_name + '.c')
+        depends = [source] + extension.depends
+        if self.force or newer_group(depends, target_file, 'newer'):
+            if have_pyrex():
+                import Pyrex.Compiler.Main
+                log.info("pyrexc:> %s" % (target_file))
+                self.mkpath(target_dir)
+                options = Pyrex.Compiler.Main.CompilationOptions(
+                    defaults=Pyrex.Compiler.Main.default_options,
+                    include_path=extension.include_dirs,
+                    output_file=target_file)
+                pyrex_result = Pyrex.Compiler.Main.compile(source,
+                                                           options=options)
+                if pyrex_result.num_errors != 0:
+                    raise DistutilsError("%d errors while compiling %r with Pyrex" \
+                          % (pyrex_result.num_errors, source))
+            elif os.path.isfile(target_file):
+                log.warn("Pyrex required for compiling %r but not available,"\
+                         " using old target %r"\
+                         % (source, target_file))
+            else:
+                raise DistutilsError("Pyrex required for compiling %r"\
+                                     " but notavailable" % (source,))
+        return target_file
+
+    def f2py_sources(self, sources, extension):
+        new_sources = []
+        f2py_sources = []
+        f_sources = []
+        f2py_targets = {}
+        target_dirs = []
+        ext_name = extension.name.split('.')[-1]
+        skip_f2py = 0
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyf': # F2PY interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                if os.path.isfile(source):
+                    name = get_f2py_modulename(source)
+                    if name != ext_name:
+                        raise DistutilsSetupError('mismatch of extension names: %s '
+                                                  'provides %r but expected %r' % (
+                            source, name, ext_name))
+                    target_file = os.path.join(target_dir, name+'module.c')
+                else:
+                    log.debug('  source %s does not exist: skipping f2py\'ing.' \
+                              % (source))
+                    name = ext_name
+                    skip_f2py = 1
+                    target_file = os.path.join(target_dir, name+'module.c')
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %smodule.c was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = os.path.join(target_dir, name+'module.c')
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.info('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                f2py_sources.append(source)
+                f2py_targets[source] = target_file
+                new_sources.append(target_file)
+            elif fortran_ext_match(ext):
+                f_sources.append(source)
+            else:
+                new_sources.append(source)
+
+        if not (f2py_sources or f_sources):
+            return new_sources
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        f2py_options = extension.f2py_options + self.f2py_opts
+
+        if self.distribution.libraries:
+            for name, build_info in self.distribution.libraries:
+                if name in extension.libraries:
+                    f2py_options.extend(build_info.get('f2py_options', []))
+
+        log.info("f2py options: %s" % (f2py_options))
+
+        if f2py_sources:
+            if len(f2py_sources) != 1:
+                raise DistutilsSetupError(
+                    'only one .pyf file is allowed per extension module but got'\
+                    ' more: %r' % (f2py_sources,))
+            source = f2py_sources[0]
+            target_file = f2py_targets[source]
+            target_dir = os.path.dirname(target_file) or '.'
+            depends = [source] + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py: %s" % (source))
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options
+                                    + ['--build-dir', target_dir, source])
+            else:
+                log.debug("  skipping '%s' f2py interface (up-to-date)" % (source))
+        else:
+            #XXX TODO: --inplace support for sdist command
+            if is_sequence(extension):
+                name = extension[0]
+            else: name = extension.name
+            target_dir = os.path.join(*([self.build_src]\
+                                        +name.split('.')[:-1]))
+            target_file = os.path.join(target_dir, ext_name + 'module.c')
+            new_sources.append(target_file)
+            depends = f_sources + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py:> %s" % (target_file))
+                self.mkpath(target_dir)
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options + ['--lower',
+                                                '--build-dir', target_dir]+\
+                                ['-m', ext_name]+f_sources)
+            else:
+                log.debug("  skipping f2py fortran files for '%s' (up-to-date)"\
+                          % (target_file))
+
+        if not os.path.isfile(target_file):
+            raise DistutilsError("f2py target file %r not generated" % (target_file,))
+
+        target_c = os.path.join(self.build_src, 'fortranobject.c')
+        target_h = os.path.join(self.build_src, 'fortranobject.h')
+        log.info("  adding '%s' to sources." % (target_c))
+        new_sources.append(target_c)
+        if self.build_src not in extension.include_dirs:
+            log.info("  adding '%s' to include_dirs." \
+                     % (self.build_src))
+            extension.include_dirs.append(self.build_src)
+
+        if not skip_f2py:
+            import numpy.f2py
+            d = os.path.dirname(numpy.f2py.__file__)
+            source_c = os.path.join(d, 'src', 'fortranobject.c')
+            source_h = os.path.join(d, 'src', 'fortranobject.h')
+            if newer(source_c, target_c) or newer(source_h, target_h):
+                self.mkpath(os.path.dirname(target_c))
+                self.copy_file(source_c, target_c)
+                self.copy_file(source_h, target_h)
+        else:
+            if not os.path.isfile(target_c):
+                raise DistutilsSetupError("f2py target_c file %r not found" % (target_c,))
+            if not os.path.isfile(target_h):
+                raise DistutilsSetupError("f2py target_h file %r not found" % (target_h,))
+
+        for name_ext in ['-f2pywrappers.f', '-f2pywrappers2.f90']:
+            filename = os.path.join(target_dir, ext_name + name_ext)
+            if os.path.isfile(filename):
+                log.info("  adding '%s' to sources." % (filename))
+                f_sources.append(filename)
+
+        return new_sources + f_sources
+
+    def swig_sources(self, sources, extension):
+        # Assuming SWIG 1.3.14 or later. See compatibility note in
+        #   http://www.swig.org/Doc1.3/Python.html#Python_nn6
+
+        new_sources = []
+        swig_sources = []
+        swig_targets = {}
+        target_dirs = []
+        py_files = []     # swig generated .py files
+        target_ext = '.c'
+        if '-c++' in extension.swig_opts:
+            typ = 'c++'
+            is_cpp = True
+            extension.swig_opts.remove('-c++')
+        elif self.swig_cpp:
+            typ = 'c++'
+            is_cpp = True
+        else:
+            typ = None
+            is_cpp = False
+        skip_swig = 0
+        ext_name = extension.name.split('.')[-1]
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.i': # SWIG interface file
+                # the code below assumes that the sources list
+                # contains not more than one .i SWIG interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                    py_target_dir = self.ext_target_dir
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                    py_target_dir = target_dir
+                if os.path.isfile(source):
+                    name = get_swig_modulename(source)
+                    if name != ext_name[1:]:
+                        raise DistutilsSetupError(
+                            'mismatch of extension names: %s provides %r'
+                            ' but expected %r' % (source, name, ext_name[1:]))
+                    if typ is None:
+                        typ = get_swig_target(source)
+                        is_cpp = typ=='c++'
+                    else:
+                        typ2 = get_swig_target(source)
+                        if typ2 is None:
+                            log.warn('source %r does not define swig target, assuming %s swig target' \
+                                     % (source, typ))
+                        elif typ!=typ2:
+                            log.warn('expected %r but source %r defines %r swig target' \
+                                     % (typ, source, typ2))
+                            if typ2=='c++':
+                                log.warn('resetting swig target to c++ (some targets may have .c extension)')
+                                is_cpp = True
+                            else:
+                                log.warn('assuming that %r has c++ swig target' % (source))
+                    if is_cpp:
+                        target_ext = '.cpp'
+                    target_file = os.path.join(target_dir, '%s_wrap%s' \
+                                               % (name, target_ext))
+                else:
+                    log.warn('  source %s does not exist: skipping swig\'ing.' \
+                             % (source))
+                    name = ext_name[1:]
+                    skip_swig = 1
+                    target_file = _find_swig_target(target_dir, name)
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %s_wrap.{c,cpp} was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = _find_swig_target(target_dir, name)
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.warn('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                new_sources.append(target_file)
+                py_files.append(os.path.join(py_target_dir, name+'.py'))
+                swig_sources.append(source)
+                swig_targets[source] = new_sources[-1]
+            else:
+                new_sources.append(source)
+
+        if not swig_sources:
+            return new_sources
+
+        if skip_swig:
+            return new_sources + py_files
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        swig = self.swig or self.find_swig()
+        swig_cmd = [swig, "-python"] + extension.swig_opts
+        if is_cpp:
+            swig_cmd.append('-c++')
+        for d in extension.include_dirs:
+            swig_cmd.append('-I'+d)
+        for source in swig_sources:
+            target = swig_targets[source]
+            depends = [source] + extension.depends
+            if self.force or newer_group(depends, target, 'newer'):
+                log.info("%s: %s" % (os.path.basename(swig) \
+                                     + (is_cpp and '++' or ''), source))
+                self.spawn(swig_cmd + self.swig_opts \
+                           + ["-o", target, '-outdir', py_target_dir, source])
+            else:
+                log.debug("  skipping '%s' swig interface (up-to-date)" \
+                         % (source))
+
+        return new_sources + py_files
+
+_f_pyf_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+_header_ext_match = re.compile(r'.*[.](inc|h|hpp)\Z', re.I).match
+
+#### SWIG related auxiliary functions ####
+_swig_module_name_match = re.compile(r'\s*%module\s*(.*\(\s*package\s*=\s*"(?P<package>[\w_]+)".*\)|)\s*(?P<name>[\w_]+)',
+                                     re.I).match
+_has_c_header = re.compile(r'-[*]-\s*c\s*-[*]-', re.I).search
+_has_cpp_header = re.compile(r'-[*]-\s*c[+][+]\s*-[*]-', re.I).search
+
+def get_swig_target(source):
+    f = open(source, 'r')
+    result = None
+    line = f.readline()
+    if _has_cpp_header(line):
+        result = 'c++'
+    if _has_c_header(line):
+        result = 'c'
+    f.close()
+    return result
+
+def get_swig_modulename(source):
+    f = open(source, 'r')
+    name = None
+    for line in f:
+        m = _swig_module_name_match(line)
+        if m:
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+def _find_swig_target(target_dir, name):
+    for ext in ['.cpp', '.c']:
+        target = os.path.join(target_dir, '%s_wrap%s' % (name, ext))
+        if os.path.isfile(target):
+            break
+    return target
+
+#### F2PY related auxiliary functions ####
+
+_f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]+)',
+                                re.I).match
+_f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]*?'\
+                                     '__user__[\w_]*)', re.I).match
+
+def get_f2py_modulename(source):
+    name = None
+    f = open(source)
+    for line in f:
+        m = _f2py_module_name_match(line)
+        if m:
+            if _f2py_user_module_name_match(line): # skip *__user__* names
+                continue
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+##########################################