From 5841a8571e4a9c37151c3d3ca04eb13881e51525 Mon Sep 17 00:00:00 2001 From: Andrew Brodko Date: Wed, 23 Dec 2020 20:38:58 +0000 Subject: [PATCH] Haxe support --- playground/haxe/bytecode/.haxerc | 4 + playground/haxe/bytecode/package.json | 18 +++ playground/haxe/bytecode/src/Main.hx | 5 + playground/haxe/bytecode/src/main.hxml | 2 + playground/haxe/bytecode/src/wscript | 7 + playground/haxe/bytecode/wscript | 8 ++ playground/haxe/executable/.haxerc | 4 + playground/haxe/executable/bin/wscript | 43 ++++++ .../haxe/executable/haxe_libraries/readme.txt | 1 + playground/haxe/executable/lib/readme.txt | 1 + playground/haxe/executable/package.json | 18 +++ playground/haxe/executable/src/Main.hx | 5 + playground/haxe/executable/src/main.hxml | 2 + playground/haxe/executable/src/wscript | 13 ++ playground/haxe/executable/wscript | 15 ++ waflib/extras/haxe.py | 131 ++++++++++++++++++ 16 files changed, 277 insertions(+) create mode 100644 playground/haxe/bytecode/.haxerc create mode 100644 playground/haxe/bytecode/package.json create mode 100644 playground/haxe/bytecode/src/Main.hx create mode 100644 playground/haxe/bytecode/src/main.hxml create mode 100644 playground/haxe/bytecode/src/wscript create mode 100644 playground/haxe/bytecode/wscript create mode 100644 playground/haxe/executable/.haxerc create mode 100644 playground/haxe/executable/bin/wscript create mode 100644 playground/haxe/executable/haxe_libraries/readme.txt create mode 100644 playground/haxe/executable/lib/readme.txt create mode 100644 playground/haxe/executable/package.json create mode 100644 playground/haxe/executable/src/Main.hx create mode 100644 playground/haxe/executable/src/main.hxml create mode 100644 playground/haxe/executable/src/wscript create mode 100644 playground/haxe/executable/wscript create mode 100644 waflib/extras/haxe.py diff --git a/playground/haxe/bytecode/.haxerc b/playground/haxe/bytecode/.haxerc new file mode 100644 index 00000000..093ce54c --- /dev/null +++ b/playground/haxe/bytecode/.haxerc @@ -0,0 +1,4 @@ +{ + "version": "4.1.4", + "resolveLibs": "scoped" +} \ No newline at end of file diff --git a/playground/haxe/bytecode/package.json b/playground/haxe/bytecode/package.json new file mode 100644 index 00000000..abe82fad --- /dev/null +++ b/playground/haxe/bytecode/package.json @@ -0,0 +1,18 @@ +{ + "name": "Haxe", + "version": "1.0.0", + "description": "", + "main": "index.js", + "directories": { + "lib": "lib" + }, + "scripts": { + "postinstall": "lix download" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "lix": "^15.10.1" + } +} diff --git a/playground/haxe/bytecode/src/Main.hx b/playground/haxe/bytecode/src/Main.hx new file mode 100644 index 00000000..331e5bf8 --- /dev/null +++ b/playground/haxe/bytecode/src/Main.hx @@ -0,0 +1,5 @@ +class Main { + static function main() { + trace('hello'); + } +} diff --git a/playground/haxe/bytecode/src/main.hxml b/playground/haxe/bytecode/src/main.hxml new file mode 100644 index 00000000..a567cc29 --- /dev/null +++ b/playground/haxe/bytecode/src/main.hxml @@ -0,0 +1,2 @@ +-dce full +-main Main.hx diff --git a/playground/haxe/bytecode/src/wscript b/playground/haxe/bytecode/src/wscript new file mode 100644 index 00000000..6ad108d6 --- /dev/null +++ b/playground/haxe/bytecode/src/wscript @@ -0,0 +1,7 @@ +def configure(ctx): + ctx.load('haxe') + +def build(ctx): + ctx.haxe( + source = 'main.hxml', + target = 'main.hl') diff --git a/playground/haxe/bytecode/wscript b/playground/haxe/bytecode/wscript new file mode 100644 index 00000000..a753e5dd --- /dev/null +++ b/playground/haxe/bytecode/wscript @@ -0,0 +1,8 @@ +top = '.' +out = 'bin/waf' + +def configure(ctx): + ctx.recurse('src') + +def build(ctx): + ctx.recurse('src') diff --git a/playground/haxe/executable/.haxerc b/playground/haxe/executable/.haxerc new file mode 100644 index 00000000..093ce54c --- /dev/null +++ b/playground/haxe/executable/.haxerc @@ -0,0 +1,4 @@ +{ + "version": "4.1.4", + "resolveLibs": "scoped" +} \ No newline at end of file diff --git a/playground/haxe/executable/bin/wscript b/playground/haxe/executable/bin/wscript new file mode 100644 index 00000000..a27e4c1a --- /dev/null +++ b/playground/haxe/executable/bin/wscript @@ -0,0 +1,43 @@ +from waflib.TaskGen import feature + +def configure(ctx): + ctx.load('clang_cl') + ctx.env.CFLAGS.extend(['/EHsc', '/O12', '/TC', '/GL', '/w', '/U __llvm__']) + for lib in ['msvcrt']: + ctx.check( + compiler='c', + lib=lib, + uselib_store='SYSTEM') + for lib in ['libhl']: + ctx.check( + compiler='c', + lib=lib, + use='HL', + uselib_store='HL') + +def build(ctx): + ctx.env.LINKFLAGS.extend(['/NODEFAULTLIB:libcmt']) + ctx.program( + source = ['waf/src/main.c'], + includes = [ctx.env.ROOT_INCLUDE_DIR], + target = 'app', + use = ['SYSTEM', 'HL']) + +@feature('cxxprogram', 'cprogram') +def call_me_static(self): + attr_name = 'source' + attr = getattr(self, attr_name, []) + if len(attr): + setattr(self, attr_name, []) + for x in self.to_list(attr): + node = self.path.make_node(x) + tg = self.bld.get_tgen_by_name(node.name) + if not tg: + self.bld.fatal('Could not find a task generator by the name %r' % x) + tg.post() + for tsk in tg.tasks: + for out in tsk.outputs: + if out.name.endswith('.c'): + self.create_compiled_task('c', out) + if not self.compiled_tasks: + self.fatal('Could not find a source file for for %r' % self.name) diff --git a/playground/haxe/executable/haxe_libraries/readme.txt b/playground/haxe/executable/haxe_libraries/readme.txt new file mode 100644 index 00000000..e2bc21ff --- /dev/null +++ b/playground/haxe/executable/haxe_libraries/readme.txt @@ -0,0 +1 @@ +this directory is served by lix automatically and stores versions of used haxe libraries diff --git a/playground/haxe/executable/lib/readme.txt b/playground/haxe/executable/lib/readme.txt new file mode 100644 index 00000000..e5e14441 --- /dev/null +++ b/playground/haxe/executable/lib/readme.txt @@ -0,0 +1 @@ +place hashlink c libraries here (e.g. libhl.lib) - dedicated directory is used for a case when hashlink libs are statically linked diff --git a/playground/haxe/executable/package.json b/playground/haxe/executable/package.json new file mode 100644 index 00000000..abe82fad --- /dev/null +++ b/playground/haxe/executable/package.json @@ -0,0 +1,18 @@ +{ + "name": "Haxe", + "version": "1.0.0", + "description": "", + "main": "index.js", + "directories": { + "lib": "lib" + }, + "scripts": { + "postinstall": "lix download" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "lix": "^15.10.1" + } +} diff --git a/playground/haxe/executable/src/Main.hx b/playground/haxe/executable/src/Main.hx new file mode 100644 index 00000000..331e5bf8 --- /dev/null +++ b/playground/haxe/executable/src/Main.hx @@ -0,0 +1,5 @@ +class Main { + static function main() { + trace('hello'); + } +} diff --git a/playground/haxe/executable/src/main.hxml b/playground/haxe/executable/src/main.hxml new file mode 100644 index 00000000..a567cc29 --- /dev/null +++ b/playground/haxe/executable/src/main.hxml @@ -0,0 +1,2 @@ +-dce full +-main Main.hx diff --git a/playground/haxe/executable/src/wscript b/playground/haxe/executable/src/wscript new file mode 100644 index 00000000..41209563 --- /dev/null +++ b/playground/haxe/executable/src/wscript @@ -0,0 +1,13 @@ +def configure(ctx): + ctx.load('haxe') + ctx.ensure_lix_pkg( + compiler='hx', + libs=['hashlink'], + uselib_store='HLR') + +def build(ctx): + ctx.haxe( + source = 'main.hxml', + res = ctx.env.ROOT_RES_DIR, + target = 'main.c', + use = ['HLR']) diff --git a/playground/haxe/executable/wscript b/playground/haxe/executable/wscript new file mode 100644 index 00000000..a7e30565 --- /dev/null +++ b/playground/haxe/executable/wscript @@ -0,0 +1,15 @@ +top = '.' +out = 'bin/waf' + +def configure(ctx): + ctx.env.ROOT_INCLUDE_DIR = ctx.path.get_bld().make_node('src').abspath() + ctx.env.ROOT_RES_DIR = ctx.path.make_node('res').abspath() + ctx.env.LIBPATH_HAXE = ctx.path.make_node('haxe_libraries').abspath() + ctx.env.LIBPATH_HL = ctx.path.make_node('lib').abspath() + ctx.env.INCLUDES_HL = ['%hashlink%/hl-1.11.0-win/include'] + ctx.recurse('src') + ctx.recurse('bin') + +def build(ctx): + ctx.recurse('src') + ctx.recurse('bin') diff --git a/waflib/extras/haxe.py b/waflib/extras/haxe.py new file mode 100644 index 00000000..cb3ba6a9 --- /dev/null +++ b/waflib/extras/haxe.py @@ -0,0 +1,131 @@ +import os, re +from waflib import Utils, Task, Errors +from waflib.TaskGen import extension, taskgen_method, feature +from waflib.Configure import conf + +@conf +def libname_haxe(self, libname): + return libname + +@conf +def check_lib_haxe(self, libname, uselib_store=None): + haxe_libs = [node.name for node in self.root.find_node('haxe_libraries').ant_glob()] + changed = False + self.start_msg('Checking for library %s' % libname) + if libname + '.hxml' in haxe_libs: + self.end_msg('yes') + else: + changed = True + try: + cmd = self.env.LIX + ['+lib', libname] + res = self.cmd_and_log(cmd) + if (res): + raise Errors.WafError(res) + else: + self.end_msg('downloaded', color = 'YELLOW') + except Errors.WafError as e: + self.end_msg('no', color = 'RED') + self.fatal('Getting %s has failed' % libname) + + postfix = uselib_store if uselib_store else libname.upper() + self.env['LIB_' + postfix] += [self.libname_haxe(libname)] + return changed + +@conf +def check_libs_haxe(self, libnames, uselib_store=None): + changed = False + for libname in Utils.to_list(libnames): + if self.check_lib_haxe(libname, uselib_store): + changed = True + return changed + +@conf +def ensure_lix_pkg(self, *k, **kw): + if kw.get('compiler') == 'hx': + if isinstance(kw.get('libs'), list) and len(kw.get('libs')): + changed = self.check_libs_haxe(kw.get('libs'), kw.get('uselib_store')) + if changed: + try: + cmd = self.env.LIX + ['download'] + res = self.cmd_and_log(cmd) + if (res): + raise Errors.WafError(res) + except Errors.WafError as e: + self.fatal('lix download has failed') + else: + self.check_lib_haxe(kw.get('lib'), kw.get('uselib_store')) + +@conf +def haxe(bld, *k, **kw): + task_gen = bld(*k, **kw) + +class haxe(Task.Task): + vars = ['HAXE', 'HAXE_VERSION', 'HAXEFLAGS'] + ext_out = ['.hl', '.c', '.h'] + + def run(self): + cmd = self.env.HAXE + self.env.HAXEFLAGS + return self.exec_command(cmd, stdout = open(os.devnull, 'w')) + +@taskgen_method +def init_haxe_task(self, node): + def addflags(flags): + self.env.append_value('HAXEFLAGS', flags) + + if node.suffix() == '.hxml': + addflags(self.path.abspath() + '/' + node.name) + else: + addflags(['-main', node.name]) + addflags(['-hl', self.path.get_bld().make_node(self.target).abspath()]) + addflags(['-cp', self.path.abspath()]) + addflags(['-D', 'resourcesPath=%s' % getattr(self, 'res', '')]) + if hasattr(self, 'use'): + for dep in self.use: + if self.env['LIB_' + dep]: + for lib in self.env['LIB_' + dep]: addflags(['-lib', lib]) + +@extension('.hx', '.hxml') +def haxe_file(self, node): + if len(self.source) > 1: + self.bld.fatal('Use separate task generators for multiple files') + + try: + haxetask = self.haxetask + except AttributeError: + haxetask = self.haxetask = self.create_task('haxe') + self.init_haxe_task(node) + + haxetask.inputs.append(node) + haxetask.outputs.append(self.path.get_bld().make_node(self.target)) + +@conf +def find_haxe(self, min_version): + npx = self.env.NPX = self.find_program('npx') + self.env.LIX = npx + ['lix'] + npx_haxe = self.env.HAXE = npx + ['haxe'] + try: + output = self.cmd_and_log(npx_haxe + ['-version']) + except Errors.WafError: + haxe_version = None + else: + ver = re.search(r'\d+.\d+.\d+', output).group().split('.') + haxe_version = tuple([int(x) for x in ver]) + + self.msg('Checking for haxe version', + haxe_version, haxe_version and haxe_version >= min_version) + if npx_haxe and haxe_version < min_version: + self.fatal('haxe version %r is too old, need >= %r' % (haxe_version, min_version)) + + self.env.HAXE_VERSION = haxe_version + return npx_haxe + +@conf +def check_haxe(self, min_version=(4,1,4)): + if self.env.HAXE_MINVER: + min_version = self.env.HAXE_MINVER + find_haxe(self, min_version) + +def configure(self): + self.env.HAXEFLAGS = [] + self.check_haxe() + self.add_os_flags('HAXEFLAGS', dup = False)