#!/usr/bin/env python # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # # external_runtime.py: Generate external runtime files for SWIG # import sys import os import re import fileinput import filecmp if __name__ == "__main__": parent_dir = os.path.dirname(os.path.abspath(os.path.dirname(sys.argv[0]))) sys.path[0:0] = [ parent_dir, os.path.dirname(parent_dir) ] import generator.swig import generator.util.executable _exec = generator.util.executable class Generator(generator.swig.Generator): """Generate external runtime files for SWIG""" def write(self): """Generate external runtimes""" for lang in self.langs: self.write_external_runtime(lang) def write_makefile_rules(self, makefile): """Write the makefile rules for generating external runtimes""" makefile.write( 'GEN_SWIG_RUNTIME = cd $(top_srcdir) && $(PYTHON)' + ' build/generator/swig/external_runtime.py build.conf $(SWIG)\n\n' ) for lang in self.langs: out = self._output_file(lang) makefile.write( 'autogen-swig-%s: %s\n' % (self.short[lang], out) + '%s: $(SWIG_CHECKOUT_FILES)\n' % out + '\t$(GEN_SWIG_RUNTIME) %s\n\n' % lang ) makefile.write('\n') def write_external_runtime(self, lang): """Generate external runtime header files for each SWIG language""" # Runtime library names runtime_library = { "python": "pyrun.swg", "perl":"perlrun.swg", "ruby":"rubydef.swg" } # Build runtime files to temporary location dest = self._output_file(lang) out = dest + '.tmp' if self.version() == (1, 3, 24): out_file = open(out, "w") out_file.write(open("%s/swigrun.swg" % self.proxy_dir).read()) out_file.write(open("%s/common.swg" % self.proxy_dir).read()) out_file.write( open("%s/%s" % (self.proxy_dir, runtime_library[lang])).read()) if lang != "ruby": out_file.write(open("%s/runtime.swg" % self.proxy_dir).read()) out_file.close() else: _exec.run("%s -%s -external-runtime %s" % (self.swig_path, lang, out)) # SWIG 1.3.24-27 should include rubyhead.swg in their # external runtime, but they don't. if lang == "ruby" and self.version() < (1, 3, 28): runtime = open(out).read() out_file = open(out, "w") head = open("%s/rubyhead.swg" % self.proxy_dir).read(); out_file.write(head) if self.version() >= (1, 3, 26): # SWIG 1.3.26-27 should include rubytracking.swg in their # external runtime, but they don't. tracking = open("%s/rubytracking.swg" % self.proxy_dir).read(); out_file.write(tracking) out_file.write(runtime) out_file.close() # SWIG 1.3.25 and earlier use the wrong number of arguments in calls to # SWIG_GetModule. We fix this below. if self.version() <= (1, 3, 25): for line in fileinput.input(out, inplace=1): sys.stdout.write( re.sub(r"SWIG_GetModule\(\)", "SWIG_GetModule(NULL)", line) ) # Did the output change? try: if filecmp.cmp(dest, out): identical = True else: identical = False except: identical = False # Only overwrite file if changed if identical: os.remove(out) else: try: os.remove(dest) except: pass os.rename(out, dest) print('Wrote %s' % (dest,)) def _output_file(self, lang): """Return the output filename of the runtime for the given language""" return '%s/swig_%s_external_runtime.swg' % (self.proxy_dir, lang) if __name__ == "__main__": if len(sys.argv) != 4: print("Usage: %s build.conf swig") print("Generates external runtime files for SWIG") else: gen = Generator(sys.argv[1], sys.argv[2]) gen.write_external_runtime(sys.argv[3])