import os import posixpath import re import _import_wrapper as iw import _common as common def init(): iw.addrule('swg', Swig) class Swig(iw.CustomCommand): def __init__(self, path, unit): self._tool = unit.get('SWIG_TOOL') self._library_dir = unit.get('SWIG_LIBRARY') or 'contrib/tools/swig/Lib' self._local_swig = unit.get('USE_LOCAL_SWIG') == "yes" self._path = path self._flags = ['-cpperraswarn'] self._bindir = common.tobuilddir(unit.path()) self._input_name = common.stripext(os.path.basename(self._path)) relpath = os.path.relpath(os.path.dirname(self._path), unit.path()) self._swig_lang = unit.get('SWIG_LANG') if self._swig_lang != 'jni_java': self._main_out = os.path.join( self._bindir, '' if relpath == '.' else relpath.replace('..', '__'), self._input_name + '_wrap.swg.c') if not path.endswith('.c.swg'): self._flags += ['-c++'] self._main_out += 'pp' # lang_specific_incl_dir = 'perl5' if self._swig_lang == 'perl' else self._swig_lang lang_specific_incl_dir = self._swig_lang if self._swig_lang == 'perl': lang_specific_incl_dir = 'perl5' elif self._swig_lang in ['jni_cpp', 'jni_java']: lang_specific_incl_dir = 'java' incl_dirs = [ "FOR", "swig", posixpath.join(self._library_dir, lang_specific_incl_dir), "FOR", "swig", self._library_dir ] self._incl_dirs = ['$S', '$B'] + [posixpath.join('$S', d) for d in incl_dirs] modname = unit.get('REALPRJNAME') self._flags.extend(['-module', modname]) if not self._local_swig: unit.onaddincl(incl_dirs) if self._swig_lang == 'python': self._out_name = modname + '.py' self._flags.extend(['-interface', unit.get('MODULE_PREFIX') + modname]) if self._swig_lang == 'perl': self._out_name = modname + '.pm' self._flags.append('-shadow') unit.onpeerdir(['build/platform/perl']) if self._swig_lang in ['jni_cpp', 'java']: self._out_header = os.path.splitext(self._main_out)[0] + '.h' if (not unit.get('USE_SYSTEM_JDK')) and (unit.get('OS_ANDROID') != "yes"): unit.onpeerdir(['contrib/libs/jdk']) self._package = 'ru.yandex.' + os.path.dirname(self._path).replace('$S/', '').replace('$B/', '').replace('/', '.').replace('-', '_') if self._swig_lang in ['jni_java', 'java']: self._out_name = os.path.splitext(os.path.basename(self._path))[0] + '.jsrc' elif self._swig_lang != 'jni_cpp': self._flags.append('-' + self._swig_lang) def descr(self): return 'SW', self._path, 'yellow' def flags(self): return self._flags def tools(self): return ['contrib/tools/swig'] if not self._tool else [] def input(self): return [ (self._path, []) ] def output(self): if self._swig_lang == 'jni_java': return [(common.join_intl_paths(self._bindir, self._out_name), [])] elif self._swig_lang == 'jni_cpp': return [(self._main_out, []), (self._out_header, [])] return [ (self._main_out, []), (common.join_intl_paths(self._bindir, self._out_name), (['noauto', 'add_to_outs'] if self._swig_lang != 'java' else [])), ] + ([(self._out_header, [])] if self._swig_lang == 'java' else []) def output_includes(self): return [(self._out_header, [])] if self._swig_lang in ['java', 'jni_cpp'] else [] def run(self, extra_args, binary): if self._local_swig: binary = self._tool return self.do_run_java(binary, self._path) if self._swig_lang in ['java', 'jni_cpp', 'jni_java'] else self.do_run(binary, self._path) def _incl_flags(self): return ['-I' + self.resolve_path(x) for x in self._incl_dirs] def do_run(self, binary, path): self.call([binary] + self._flags + [ '-o', self.resolve_path(common.get(self.output, 0)), '-outdir', self.resolve_path(self._bindir) ] + self._incl_flags() + [self.resolve_path(path)]) def do_run_java(self, binary, path): import tarfile outdir = self.resolve_path(self._bindir) if self._swig_lang != 'jni_cpp': java_srcs_dir = os.path.join(outdir, self._package.replace('.', '/')) if not os.path.exists(java_srcs_dir): os.makedirs(java_srcs_dir) flags = self._incl_flags() src = self.resolve_path(path) with open(src, 'r') as f: if not re.search(r'(?m)^%module\b', f.read()): flags += ['-module', os.path.splitext(os.path.basename(src))[0]] if self._swig_lang == 'jni_cpp': self.call([binary, '-c++', '-o', self._main_out, '-java', '-package', self._package] + flags + [src]) elif self._swig_lang == 'jni_java': self.call([binary, '-c++', '-o', os.path.join(outdir, 'unused.cpp'), '-outdir', java_srcs_dir, '-java', '-package', self._package] + flags + [src]) elif self._swig_lang == 'java': self.call([ binary, '-c++', '-o', self._main_out, '-outdir', java_srcs_dir, '-java', '-package', self._package, ] + flags + [src]) if self._swig_lang in ['jni_java', 'java']: with tarfile.open(os.path.join(outdir, self._out_name), 'a') as tf: tf.add(java_srcs_dir, arcname=self._package.replace('.', '/')) if self._swig_lang in ['jni_cpp', 'java']: header = os.path.splitext(self.resolve_path(self._main_out))[0] + '.h' if not os.path.exists(header): open(header, 'w').close() def on_swig_lang_filtered_srcs(unit, *args): swig_lang = unit.get('SWIG_LANG') allowed_exts = set() if swig_lang == 'jni_cpp': allowed_exts = set(['.cpp', '.swg']) if swig_lang == 'jni_java': allowed_exts = set(['.java', '.swg']) args = [arg for arg in iter(args) if allowed_exts and os.path.splitext(arg)[1] in allowed_exts] unit.onsrcs(args)