mirror of
https://gitlab.com/ita1024/waf.git
synced 2024-11-22 01:46:15 +01:00
Haxe Toolkit support
This commit is contained in:
parent
d4f495bced
commit
67dcb2b7f6
@ -1,4 +0,0 @@
|
||||
{
|
||||
"version": "4.1.4",
|
||||
"resolveLibs": "scoped"
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
-dce full
|
||||
-main Main.hx
|
@ -1,7 +1,15 @@
|
||||
def configure(ctx):
|
||||
ctx.load('haxe')
|
||||
ctx.check_haxe(mini='4.0.0', maxi='4.2.5')
|
||||
ctx.check_haxe_pkg(
|
||||
libs=['hashlink'],
|
||||
uselib_store='HLR',
|
||||
fetch=False)
|
||||
|
||||
def build(ctx):
|
||||
ctx.haxe(
|
||||
source = 'main.hxml',
|
||||
target = 'main.hl')
|
||||
ctx.env.HAXE_FLAGS = ['-dce', 'full', '-main', 'Main']
|
||||
ctx(
|
||||
compiler = 'HL',
|
||||
source = 'Main.hx',
|
||||
target = 'out.hl',
|
||||
use = ['HLR'])
|
||||
|
@ -1,5 +1,5 @@
|
||||
top = '.'
|
||||
out = 'bin/waf'
|
||||
out = 'build'
|
||||
|
||||
def configure(ctx):
|
||||
ctx.recurse('src')
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"version": "4.1.4",
|
||||
"resolveLibs": "scoped"
|
||||
}
|
19
playground/haxe/executable/README.md
Normal file
19
playground/haxe/executable/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Using `HLC` source generation with `clang`
|
||||
|
||||
## Environment
|
||||
In this particular case, you need to have a distribution of `hashlink` in your system. After installing, you need to perform additional steps to pass required files for binary generation (in this case - to `clang`):
|
||||
|
||||
- either add hashlink's `lib` folder to `ctx.env.LIBPATH_HL`
|
||||
- or replace `lib` folder with a symlink to hashlink's `lib` folder
|
||||
- either add hashlink's `include` folder to `ctx.env.INCLUDES_HL`
|
||||
- or replace `include` folder with a symlink to hashlink's `include` folder
|
||||
|
||||
## Targets
|
||||
In this particular case, generated `.c` files are placed in separate `bin` subdirectory. This enhances your build transparency and allows you to add desired checks or perform additional operations with generated `.c` sources if needed, while keeping things in parallel. Keep this in mind if you're planning to extend your build layout with additional Haxe targets
|
||||
|
||||
## Running assembled binaries
|
||||
Assuming that you have a `hashlink` distribution and all relevant system paths are adjusted, you could easily run your binary and see resulting output of `Main.hx:3: hello`. Keep in mind that if you're using an official `hashlink` distribution, it doesn't come with static libs for linking - this means that your produced binary requires paths to `libhl.dll` (or `.so`/`.dylib` - depends on your system). Of course, there may be a use case when you're building `hashlink` from sources or using it as a portable distribution - in these cases, you could run your binary while pointing paths to your dynamic libraries with adding correct paths (`$PWD/lib/` for example) to:
|
||||
|
||||
- `PATH` on windows
|
||||
- `LD_LIBRARY_PATH` on linux
|
||||
- `DYLD_LIBRARY_PATH` on macOS
|
@ -1,43 +1,14 @@
|
||||
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')
|
||||
ctx.load('clang')
|
||||
ctx.check(
|
||||
compiler='c',
|
||||
lib='hl',
|
||||
use='HL',
|
||||
uselib_store='HL')
|
||||
|
||||
def build(ctx):
|
||||
ctx.env.LINKFLAGS.extend(['/NODEFAULTLIB:libcmt'])
|
||||
ctx.program(
|
||||
source = ['waf/src/main.c'],
|
||||
source = [ctx.bldnode.make_node('src/main/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)
|
||||
use = ['HL'])
|
||||
|
@ -1 +0,0 @@
|
||||
this directory is served by lix automatically and stores versions of used haxe libraries
|
1
playground/haxe/executable/include/readme.txt
Normal file
1
playground/haxe/executable/include/readme.txt
Normal file
@ -0,0 +1 @@
|
||||
place hashlink includes here (e.g. hlc.h) or replace this directory with symlink if using package manager - dedicated directory is used when native hashlink includes are used
|
@ -1 +1 @@
|
||||
place hashlink c libraries here (e.g. libhl.lib) - dedicated directory is used for a case when hashlink libs are statically linked
|
||||
place hashlink libraries here (e.g. libhl.so) or replace this directory with symlink if using package manager - dedicated directory is used when native hashlink libs are linked
|
||||
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
-dce full
|
||||
-main Main.hx
|
@ -1,13 +1,15 @@
|
||||
def configure(ctx):
|
||||
ctx.load('haxe')
|
||||
ctx.ensure_lix_pkg(
|
||||
compiler='hx',
|
||||
ctx.check_haxe(mini='4.0.0', maxi='4.2.5')
|
||||
ctx.check_haxe_pkg(
|
||||
libs=['hashlink'],
|
||||
uselib_store='HLR')
|
||||
|
||||
def build(ctx):
|
||||
ctx.haxe(
|
||||
source = 'main.hxml',
|
||||
ctx.env.HAXE_FLAGS = ['-dce', 'full', '-main', 'Main']
|
||||
ctx(
|
||||
compiler = 'HLC',
|
||||
source = 'Main.hx',
|
||||
res = ctx.env.ROOT_RES_DIR,
|
||||
target = 'main.c',
|
||||
target = 'main',
|
||||
use = ['HLR'])
|
||||
|
@ -2,11 +2,11 @@ top = '.'
|
||||
out = 'bin/waf'
|
||||
|
||||
def configure(ctx):
|
||||
ctx.env.ROOT_INCLUDE_DIR = ctx.path.get_bld().make_node('src').abspath()
|
||||
ctx.env.ROOT_INCLUDE_DIR = ctx.path.get_bld().make_node('src').make_node('main').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.env.INCLUDES_HL = ctx.path.make_node('include').abspath()
|
||||
ctx.recurse('src')
|
||||
ctx.recurse('bin')
|
||||
|
||||
|
@ -1,131 +1,154 @@
|
||||
import os, re
|
||||
from waflib import Utils, Task, Errors
|
||||
from waflib.TaskGen import extension, taskgen_method, feature
|
||||
import re
|
||||
|
||||
from waflib import Utils, Task, Errors, Logs
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import extension, taskgen_method
|
||||
|
||||
HAXE_COMPILERS = {
|
||||
'JS': {'tgt': '--js', 'ext_out': ['.js']},
|
||||
'LUA': {'tgt': '--lua', 'ext_out': ['.lua']},
|
||||
'SWF': {'tgt': '--swf', 'ext_out': ['.swf']},
|
||||
'NEKO': {'tgt': '--neko', 'ext_out': ['.n']},
|
||||
'PHP': {'tgt': '--php', 'ext_out': ['.php']},
|
||||
'CPP': {'tgt': '--cpp', 'ext_out': ['.h', '.cpp']},
|
||||
'CPPIA': {'tgt': '--cppia', 'ext_out': ['.cppia']},
|
||||
'CS': {'tgt': '--cs', 'ext_out': ['.cs']},
|
||||
'JAVA': {'tgt': '--java', 'ext_out': ['.java']},
|
||||
'JVM': {'tgt': '--jvm', 'ext_out': ['.jar']},
|
||||
'PYTHON': {'tgt': '--python', 'ext_out': ['.py']},
|
||||
'HL': {'tgt': '--hl', 'ext_out': ['.hl']},
|
||||
'HLC': {'tgt': '--hl', 'ext_out': ['.h', '.c']},
|
||||
}
|
||||
|
||||
@conf
|
||||
def libname_haxe(self, libname):
|
||||
return libname
|
||||
def check_haxe_pkg(self, **kw):
|
||||
self.find_program('haxelib')
|
||||
libs = kw.get('libs')
|
||||
if not libs or not (type(libs) == str or (type(libs) == list and all(isinstance(s, str) for s in libs))):
|
||||
self.fatal('Specify correct libs value in ensure call')
|
||||
return
|
||||
fetch = kw.get('fetch')
|
||||
if not fetch is None and not type(fetch) == bool:
|
||||
self.fatal('Specify correct fetch value in ensure call')
|
||||
|
||||
@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)
|
||||
libs = [libs] if type(libs) == str else libs
|
||||
halt = False
|
||||
for lib in libs:
|
||||
try:
|
||||
self.start_msg('Checking for library %s' % lib)
|
||||
output = self.cmd_and_log(self.env.HAXELIB + ['list', lib])
|
||||
except Errors.WafError:
|
||||
self.end_msg(False)
|
||||
self.fatal('Can\'t run haxelib list, ensuring halted')
|
||||
return
|
||||
|
||||
postfix = uselib_store if uselib_store else libname.upper()
|
||||
self.env['LIB_' + postfix] += [self.libname_haxe(libname)]
|
||||
return changed
|
||||
if lib in output:
|
||||
self.end_msg(lib in output)
|
||||
else:
|
||||
if not fetch:
|
||||
self.end_msg(False)
|
||||
halt = True
|
||||
continue
|
||||
try:
|
||||
status = self.exec_command(self.env.HAXELIB + ['install', lib])
|
||||
if status:
|
||||
self.end_msg(False)
|
||||
self.fatal('Can\'t get %s with haxelib, ensuring halted' % lib)
|
||||
return
|
||||
else:
|
||||
self.end_msg('downloaded', color='YELLOW')
|
||||
except Errors.WafError:
|
||||
self.end_msg(False)
|
||||
self.fatal('Can\'t run haxelib install, ensuring halted')
|
||||
return
|
||||
postfix = kw.get('uselib_store') or lib.upper()
|
||||
self.env.append_unique('LIB_' + postfix, lib)
|
||||
|
||||
@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)
|
||||
if halt:
|
||||
self.fatal('Can\'t find libraries in haxelib list, ensuring halted')
|
||||
return
|
||||
|
||||
class haxe(Task.Task):
|
||||
vars = ['HAXE', 'HAXE_VERSION', 'HAXEFLAGS']
|
||||
ext_out = ['.hl', '.c', '.h']
|
||||
vars = ['HAXE_VERSION', 'HAXE_FLAGS']
|
||||
ext_in = ['.hx']
|
||||
|
||||
def run(self):
|
||||
cmd = self.env.HAXE + self.env.HAXEFLAGS
|
||||
return self.exec_command(cmd, stdout = open(os.devnull, 'w'))
|
||||
def run(self):
|
||||
cmd = self.env.HAXE + self.env.HAXE_FLAGS_DEFAULT + self.env.HAXE_FLAGS
|
||||
return self.exec_command(cmd)
|
||||
|
||||
for COMP in HAXE_COMPILERS:
|
||||
# create runners for each compile target
|
||||
type("haxe_" + COMP, (haxe,), {'ext_out': HAXE_COMPILERS[COMP]['ext_out']})
|
||||
|
||||
@taskgen_method
|
||||
def init_haxe_task(self, node):
|
||||
def addflags(flags):
|
||||
self.env.append_value('HAXEFLAGS', flags)
|
||||
def init_haxe(self):
|
||||
errmsg = '%s not found, specify correct value'
|
||||
try:
|
||||
compiler = HAXE_COMPILERS[self.compiler]
|
||||
comp_tgt = compiler['tgt']
|
||||
comp_mod = '/main.c' if self.compiler == 'HLC' else ''
|
||||
except (AttributeError, KeyError):
|
||||
self.bld.fatal(errmsg % 'COMPILER' + ': ' + ', '.join(HAXE_COMPILERS.keys()))
|
||||
return
|
||||
|
||||
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])
|
||||
self.env.append_value(
|
||||
'HAXE_FLAGS',
|
||||
[comp_tgt, self.path.get_bld().make_node(self.target + comp_mod).abspath()])
|
||||
if hasattr(self, 'use'):
|
||||
if not (type(self.use) == str or type(self.use) == list):
|
||||
self.bld.fatal(errmsg % 'USE')
|
||||
return
|
||||
self.use = [self.use] if type(self.use) == str else self.use
|
||||
|
||||
@extension('.hx', '.hxml')
|
||||
def haxe_file(self, node):
|
||||
if len(self.source) > 1:
|
||||
self.bld.fatal('Use separate task generators for multiple files')
|
||||
for dep in self.use:
|
||||
if self.env['LIB_' + dep]:
|
||||
for lib in self.env['LIB_' + dep]:
|
||||
self.env.append_value('HAXE_FLAGS', ['-lib', lib])
|
||||
|
||||
try:
|
||||
haxetask = self.haxetask
|
||||
except AttributeError:
|
||||
haxetask = self.haxetask = self.create_task('haxe')
|
||||
self.init_haxe_task(node)
|
||||
if hasattr(self, 'res'):
|
||||
if not type(self.res) == str:
|
||||
self.bld.fatal(errmsg % 'RES')
|
||||
return
|
||||
self.env.append_value('HAXE_FLAGS', ['-D', 'resourcesPath=%s' % self.res])
|
||||
|
||||
haxetask.inputs.append(node)
|
||||
haxetask.outputs.append(self.path.get_bld().make_node(self.target))
|
||||
@extension('.hx')
|
||||
def haxe_hook(self, node):
|
||||
if len(self.source) > 1:
|
||||
self.bld.fatal('Use separate task generators for multiple files')
|
||||
return
|
||||
|
||||
src = node
|
||||
tgt = self.path.get_bld().find_or_declare(self.target)
|
||||
|
||||
self.init_haxe()
|
||||
self.create_task('haxe_' + self.compiler, src, tgt)
|
||||
|
||||
@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])
|
||||
def check_haxe(self, mini=None, maxi=None):
|
||||
self.start_msg('Checking for haxe version')
|
||||
try:
|
||||
curr = re.search(
|
||||
r'(\d+.?)+',
|
||||
self.cmd_and_log(self.env.HAXE + ['-version'])).group()
|
||||
except Errors.WafError:
|
||||
self.end_msg(False)
|
||||
self.fatal('Can\'t get haxe version')
|
||||
return
|
||||
|
||||
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)
|
||||
if mini and Utils.num2ver(curr) < Utils.num2ver(mini):
|
||||
self.end_msg('wrong', color='RED')
|
||||
self.fatal('%s is too old, need >= %s' % (curr, mini))
|
||||
return
|
||||
if maxi and Utils.num2ver(curr) > Utils.num2ver(maxi):
|
||||
self.end_msg('wrong', color='RED')
|
||||
self.fatal('%s is too new, need <= %s' % (curr, maxi))
|
||||
return
|
||||
self.end_msg(curr, color='GREEN')
|
||||
self.env.HAXE_VERSION = curr
|
||||
|
||||
def configure(self):
|
||||
self.env.HAXEFLAGS = []
|
||||
self.check_haxe()
|
||||
self.add_os_flags('HAXEFLAGS', dup = False)
|
||||
self.env.append_value(
|
||||
'HAXE_FLAGS_DEFAULT',
|
||||
['-D', 'no-compilation', '-cp', self.path.abspath()])
|
||||
Logs.warn('Default flags: %s' % ' '.join(self.env.HAXE_FLAGS_DEFAULT))
|
||||
self.find_program('haxe')
|
||||
|
Loading…
Reference in New Issue
Block a user