Viewing file: BuildExt.py (4.97 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import os, re, sys from distutils import util from distutils.command import build_ext from distutils.dep_util import newer_group, newer
class BuildExt(build_ext.build_ext):
command_name = 'build_ext'
_include_re = re.compile(r'^\s*#\s*include\s*("|<)(?P<file>[^">]+?)("|>)', re.MULTILINE)
def _find_includes(self, ext, filename, includes): source = open(filename).read() basename = os.path.basename(filename)
include_dirs = [os.path.dirname(filename)] include_dirs.extend(ext.include_dirs)
match = self._include_re.search(source) while match: filename = util.convert_path(match.group('file')) for base in include_dirs: include = os.path.normpath(os.path.join(base, filename)) if os.path.isfile(include) and include not in includes: includes.append(include) self._find_includes(ext, include, includes) break match = self._include_re.search(source, match.end()) return
def get_source_files (self): self.check_extensions_list(self.extensions) filenames = []
for ext in self.extensions: all_sources = self.prep_build(ext) for source, includes in all_sources: filenames.append(source) filenames.extend(includes)
return filenames
def prep_build(self, ext): # This should really exist in the CCompiler class, but # that would required overriding all compilers. result = [] for source in ext.sources: includes = [] self._find_includes(ext, util.convert_path(source), includes) result.append((source, includes)) return result def build_extension(self, ext): fullname = self.get_ext_fullname(ext.name) ext_filename = os.path.join(self.build_lib, self.get_ext_filename(fullname))
all_sources = self.prep_build(ext) sources = [] for source, includes in all_sources: sources.append(source) sources.extend(includes)
if not (self.force or newer_group(sources, ext_filename, 'newer')): self.announce("skipping '%s' extension (up-to-date)" % ext.name) return else: self.announce("building '%s' extension" % ext.name)
preargs = [] postargs = ext.extra_compile_args or [] macros = ext.define_macros[:] for undef in ext.undef_macros: macros.append((undef,))
objects = [] for source, includes in all_sources: kwords = {} if sys.hexversion > 0x02030000: output_dir = self.build_temp else: output_dir = os.path.join(self.build_temp, os.path.dirname(source)) if sys.hexversion > 0x02030000: # Distutils has a depends keyword for compiling kwords['depends'] = includes elif not self.force: # Recompile if the includes or source are newer than the # resulting object files. objs = self.compiler.object_filenames([source], 1, output_dir) # Recompile if any of the inputs are newer than the object inputs = [source] + includes force = 0 for filename in objs: force = force or newer_group(inputs, filename, 'newer') self.compiler.force = force
objs = self.compiler.compile([source], output_dir=output_dir, macros=macros, include_dirs=ext.include_dirs, debug=self.debug, extra_preargs=preargs, extra_postargs=postargs, **kwords) objects.extend(objs)
# Reset the force flag on the compilier self.compiler.force = self.force # Now link the object files together into a "shared object" -- # of course, first we have to figure out all the other things # that go into the mix. if ext.extra_objects: objects.extend(ext.extra_objects)
extra_args = ext.extra_link_args or []
self.compiler.link_shared_object( objects, ext_filename, libraries=self.get_libraries(ext), library_dirs=ext.library_dirs, runtime_library_dirs=ext.runtime_library_dirs, extra_preargs=extra_args, extra_postargs=[], export_symbols=self.get_export_symbols(ext), debug=self.debug, build_temp=self.build_temp) return
|