diff options
Diffstat (limited to 'graphics/asymptote/tinyexr/test/unit/kuroga.py')
-rwxr-xr-x | graphics/asymptote/tinyexr/test/unit/kuroga.py | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/graphics/asymptote/tinyexr/test/unit/kuroga.py b/graphics/asymptote/tinyexr/test/unit/kuroga.py new file mode 100755 index 0000000000..56d3f863dd --- /dev/null +++ b/graphics/asymptote/tinyexr/test/unit/kuroga.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python + +# +# Kuroga, single python file meta-build system for ninja +# https://github.com/lighttransport/kuroga +# +# Requirements: python 2.6 or 2.7 +# +# Usage: $ python kuroga.py input.py +# + +import imp +import re +import textwrap +import glob +import os +import sys + +# gcc preset +def add_gnu_rule(ninja): + ninja.rule('gnucxx', description='CXX $out', + command='$gnucxx -MMD -MF $out.d $gnudefines $gnuincludes $gnucxxflags -c $in -o $out', + depfile='$out.d', deps='gcc') + ninja.rule('gnucc', description='CC $out', + command='$gnucc -MMD -MF $out.d $gnudefines $gnuincludes $gnucflags -c $in -o $out', + depfile='$out.d', deps='gcc') + ninja.rule('gnulink', description='LINK $out', pool='link_pool', + command='$gnuld -o $out $in $libs $gnuldflags') + ninja.rule('gnuar', description='AR $out', pool='link_pool', + command='$gnuar rsc $out $in') + ninja.rule('gnustamp', description='STAMP $out', command='touch $out') + ninja.newline() + + ninja.variable('gnucxx', 'g++') + ninja.variable('gnucc', 'gcc') + ninja.variable('gnuld', '$gnucxx') + ninja.variable('gnuar', 'ar') + ninja.newline() + +# clang preset +def add_clang_rule(ninja): + ninja.rule('clangcxx', description='CXX $out', + command='$clangcxx -MMD -MF $out.d $clangdefines $clangincludes $clangcxxflags -c $in -o $out', + depfile='$out.d', deps='gcc') + ninja.rule('clangcc', description='CC $out', + command='$clangcc -MMD -MF $out.d $clangdefines $clangincludes $clangcflags -c $in -o $out', + depfile='$out.d', deps='gcc') + ninja.rule('clanglink', description='LINK $out', pool='link_pool', + command='$clangld -o $out $in $libs $clangldflags') + ninja.rule('clangar', description='AR $out', pool='link_pool', + command='$clangar rsc $out $in') + ninja.rule('clangstamp', description='STAMP $out', command='touch $out') + ninja.newline() + + ninja.variable('clangcxx', 'clang++') + ninja.variable('clangcc', 'clang') + ninja.variable('clangld', '$clangcxx') + ninja.variable('clangar', 'ar') + ninja.newline() + +# msvc preset +def add_msvc_rule(ninja): + ninja.rule('msvccxx', description='CXX $out', + command='$msvccxx /TP /showIncludes $msvcdefines $msvcincludes $msvccxxflags -c $in /Fo$out', + depfile='$out.d', deps='msvc') + ninja.rule('msvccc', description='CC $out', + command='$msvccc /TC /showIncludes $msvcdefines $msvcincludes $msvccflags -c $in /Fo$out', + depfile='$out.d', deps='msvc') + ninja.rule('msvclink', description='LINK $out', pool='link_pool', + command='$msvcld $msvcldflags $in $libs /OUT:$out') + ninja.rule('msvcar', description='AR $out', pool='link_pool', + command='$msvcar $in /OUT:$out') + #ninja.rule('msvcstamp', description='STAMP $out', command='touch $out') + ninja.newline() + + ninja.variable('msvccxx', 'cl.exe') + ninja.variable('msvccc', 'cl.exe') + ninja.variable('msvcld', 'link.exe') + ninja.variable('msvcar', 'lib.exe') + ninja.newline() + +# -- from ninja_syntax.py -- +def escape_path(word): + return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:') + +class Writer(object): + def __init__(self, output, width=78): + self.output = output + self.width = width + + def newline(self): + self.output.write('\n') + + def comment(self, text, has_path=False): + for line in textwrap.wrap(text, self.width - 2, break_long_words=False, + break_on_hyphens=False): + self.output.write('# ' + line + '\n') + + def variable(self, key, value, indent=0): + if value is None: + return + if isinstance(value, list): + value = ' '.join(filter(None, value)) # Filter out empty strings. + self._line('%s = %s' % (key, value), indent) + + def pool(self, name, depth): + self._line('pool %s' % name) + self.variable('depth', depth, indent=1) + + def rule(self, name, command, description=None, depfile=None, + generator=False, pool=None, restat=False, rspfile=None, + rspfile_content=None, deps=None): + self._line('rule %s' % name) + self.variable('command', command, indent=1) + if description: + self.variable('description', description, indent=1) + if depfile: + self.variable('depfile', depfile, indent=1) + if generator: + self.variable('generator', '1', indent=1) + if pool: + self.variable('pool', pool, indent=1) + if restat: + self.variable('restat', '1', indent=1) + if rspfile: + self.variable('rspfile', rspfile, indent=1) + if rspfile_content: + self.variable('rspfile_content', rspfile_content, indent=1) + if deps: + self.variable('deps', deps, indent=1) + + def build(self, outputs, rule, inputs=None, implicit=None, order_only=None, + variables=None): + outputs = as_list(outputs) + out_outputs = [escape_path(x) for x in outputs] + all_inputs = [escape_path(x) for x in as_list(inputs)] + + if implicit: + implicit = [escape_path(x) for x in as_list(implicit)] + all_inputs.append('|') + all_inputs.extend(implicit) + if order_only: + order_only = [escape_path(x) for x in as_list(order_only)] + all_inputs.append('||') + all_inputs.extend(order_only) + + self._line('build %s: %s' % (' '.join(out_outputs), + ' '.join([rule] + all_inputs))) + + if variables: + if isinstance(variables, dict): + iterator = iter(variables.items()) + else: + iterator = iter(variables) + + for key, val in iterator: + self.variable(key, val, indent=1) + + return outputs + + def include(self, path): + self._line('include %s' % path) + + def subninja(self, path): + self._line('subninja %s' % path) + + def default(self, paths): + self._line('default %s' % ' '.join(as_list(paths))) + + def _count_dollars_before_index(self, s, i): + """Returns the number of '$' characters right in front of s[i].""" + dollar_count = 0 + dollar_index = i - 1 + while dollar_index > 0 and s[dollar_index] == '$': + dollar_count += 1 + dollar_index -= 1 + return dollar_count + + def _line(self, text, indent=0): + """Write 'text' word-wrapped at self.width characters.""" + leading_space = ' ' * indent + while len(leading_space) + len(text) > self.width: + # The text is too wide; wrap if possible. + + # Find the rightmost space that would obey our width constraint and + # that's not an escaped space. + available_space = self.width - len(leading_space) - len(' $') + space = available_space + while True: + space = text.rfind(' ', 0, space) + if (space < 0 or + self._count_dollars_before_index(text, space) % 2 == 0): + break + + if space < 0: + # No such space; just use the first unescaped space we can find. + space = available_space - 1 + while True: + space = text.find(' ', space + 1) + if (space < 0 or + self._count_dollars_before_index(text, space) % 2 == 0): + break + if space < 0: + # Give up on breaking. + break + + self.output.write(leading_space + text[0:space] + ' $\n') + text = text[space+1:] + + # Subsequent lines are continuations, so indent them. + leading_space = ' ' * (indent+2) + + self.output.write(leading_space + text + '\n') + + def close(self): + self.output.close() + + +def as_list(input): + if input is None: + return [] + if isinstance(input, list): + return input + return [input] + +# -- end from ninja_syntax.py -- + +def gen(ninja, toolchain, config): + + ninja.variable('ninja_required_version', '1.4') + ninja.newline() + + if hasattr(config, "builddir"): + builddir = config.builddir[toolchain] + ninja.variable(toolchain + 'builddir', builddir) + else: + builddir = '' + + ninja.variable(toolchain + 'defines', config.defines[toolchain] or []) + ninja.variable(toolchain + 'includes', config.includes[toolchain] or []) + ninja.variable(toolchain + 'cflags', config.cflags[toolchain] or []) + ninja.variable(toolchain + 'cxxflags', config.cxxflags[toolchain] or []) + ninja.variable(toolchain + 'ldflags', config.ldflags[toolchain] or []) + ninja.newline() + + if hasattr(config, "link_pool_depth"): + ninja.pool('link_pool', depth=config.link_pool_depth) + else: + ninja.pool('link_pool', depth=4) + ninja.newline() + + # Add default toolchain(gnu, clang and msvc) + add_gnu_rule(ninja) + add_clang_rule(ninja) + add_msvc_rule(ninja) + + obj_files = [] + + cc = toolchain + 'cc' + cxx = toolchain + 'cxx' + link = toolchain + 'link' + ar = toolchain + 'ar' + + if hasattr(config, "cxx_files"): + for src in config.cxx_files: + srcfile = src + obj = os.path.splitext(srcfile)[0] + '.o' + obj = os.path.join(builddir, obj); + obj_files.append(obj) + ninja.build(obj, cxx, srcfile) + ninja.newline() + + if hasattr(config, "c_files"): + for src in config.c_files: + srcfile = src + obj = os.path.splitext(srcfile)[0] + '.o' + obj = os.path.join(builddir, obj); + obj_files.append(obj) + ninja.build(obj, cc, srcfile) + ninja.newline() + + targetlist = [] + if hasattr(config, "exe"): + ninja.build(config.exe, link, obj_files) + targetlist.append(config.exe) + + if hasattr(config, "staticlib"): + ninja.build(config.staticlib, ar, obj_files) + targetlist.append(config.staticlib) + + ninja.build('all', 'phony', targetlist) + ninja.newline() + + ninja.default('all') + +def main(): + if len(sys.argv) < 2: + print("Usage: python kuroga.py config.py") + sys.exit(1) + + config = imp.load_source("config", sys.argv[1]) + + f = open('build.ninja', 'w') + ninja = Writer(f) + + if hasattr(config, "register_toolchain"): + config.register_toolchain(ninja) + + gen(ninja, config.toolchain, config) + f.close() + +main() |