-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(dev-cli): refactored container and started code to allow mor…
…e language additions #828
- Loading branch information
1 parent
12bd1f3
commit f07cf68
Showing
18 changed files
with
536 additions
and
529 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import sys | ||
import os | ||
import glob | ||
import shutil | ||
from shlex import quote | ||
|
||
sys.path.append('/usr/local/ao-module') | ||
|
||
from ao_module_lib.definition import Definition | ||
from ao_module_lib.helper import is_lua_source_file, is_c_source_file, is_c_header_file, shell_exec, debug_print | ||
|
||
from ao_module_lib.languages.c import inject_c_files | ||
from ao_module_lib.languages.lua import inject_lua_files, LUAROCKS_LOCAL_MODULE_DIR | ||
|
||
|
||
def determine_language(): | ||
lang = [] | ||
# Get all source files | ||
files = glob.glob('/src/**/*', recursive=True) | ||
# Loop through all files and determine the language | ||
for file in files: | ||
if is_lua_source_file(file) and 'lua' not in lang: | ||
lang.append('lua') | ||
elif (is_c_source_file(file) or is_c_header_file(file)) and 'c' not in lang: | ||
lang.append('c') | ||
|
||
# Check if multiple languages are detected | ||
if len(lang) > 1: | ||
raise Exception('Multiple languages detected in the module') | ||
elif len(lang) == 0: | ||
raise Exception('No language detected in the module') | ||
|
||
# Return the language or default to lua | ||
return lang[0] or 'lua' | ||
|
||
def main(): | ||
# Load the definition file | ||
definition = Definition('/opt/definition.yml') | ||
|
||
# Determine the language of the source files | ||
language = determine_language() | ||
|
||
# Read the main.c file into c_program | ||
c_program = '' | ||
with open('/opt/main.c', mode='r') as c: | ||
c_program = c.read() | ||
|
||
# Inject c files into c_program if language is c | ||
c_source_files = [] | ||
if(language == 'c'): | ||
c_program = inject_c_files(definition, c_program, c_source_files) | ||
|
||
# Inject lua files into c_program always to load lua files and replace placeholders | ||
link_libraries = [] | ||
c_program = inject_lua_files(definition, c_program, link_libraries) | ||
|
||
#Generate compile target file | ||
debug_print('Start to generate complie.c') | ||
|
||
with open('/tmp/compile.cpp', mode='w') as build: | ||
build.write(c_program) | ||
|
||
# Compile the module to a WASM file using emcc | ||
debug_print('Start to compile as WASM') | ||
|
||
# Setup the compile command | ||
cmd = ['emcc', '-O3', | ||
'-g2', | ||
'-s', 'ASYNCIFY=1', | ||
'-s', 'MEMORY64=1', | ||
'-s', 'STACK_SIZE=41943040', | ||
'-s', 'ASYNCIFY_STACK_SIZE=41943040', | ||
'-s', 'ALLOW_MEMORY_GROWTH=1', | ||
'-s', 'INITIAL_MEMORY=52428800', | ||
'-s', 'MAXIMUM_MEMORY=524288000', | ||
'-s', 'WASM=1', | ||
'-s', 'MODULARIZE', | ||
# '-s', 'FILESYSTEM=0', | ||
'-s', 'DETERMINISTIC=1', | ||
'-s', 'NODERAWFS=0', | ||
'-s', 'FORCE_FILESYSTEM=1', | ||
'-msimd128', | ||
'--pre-js', '/opt/pre.js' | ||
] | ||
|
||
# Link aolibc library | ||
cmd.extend(['-L/opt/aolibc', '-l:aolibc.a']) | ||
cmd.extend(['-s', 'ASSERTIONS=1']) | ||
cmd.extend(definition.get_extra_args()) | ||
|
||
# Add the lua include path | ||
cmd.extend(['-I', quote('/lua-{}/src'.format(os.environ.get('LUA_VERSION')))]) | ||
|
||
# Add all c source files if there are any | ||
for f in c_source_files: | ||
cmd.append(quote(f)) | ||
|
||
# Add the compile file and link libraries | ||
cmd.extend(['/tmp/compile.cpp', quote('/lua-{}/src/liblua.a'.format(os.environ.get('LUA_VERSION')))]) | ||
cmd.extend([quote(v.filepath) for v in link_libraries]) | ||
cmd.extend([quote(v.filepath) for v in link_libraries]) | ||
|
||
# Export the main function and malloc for the runtime | ||
cmd.extend(['-s', 'EXPORTED_FUNCTIONS=["_malloc", "_main"]']) | ||
|
||
# Export the runtime methods cwrap | ||
cmd.extend(['-lm', '-ldl', '-o', definition.get_output_file(), '-s', 'EXPORTED_RUNTIME_METHODS=["cwrap"]']) | ||
|
||
debug_print('Compile command is {}'.format(' '.join(cmd))) | ||
shell_exec(*cmd) | ||
|
||
# add metering library | ||
# meter_cmd = ['node', '/opt/node/apply-metering.cjs'] | ||
# shell_exec(*meter_cmd) | ||
shell_exec(*['rm', os.path.join(os.getcwd(), 'process.js')]) | ||
|
||
if __name__ == '__main__': | ||
main() | ||
|
||
# cleanup temporary module directory | ||
if os.path.isdir(LUAROCKS_LOCAL_MODULE_DIR): | ||
shutil.rmtree(LUAROCKS_LOCAL_MODULE_DIR) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import glob | ||
from ao_module_lib.definition import Definition | ||
|
||
def inject_c_files(definition: Definition, c_program: str, c_source_files: list): | ||
|
||
c_header_files = [] | ||
c_source_files += glob.glob('/src/**/*.c', recursive=True) | ||
c_source_files += glob.glob('/src/**/*.cpp', recursive=True) | ||
c_header_files += glob.glob('/src/**/*.h', recursive=True) | ||
c_header_files += glob.glob('/src/**/*.hpp', recursive=True) | ||
|
||
for header in c_header_files: | ||
c_program = '#include "{}"\n'.format(header) + c_program | ||
|
||
|
||
c_program = 'const char *process_handle(const char *arg_0, const char *arg_1);\n' + c_program | ||
c_program = c_program.replace('__FUNCTION_DECLARATIONS__', definition.make_c_function_delarations()) | ||
return c_program |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import glob | ||
import os | ||
import re | ||
import subprocess | ||
|
||
from ao_module_lib.definition import Definition | ||
from ao_module_lib.file import LuaFile, ModuleFile, BundleFile | ||
from ao_module_lib.helper import is_lua_source_file, is_binary_library, encode_hex_literals, shell_exec, debug_print | ||
|
||
CC = os.environ.get('CC', 'cc') | ||
NM = os.environ.get('NM', 'nm') | ||
|
||
LUAROCKS_LOCAL_MODULE_DIR = '/src/modules' # os.path.abspath('/src/modules') | ||
LUAROCKS_LOCAL_MODULE_PREFIX_RE = re.compile(re.escape(LUAROCKS_LOCAL_MODULE_DIR) + '\/share\/lua\/\d+.\d+/') | ||
|
||
def __get_uname(): | ||
uname = '' | ||
try: | ||
uname, _ = shell_exec('uname', '-s') | ||
except (subprocess.CalledProcessError): | ||
uname = 'Unknown' | ||
|
||
return uname | ||
|
||
|
||
def inject_lua_files(definition: Definition, c_program: str, link_libraries: list): | ||
|
||
uname = __get_uname() | ||
|
||
lua_files = [] | ||
library_files = [] | ||
dependency_libraries = [] | ||
|
||
# entry_file = definition.get_entry_file() | ||
entry_file = '/opt/loader.lua' | ||
|
||
if not is_lua_source_file(entry_file): | ||
print('main file of {} must be lua script.'.format(entry_file)) | ||
return | ||
|
||
definition.install_dependencies(LUAROCKS_LOCAL_MODULE_DIR) | ||
|
||
local_include_dir = os.path.join(os.path.dirname(entry_file), 'src') | ||
local_include_prefix_re = re.compile(re.escape(local_include_dir + '/')) | ||
|
||
# Detect bundles | ||
bundle_files = glob.glob('/src/**/*.lua', recursive=True) | ||
|
||
# Optional dependencies | ||
bundle_files += glob.glob(local_include_dir + '/**/*.lua', recursive=True) | ||
bundle_files += glob.glob(local_include_dir + '/**/*.so', recursive=True) | ||
bundle_files += glob.glob(LUAROCKS_LOCAL_MODULE_DIR + | ||
'/lib/lua/**/*.so', recursive=True) | ||
bundle_files += glob.glob(LUAROCKS_LOCAL_MODULE_DIR + | ||
'/share/lua/**/*.lua', recursive=True) | ||
debug_print('Start to factory and distinguish module files') | ||
|
||
for bundle in bundle_files: | ||
if is_lua_source_file(bundle): | ||
basename = re.sub(LUAROCKS_LOCAL_MODULE_PREFIX_RE, '', bundle) | ||
basename = re.sub(local_include_prefix_re, '', basename) | ||
lua_files.append(LuaFile(bundle, basename)) | ||
continue | ||
|
||
if is_binary_library(bundle): | ||
try: | ||
nm, _ = shell_exec(NM, bundle) | ||
is_module = False | ||
if re.search(r'T _?luaL_newstate', nm): | ||
if re.search(r'U _?dlopen', nm): | ||
if uname in ['Linux', 'SunOS', 'Darwin']: | ||
libdl_option = '-ldl' | ||
|
||
else: | ||
for luaopen in re.finditer(r'[^dD] _?luaopen_([0-9a-zA-Z!"#\$%&\'\(\)\*\+,\-\.\/:;\<=\>\?@\[\]^_`\{\|\}~]+)', nm): | ||
debug_print('luaopen_{} function found. add to library in {}'.format( | ||
luaopen.group(1), bundle)) | ||
library_files.append( | ||
ModuleFile(bundle, luaopen.group(1))) | ||
is_module = True | ||
|
||
if is_module: | ||
link_libraries.append(BundleFile(bundle)) | ||
else: | ||
dependency_libraries.append(BundleFile(bundle)) | ||
|
||
except (subprocess.CalledProcessError): | ||
print(NM + ' command failed') | ||
return | ||
|
||
debug_print('===== Bundle Lua files ======') | ||
debug_print('\n'.join([v.filepath for v in lua_files])) | ||
debug_print('===== Library files =====') | ||
debug_print('\n'.join([v.filepath for v in library_files])) | ||
debug_print('===== Link libraries =====') | ||
debug_print('\n'.join([v.filepath for v in link_libraries])) | ||
debug_print('===== Dependency libraries =====') | ||
debug_print('\n'.join([v.filepath for v in dependency_libraries])) | ||
|
||
with open('/opt/main.lua', mode='r') as lua: | ||
lua_program = lua.read() | ||
|
||
c_program = c_program.replace( | ||
'__LUA_BASE__', encode_hex_literals(lua_program)) | ||
with open(entry_file, mode='r') as main_file: | ||
p = main_file.read() | ||
c_program = c_program.replace('__LUA_MAIN__', encode_hex_literals(p)) | ||
|
||
inject_lua_files = [] | ||
for i, f in enumerate(lua_files): | ||
with open(f.filepath, mode='r') as l: | ||
lines = l.readlines() | ||
# check first line has control command | ||
if lines[0].find("\xef\xbb\xbf") != -1: | ||
# UTF-8 byte order mark | ||
lines[0] = lines[0][4:] | ||
elif lines[0][0] == '#': | ||
# shebang | ||
lines = lines[1:] | ||
|
||
inject_lua_files.extend([ | ||
' static const unsigned char lua_require_{}[] = {{{}}};'.format( | ||
i, encode_hex_literals('\n'.join(lines))), | ||
' lua_pushlstring(L, (const char*)lua_require_{}, sizeof(lua_require_{}));'.format(i, i), | ||
' lua_setfield(L, -2, "{}");\n'.format(f.module_name) | ||
]) | ||
|
||
for f in library_files: | ||
inject_lua_files.extend([ | ||
' int luaopen_{}(lua_State* L);'.format(f.module_name), | ||
' lua_pushcfunction(L, luaopen_{});'.format(f.module_name), | ||
' lua_setfield(L, -2, "{}");'.format(f.basename) | ||
]) | ||
c_program = c_program.replace( | ||
'__FUNCTION_DECLARATIONS__', definition.make_function_delarations()) | ||
c_program = c_program.replace( | ||
'__INJECT_LUA_FILES__', '\n'.join(inject_lua_files)) | ||
|
||
return c_program |
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion
1
dev-cli/container/src/main.c → dev-cli/container/src/core/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <signal.h> | ||
|
File renamed without changes.
File renamed without changes.
Oops, something went wrong.