Convert build scripts to Python #31
|
@ -1,131 +1,135 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("bindgen require an api name\n")
|
||||
exit(-1);
|
||||
def bindgen(apiName, cdir):
|
||||
inPath = cdir + '/bindgen_' + apiName + '_api.txt'
|
||||
outPath = cdir + '/bindgen_' + apiName + '_api.c'
|
||||
|
||||
apiName = sys.argv[1]
|
||||
cdir = ''
|
||||
inFile = open(inPath, 'r')
|
||||
outFile = open(outPath, 'w')
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
cdir = sys.argv[2]
|
||||
stubs = []
|
||||
links = []
|
||||
|
||||
inPath = cdir + '/bindgen_' + apiName + '_api.txt'
|
||||
outPath = cdir + '/bindgen_' + apiName + '_api.c'
|
||||
def gen_stub(name, sig, native_name):
|
||||
if native_name == None:
|
||||
native_name = name
|
||||
|
||||
inFile = open(inPath, 'r')
|
||||
outFile = open(outPath, 'w')
|
||||
src = 'const void* ' + name + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)\n'
|
||||
src += '{\n'
|
||||
spIndex = 0
|
||||
|
||||
stubs = []
|
||||
links = []
|
||||
parsingRet = True
|
||||
retCount = 0
|
||||
argCount = 0
|
||||
retString = ''
|
||||
argString = ''
|
||||
|
||||
def gen_stub(name, sig, native_name):
|
||||
if native_name == None:
|
||||
native_name = name
|
||||
|
||||
src = 'const void* ' + name + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)\n'
|
||||
src += '{\n'
|
||||
spIndex = 0
|
||||
|
||||
parsingRet = True
|
||||
retCount = 0
|
||||
argCount = 0
|
||||
retString = ''
|
||||
argString = ''
|
||||
|
||||
for index, c in enumerate(sig):
|
||||
if parsingRet:
|
||||
if retCount > 1:
|
||||
print('unsupported multiple return types\n')
|
||||
break
|
||||
if c == '(':
|
||||
parsingRet = False
|
||||
continue
|
||||
elif c == ')':
|
||||
print('unexpected ) while parsing return type\n')
|
||||
break;
|
||||
elif c == 'v':
|
||||
continue
|
||||
elif c == 'i':
|
||||
retString = '*((i32*)&_sp[0]) = '
|
||||
elif c == 'I':
|
||||
retString = '*((i64*)&_sp[0]) = '
|
||||
elif c == 'f':
|
||||
retString = '*((f32*)&_sp[0]) = '
|
||||
elif c == 'F':
|
||||
retString = '*((f64*)&_sp[0]) = '
|
||||
elif c == 'p':
|
||||
print('returning pointers is not supported yet\n')
|
||||
break
|
||||
for index, c in enumerate(sig):
|
||||
if parsingRet:
|
||||
if retCount > 1:
|
||||
print('unsupported multiple return types\n')
|
||||
break
|
||||
if c == '(':
|
||||
parsingRet = False
|
||||
continue
|
||||
elif c == ')':
|
||||
print('unexpected ) while parsing return type\n')
|
||||
break;
|
||||
elif c == 'v':
|
||||
continue
|
||||
elif c == 'i':
|
||||
retString = '*((i32*)&_sp[0]) = '
|
||||
elif c == 'I':
|
||||
retString = '*((i64*)&_sp[0]) = '
|
||||
elif c == 'f':
|
||||
retString = '*((f32*)&_sp[0]) = '
|
||||
elif c == 'F':
|
||||
retString = '*((f64*)&_sp[0]) = '
|
||||
elif c == 'p':
|
||||
print('returning pointers is not supported yet\n')
|
||||
break
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure return\n')
|
||||
break
|
||||
retCount += 1
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure return\n')
|
||||
break
|
||||
retCount += 1
|
||||
else:
|
||||
argIndex = argCount + retCount
|
||||
if c == ')':
|
||||
break
|
||||
elif c == 'v':
|
||||
break
|
||||
elif c == 'i':
|
||||
argString += '*(i32*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'I':
|
||||
argString += '*(i64*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'f':
|
||||
argString += '*(f32*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'F':
|
||||
argString += '*(f64*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'p':
|
||||
argString += '(void*)((char*)_mem + *(i32*)&_sp[' + str(argIndex) + '])'
|
||||
argIndex = argCount + retCount
|
||||
if c == ')':
|
||||
break
|
||||
elif c == 'v':
|
||||
break
|
||||
elif c == 'i':
|
||||
argString += '*(i32*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'I':
|
||||
argString += '*(i64*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'f':
|
||||
argString += '*(f32*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'F':
|
||||
argString += '*(f64*)&_sp[' + str(argIndex) + ']'
|
||||
elif c == 'p':
|
||||
argString += '(void*)((char*)_mem + *(i32*)&_sp[' + str(argIndex) + '])'
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure signature\n')
|
||||
break
|
||||
|
||||
if index+2 < len(sig):
|
||||
argString += ', '
|
||||
argCount += 1
|
||||
|
||||
src += '\t' + retString + native_name + '(' + argString + ');\n'
|
||||
src += '\treturn(0);\n'
|
||||
src += '}\n'
|
||||
stubs.append(src)
|
||||
|
||||
def gen_link(name, sig):
|
||||
m3_Sig = ''
|
||||
for c in sig:
|
||||
if c == 'p':
|
||||
m3_Sig += 'i'
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure signature\n')
|
||||
break
|
||||
m3_Sig += c
|
||||
|
||||
if index+2 < len(sig):
|
||||
argString += ', '
|
||||
argCount += 1
|
||||
src = '\tres = m3_LinkRawFunction(module, "*", "' + name + '", "' + m3_Sig + '", ' + name + '_stub);\n'
|
||||
src += '\tif(res != m3Err_none && res != m3Err_functionLookupFailed) { log_error("error: %s\\n", res); return(-1); }\n\n'
|
||||
links.append(src)
|
||||
|
||||
src += '\t' + retString + native_name + '(' + argString + ');\n'
|
||||
src += '\treturn(0);\n'
|
||||
src += '}\n'
|
||||
stubs.append(src)
|
||||
for line in inFile:
|
||||
if line.isspace():
|
||||
continue
|
||||
desc = line.split()
|
||||
|
||||
def gen_link(name, sig):
|
||||
m3_Sig = ''
|
||||
for c in sig:
|
||||
if c == 'p':
|
||||
m3_Sig += 'i'
|
||||
else:
|
||||
m3_Sig += c
|
||||
gen_stub(desc[0], desc[1], desc[2] if len(desc) > 2 else None)
|
||||
gen_link(desc[0], desc[1])
|
||||
|
||||
src = '\tres = m3_LinkRawFunction(module, "*", "' + name + '", "' + m3_Sig + '", ' + name + '_stub);\n'
|
||||
src += '\tif(res != m3Err_none && res != m3Err_functionLookupFailed) { log_error("error: %s\\n", res); return(-1); }\n\n'
|
||||
links.append(src)
|
||||
linkProc = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n'
|
||||
linkProc += '{\n'
|
||||
linkProc += '\tM3Result res;\n'
|
||||
|
||||
for line in inFile:
|
||||
if line.isspace():
|
||||
continue
|
||||
desc = line.split()
|
||||
for link in links:
|
||||
linkProc += link
|
||||
|
||||
gen_stub(desc[0], desc[1], desc[2] if len(desc) > 2 else None)
|
||||
gen_link(desc[0], desc[1])
|
||||
linkProc += '\treturn(0);\n'
|
||||
linkProc += '}\n'
|
||||
|
||||
linkProc = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n'
|
||||
linkProc += '{\n'
|
||||
linkProc += '\tM3Result res;\n'
|
||||
for stub in stubs:
|
||||
outFile.write(stub)
|
||||
|
||||
for link in links:
|
||||
linkProc += link
|
||||
outFile.write('\n')
|
||||
outFile.write(linkProc)
|
||||
|
||||
linkProc += '\treturn(0);\n'
|
||||
linkProc += '}\n'
|
||||
inFile.close()
|
||||
outFile.close()
|
||||
|
||||
for stub in stubs:
|
||||
outFile.write(stub)
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("bindgen require an api name\n")
|
||||
exit(-1)
|
||||
|
||||
outFile.write('\n')
|
||||
outFile.write(linkProc)
|
||||
apiName = sys.argv[1]
|
||||
cdir = ''
|
||||
|
||||
inFile.close()
|
||||
outFile.close()
|
||||
if len(sys.argv) > 2:
|
||||
cdir = sys.argv[2]
|
||||
|
||||
bindgen(apiName, cdir)
|
||||
|
|
|
@ -3,31 +3,6 @@
|
|||
from argparse import ArgumentParser
|
||||
import json
|
||||
|
||||
parser = ArgumentParser(prog='bindgen.py')
|
||||
parser.add_argument('api')
|
||||
parser.add_argument('spec')
|
||||
parser.add_argument('-g', '--guest-stubs')
|
||||
parser.add_argument('--guest-include')
|
||||
parser.add_argument('--wasm3-bindings')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
apiName = args.api
|
||||
spec = args.spec
|
||||
guest_stubs_path = args.guest_stubs
|
||||
if guest_stubs_path == None:
|
||||
guest_stubs_path = 'bindgen_' + apiName + '_guest_stubs.c'
|
||||
|
||||
wasm3_bindings_path = args.wasm3_bindings
|
||||
if wasm3_bindings_path == None:
|
||||
wasm3_bindings_path = 'bindgen_' + apiName + '_wasm3_bindings.c'
|
||||
|
||||
host_bindings = open(wasm3_bindings_path, 'w')
|
||||
guest_bindings = None
|
||||
|
||||
specFile = open(spec, 'r')
|
||||
data = json.load(specFile)
|
||||
|
||||
def needs_arg_ptr_stub(decl):
|
||||
res = (decl['ret']['tag'] == 'S')
|
||||
for arg in decl['args']:
|
||||
|
@ -35,167 +10,205 @@ def needs_arg_ptr_stub(decl):
|
|||
res = True
|
||||
return(res)
|
||||
|
||||
for decl in data:
|
||||
if needs_arg_ptr_stub(decl):
|
||||
guest_bindings = open(guest_stubs_path, 'w')
|
||||
if args.guest_include != None:
|
||||
s = '#include"' + args.guest_include + '"\n\n'
|
||||
print(s, file=guest_bindings)
|
||||
break
|
||||
def bindgen2(apiName, spec, **kwargs):
|
||||
guest_stubs_path = kwargs["guest_stubs"]
|
||||
guest_include = kwargs.get("guest-include")
|
||||
wasm3_bindings_path = kwargs["wasm3_bindings"]
|
||||
|
||||
for decl in data:
|
||||
host_bindings = open(wasm3_bindings_path, 'w')
|
||||
guest_bindings = None
|
||||
|
||||
name = decl['name']
|
||||
cname = decl.get('cname', name)
|
||||
specFile = open(spec, 'r')
|
||||
data = json.load(specFile)
|
||||
|
||||
if needs_arg_ptr_stub(decl):
|
||||
argPtrStubName = name + '_argptr_stub'
|
||||
# pointer arg stub declaration
|
||||
s = ''
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += 'void'
|
||||
else:
|
||||
s += decl['ret']['name']
|
||||
for decl in data:
|
||||
if needs_arg_ptr_stub(decl):
|
||||
guest_bindings = open(guest_stubs_path, 'w')
|
||||
if guest_include != None:
|
||||
s = '#include"' + guest_include + '"\n\n'
|
||||
print(s, file=guest_bindings)
|
||||
break
|
||||
|
||||
s += ' ORCA_IMPORT(' + argPtrStubName + ') ('
|
||||
for decl in data:
|
||||
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += decl['ret']['name'] + '* __retArg'
|
||||
if len(decl['args']) > 0:
|
||||
s += ', '
|
||||
name = decl['name']
|
||||
cname = decl.get('cname', name)
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
s += arg['type']['name']
|
||||
if arg['type']['tag'] == 'S':
|
||||
s += '*'
|
||||
s += ' ' + arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ');\n\n'
|
||||
|
||||
# forward function to pointer arg stub declaration
|
||||
s += decl['ret']['name'] + ' ' + name + '('
|
||||
for i, arg in enumerate(decl['args']):
|
||||
s += arg['type']['name'] + ' ' + arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ')\n'
|
||||
s += '{\n'
|
||||
s += '\t'
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += decl['ret']['name'] + ' __ret;\n\t'
|
||||
elif decl['ret']['tag'] != 'v':
|
||||
s += decl['ret']['name']
|
||||
s += ' __ret = '
|
||||
s += argPtrStubName + '('
|
||||
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += '&__ret'
|
||||
if len(decl['args']) > 0:
|
||||
s += ', '
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
if arg['type']['tag'] == 'S':
|
||||
s += '&'
|
||||
|
||||
s += arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ');\n'
|
||||
if decl['ret']['tag'] != 'v':
|
||||
s += '\treturn(__ret);\n'
|
||||
s += '}\n\n'
|
||||
|
||||
print(s, file=guest_bindings)
|
||||
|
||||
# host-side stub
|
||||
s = 'const void* ' + cname + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)'
|
||||
|
||||
gen_stub = decl.get('gen_stub', True)
|
||||
if gen_stub == False:
|
||||
s += ';\n\n'
|
||||
else:
|
||||
s += '\n{\n\t'
|
||||
retTag = decl['ret']['tag']
|
||||
|
||||
if retTag == 'i':
|
||||
s += '*((i32*)&_sp[0]) = '
|
||||
elif retTag == 'I':
|
||||
s += '*((i64*)&_sp[0]) = '
|
||||
elif retTag == 'f':
|
||||
s += '*((f32*)&_sp[0]) = '
|
||||
elif retTag == 'F':
|
||||
s += '*((f64*)&_sp[0]) = '
|
||||
elif retTag == 'S':
|
||||
retTypeName = decl['ret']['name']
|
||||
retTypeCName = decl['ret'].get('cname', retTypeName)
|
||||
s += '*(' + retTypeCName + '*)((char*)_mem + *(i32*)&_sp[0]) = '
|
||||
|
||||
s += cname + '('
|
||||
|
||||
firstArgIndex = 0
|
||||
if retTag != 'v':
|
||||
firstArgIndex = 1
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
typeName = arg['type']['name']
|
||||
typeCName = arg['type'].get('cname', typeName)
|
||||
argTag = arg['type']['tag']
|
||||
if argTag == 'i':
|
||||
s += '*(i32*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'I':
|
||||
s += '*(i64*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'f':
|
||||
s += '*(f32*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'F':
|
||||
s += '*(f64*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'p':
|
||||
s += '(void*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])'
|
||||
elif argTag == 'S':
|
||||
s += '*(' + typeCName + '*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])'
|
||||
if needs_arg_ptr_stub(decl):
|
||||
argPtrStubName = name + '_argptr_stub'
|
||||
# pointer arg stub declaration
|
||||
s = ''
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += 'void'
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure signature\n')
|
||||
break
|
||||
s += decl['ret']['name']
|
||||
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ' ORCA_IMPORT(' + argPtrStubName + ') ('
|
||||
|
||||
s += ');\n\treturn(0);\n}\n\n'
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += decl['ret']['name'] + '* __retArg'
|
||||
if len(decl['args']) > 0:
|
||||
s += ', '
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
s += arg['type']['name']
|
||||
if arg['type']['tag'] == 'S':
|
||||
s += '*'
|
||||
s += ' ' + arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ');\n\n'
|
||||
|
||||
# forward function to pointer arg stub declaration
|
||||
s += decl['ret']['name'] + ' ' + name + '('
|
||||
for i, arg in enumerate(decl['args']):
|
||||
s += arg['type']['name'] + ' ' + arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ')\n'
|
||||
s += '{\n'
|
||||
s += '\t'
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += decl['ret']['name'] + ' __ret;\n\t'
|
||||
elif decl['ret']['tag'] != 'v':
|
||||
s += decl['ret']['name']
|
||||
s += ' __ret = '
|
||||
s += argPtrStubName + '('
|
||||
|
||||
if decl['ret']['tag'] == 'S':
|
||||
s += '&__ret'
|
||||
if len(decl['args']) > 0:
|
||||
s += ', '
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
if arg['type']['tag'] == 'S':
|
||||
s += '&'
|
||||
|
||||
s += arg['name']
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
s += ');\n'
|
||||
if decl['ret']['tag'] != 'v':
|
||||
s += '\treturn(__ret);\n'
|
||||
s += '}\n\n'
|
||||
|
||||
print(s, file=guest_bindings)
|
||||
|
||||
# host-side stub
|
||||
s = 'const void* ' + cname + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)'
|
||||
|
||||
gen_stub = decl.get('gen_stub', True)
|
||||
if gen_stub == False:
|
||||
s += ';\n\n'
|
||||
else:
|
||||
s += '\n{\n\t'
|
||||
retTag = decl['ret']['tag']
|
||||
|
||||
if retTag == 'i':
|
||||
s += '*((i32*)&_sp[0]) = '
|
||||
elif retTag == 'I':
|
||||
s += '*((i64*)&_sp[0]) = '
|
||||
elif retTag == 'f':
|
||||
s += '*((f32*)&_sp[0]) = '
|
||||
elif retTag == 'F':
|
||||
s += '*((f64*)&_sp[0]) = '
|
||||
elif retTag == 'S':
|
||||
retTypeName = decl['ret']['name']
|
||||
retTypeCName = decl['ret'].get('cname', retTypeName)
|
||||
s += '*(' + retTypeCName + '*)((char*)_mem + *(i32*)&_sp[0]) = '
|
||||
|
||||
s += cname + '('
|
||||
|
||||
firstArgIndex = 0
|
||||
if retTag != 'v':
|
||||
firstArgIndex = 1
|
||||
|
||||
for i, arg in enumerate(decl['args']):
|
||||
typeName = arg['type']['name']
|
||||
typeCName = arg['type'].get('cname', typeName)
|
||||
argTag = arg['type']['tag']
|
||||
if argTag == 'i':
|
||||
s += '*(i32*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'I':
|
||||
s += '*(i64*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'f':
|
||||
s += '*(f32*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'F':
|
||||
s += '*(f64*)&_sp[' + str(firstArgIndex + i) + ']'
|
||||
elif argTag == 'p':
|
||||
s += '(void*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])'
|
||||
elif argTag == 'S':
|
||||
s += '*(' + typeCName + '*)((char*)_mem + *(i32*)&_sp[' + str(firstArgIndex + i) + '])'
|
||||
else:
|
||||
print('unrecognized type ' + c + ' in procedure signature\n')
|
||||
break
|
||||
|
||||
if i+1 < len(decl['args']):
|
||||
s += ', '
|
||||
|
||||
s += ');\n\treturn(0);\n}\n\n'
|
||||
|
||||
print(s, file=host_bindings)
|
||||
|
||||
# link function
|
||||
s = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n{\n\t'
|
||||
s += 'M3Result res;\n'
|
||||
|
||||
for decl in data:
|
||||
name = decl['name']
|
||||
cname = decl.get('cname', name)
|
||||
|
||||
if needs_arg_ptr_stub(decl):
|
||||
name = name + '_argptr_stub'
|
||||
|
||||
m3Sig = ''
|
||||
if decl['ret']['tag'] == 'S':
|
||||
m3Sig += 'v'
|
||||
else:
|
||||
m3Sig += decl['ret']['tag']
|
||||
|
||||
m3Sig += '('
|
||||
if decl['ret']['tag'] == 'S':
|
||||
m3Sig += 'i'
|
||||
for arg in decl['args']:
|
||||
tag = arg['type']['tag']
|
||||
if tag == 'p' or tag == 'S':
|
||||
tag = 'i'
|
||||
m3Sig += tag
|
||||
m3Sig += ')'
|
||||
|
||||
|
||||
s += '\tres = m3_LinkRawFunction(module, "*", "' + name + '", "' + m3Sig + '", ' + cname + '_stub);\n'
|
||||
s += '\tif(res != m3Err_none && res != m3Err_functionLookupFailed) { log_error("error: %s\\n", res); return(-1); }\n\n'
|
||||
|
||||
|
||||
s += '\treturn(0);\n}\n'
|
||||
|
||||
print(s, file=host_bindings)
|
||||
|
||||
# link function
|
||||
s = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n{\n\t'
|
||||
s += 'M3Result res;\n'
|
||||
|
||||
for decl in data:
|
||||
name = decl['name']
|
||||
cname = decl.get('cname', name)
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser(prog='bindgen.py')
|
||||
parser.add_argument('api')
|
||||
parser.add_argument('spec')
|
||||
parser.add_argument('-g', '--guest-stubs')
|
||||
parser.add_argument('--guest-include')
|
||||
parser.add_argument('--wasm3-bindings')
|
||||
|
||||
if needs_arg_ptr_stub(decl):
|
||||
name = name + '_argptr_stub'
|
||||
args = parser.parse_args()
|
||||
|
||||
m3Sig = ''
|
||||
if decl['ret']['tag'] == 'S':
|
||||
m3Sig += 'v'
|
||||
else:
|
||||
m3Sig += decl['ret']['tag']
|
||||
apiName = args.api
|
||||
spec = args.spec
|
||||
guest_stubs_path = args.guest_stubs
|
||||
if guest_stubs_path == None:
|
||||
guest_stubs_path = 'bindgen_' + apiName + '_guest_stubs.c'
|
||||
|
||||
m3Sig += '('
|
||||
if decl['ret']['tag'] == 'S':
|
||||
m3Sig += 'i'
|
||||
for arg in decl['args']:
|
||||
tag = arg['type']['tag']
|
||||
if tag == 'p' or tag == 'S':
|
||||
tag = 'i'
|
||||
m3Sig += tag
|
||||
m3Sig += ')'
|
||||
wasm3_bindings_path = args.wasm3_bindings
|
||||
if wasm3_bindings_path == None:
|
||||
wasm3_bindings_path = 'bindgen_' + apiName + '_wasm3_bindings.c'
|
||||
|
||||
|
||||
s += '\tres = m3_LinkRawFunction(module, "*", "' + name + '", "' + m3Sig + '", ' + cname + '_stub);\n'
|
||||
s += '\tif(res != m3Err_none && res != m3Err_functionLookupFailed) { log_error("error: %s\\n", res); return(-1); }\n\n'
|
||||
|
||||
|
||||
s += '\treturn(0);\n}\n'
|
||||
|
||||
print(s, file=host_bindings)
|
||||
bindgen2(apiName, spec,
|
||||
guest_stubs_path=guest_stubs_path,
|
||||
guest_include=args.guest_include,
|
||||
wasm3_bindings_path=wasm3_bindings_path,
|
||||
)
|
||||
|
|
|
@ -9,6 +9,8 @@ import subprocess
|
|||
from zipfile import ZipFile
|
||||
|
||||
import checksum
|
||||
from bindgen import bindgen
|
||||
from bindgen2 import bindgen2
|
||||
from log import *
|
||||
from utils import pushd, removeall
|
||||
|
||||
|
@ -28,6 +30,7 @@ def build_runtime(args):
|
|||
|
||||
build_milepost("lib", args.release)
|
||||
build_wasm3(args.release)
|
||||
build_orca(args.release)
|
||||
|
||||
|
||||
def build_milepost(target, release):
|
||||
|
@ -213,6 +216,75 @@ def build_wasm3_lib_win(release):
|
|||
], check=True)
|
||||
|
||||
|
||||
def build_orca(release):
|
||||
print("Building Orca...")
|
||||
|
||||
os.makedirs("bin", exist_ok=True)
|
||||
|
||||
if platform.system() == "Windows":
|
||||
build_orca_win(release)
|
||||
elif platform.system() == "Darwin":
|
||||
raise "can't yet build Orca on Mac"
|
||||
else:
|
||||
log_error(f"can't build Orca for unknown platform '{platform.system()}'")
|
||||
exit(1)
|
||||
|
||||
|
||||
def build_orca_win(release):
|
||||
pthread_dir = "..\\vcpkg\\packages\\pthreads_x64-windows"
|
||||
|
||||
# copy libraries
|
||||
shutil.copy("milepost\\bin\\milepost.dll", "bin")
|
||||
shutil.copy("milepost\\bin\\milepost.dll.lib", "bin")
|
||||
shutil.copy(os.path.join(pthread_dir, "bin\\pthreadVC3.dll"), "bin")
|
||||
|
||||
# generate wasm3 api bindings
|
||||
bindgen("core", "src")
|
||||
bindgen("gles", "src")
|
||||
bindgen2("canvas", "src\\canvas_api.json",
|
||||
guest_stubs="sdk\\orca_surface.c",
|
||||
guest_include="graphics.h",
|
||||
wasm3_bindings="src\\canvas_api_bind_gen.c",
|
||||
)
|
||||
bindgen2("clock", "src\\clock_api.json",
|
||||
guest_stubs="sdk\\orca_clock.c",
|
||||
guest_include="platform_clock.h",
|
||||
wasm3_bindings="src\\clock_api_bind_gen.c",
|
||||
)
|
||||
bindgen2("io", "src\\io_api.json",
|
||||
guest_stubs="sdk\\io_stubs.c",
|
||||
wasm3_bindings="src\\io_api_bind_gen.c",
|
||||
)
|
||||
|
||||
# compile orca
|
||||
pthread_include = os.path.join(pthread_dir, "include")
|
||||
includes = [
|
||||
"/I", "src",
|
||||
"/I", "sdk",
|
||||
"/I", "ext\wasm3\source",
|
||||
"/I", "milepost\src",
|
||||
"/I", "milepost\ext",
|
||||
"/I", pthread_include,
|
||||
]
|
||||
pthread_lib = os.path.join(pthread_dir, "lib")
|
||||
libs = [
|
||||
"/LIBPATH:bin",
|
||||
f"/LIBPATH:{pthread_lib}",
|
||||
"milepost.dll.lib",
|
||||
"wasm3.lib",
|
||||
"pthreadVC3.lib",
|
||||
]
|
||||
|
||||
subprocess.run([
|
||||
"cl",
|
||||
"/Zi", "/Zc:preprocessor", "/std:c11",
|
||||
*includes,
|
||||
"src\\main.c",
|
||||
"/link", *libs,
|
||||
"/out:bin\\orca.exe",
|
||||
], check=True)
|
||||
|
||||
|
||||
def ensure_programs():
|
||||
if platform.system() == "Windows":
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue