from waflib.ConfigSet import ConfigSet from waflib import Context, Errors, Task, TaskGen class js_tooling(Task.Task): run_str = '${CC} ${CFLAGS} ${DEFINES_ST:DEFINES} ${CPPPATH_ST:INCPATHS} ${SRC} -o ${TGT[0].abspath()}' @TaskGen.feature('js_tooling') @TaskGen.before_method('process_source', 'process_rule') def process_js_tooling(self): task = self.create_task('js_tooling', self.jerry_sources, self.js_tooling_target) task.dep_nodes = self.js_deps JERRY_RUNTIME_HEAP_SIZE_KB = 32 # KB JERRY_COMPILER_HEAP_SIZE_KB = 512 # KB JERRY_CORE_DIRS = ['jerry-core', 'jerry-core/jcontext', 'jerry-core/jmem', 'jerry-core/jrt', 'jerry-core/lit', 'jerry-core/vm', 'jerry-core/ecma/builtin-objects', 'jerry-core/ecma/base', 'jerry-core/ecma/operations', 'jerry-core/parser/js', 'jerry-core/parser/regexp', ] def _get_jerry_include_dirs(bld): include_dirs = JERRY_CORE_DIRS if bld.variant == 'test': include_dirs.append('third-party/valgrind') return include_dirs def jerry_build_js_compiler(bld): # Set the output node for JS tooling in the primary build ConfigSet bld.env.JS_TOOLING_SCRIPT = bld.path.get_bld().make_node('js_tooling/generate_snapshot.js') env = bld.all_envs['emscripten'] # A few values to experiment with, while 'speed' is nice for experimentation, # and None seems to be ok, we should probably stick to 'size' at the cost of # a longer build time once this whole task got cleaned up optimize = 'size' # optimize = 'size' # optimize = 'speed' if optimize == 'size': env.append_value('CFLAGS', ['-Oz']) env.append_value('CFLAGS', ['--llvm-lto', '3']) env.append_value('CFLAGS', ['--closure', '1']) elif optimize == 'speed': env.append_value('CFLAGS', ['-O3']) else: env.append_value('CFLAGS', ['-O0']) env.append_value('CFLAGS', ['-g3']) fw_path = bld.path.parent.parent env['CPPPATH_ST'] = '-I%s' include_dirs = _get_jerry_include_dirs(bld) env.append_value('INCPATHS', [bld.path.find_node(d).abspath() for d in include_dirs]) env.append_value('INCPATHS', fw_path.abspath()) env['DEFINES_ST'] = '-D%s' env.append_value('DEFINES', [ 'JERRY_ENABLE_LOG', 'CONFIG_MEM_HEAP_AREA_SIZE={}'.format(JERRY_COMPILER_HEAP_SIZE_KB * 1024), ]) bytecode_version = bld.capability('JAVASCRIPT_BYTECODE_VERSION') env.append_value('DEFINES', 'CAPABILITY_JAVASCRIPT_BYTECODE_VERSION={}'.format(bytecode_version)) env.append_value('DEFINES', 'JERRY_RETURN_ADDRESS=0') # provide proper error handling w fake # Emscripten specific arguments post_file = bld.path.make_node('js_tooling/_js_tooling.js').abspath() env.append_value('CFLAGS', ['--post-js', post_file]) transform_js_file = bld.path.make_node('js_tooling/transform_js.py').abspath() env.append_value('CFLAGS', ['--js-transform', transform_js_file]) # tell Emscripten to create a single file env.append_value('CFLAGS', ['--memory-init-file', '0']) # Uncomment this line to get verbose output for emscripten # env.append_value('CFLAGS', ['-v']) # keep these functions so that they are not optimized out exported_functions = ("_jerry_init", "_jerry_cleanup", "_jerry_parse_and_save_snapshot_from_zt_utf8_string", "_legacy_defective_checksum_memory", "_rocky_fill_header", "_jerry_port_set_errormsg_handler") env.append_value('CFLAGS', ['-s', 'EXPORTED_FUNCTIONS=[{}]'.format( ', '.join(('"' + f + '"' for f in exported_functions)))]) # so we can call jerry_port_set_errormsg_handler() with a JS function pointer env.append_value('CFLAGS', ['-s', 'RESERVED_FUNCTION_POINTERS=1']) env.append_value('CFLAGS', ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0']) sources = bld.path.ant_glob('jerry-core/**/*.c') sources += bld.path.ant_glob('js_tooling/*.c') sources += fw_path.ant_glob('util/legacy_checksum.c') js_deps = [bld.path.find_node(x) for x in ('js_tooling/_js_tooling.js', 'js_tooling/transform_js.py')] output_node = bld.path.get_bld().make_node('js_tooling/js_tooling.js') output_node.parent.mkdir() bld(features=['js_tooling', 'use'], jerry_sources=sources, js_tooling_target=output_node, js_deps=js_deps, use=['jerry_common_config'], env=env) bld.path.find_node('js_tooling').get_bld().mkdir() for resource in ('index.js', 'generate_snapshot.js', 'package.json', 'test.html'): src_node = bld.path.find_node('js_tooling/{}'.format(resource)) bld(rule='cp ${SRC} ${TGT}', source=src_node, target=src_node.get_bld(), env=env) bld(rule='${NPM} install .', source=[output_node, bld.path.get_bld().make_node('js_tooling/package.json')], target=bld.path.get_bld().make_node('js_tooling/node_modules/'), cwd=bld.path.get_bld().find_node('js_tooling/').abspath(), env=env) def configure(conf): conf.load('c_inject_include_files') # Create a new environment for emscipten and configure it with the location of our emcc binary prev_env = conf.variant conf.setenv('emscripten') missing_emcscripten = """ 'emcc' cannot be found on the system. Please install Emscripten using the instructions on the wiki: https://pebbletechnology.atlassian.net/wiki/display/DEV/Emscripten """ conf.find_program('emcc', errmsg=missing_emcscripten, var='CC') conf.find_program('em-config') conf.find_program('npm', var='NPM') conf.setenv(prev_env) def build(bld): def run_cmd(cmd): try: return bld.cmd_and_log(cmd, quiet=Context.BOTH).strip() except Errors.WafError as e: print e return "unknown" # Build jerry_common_config. # These are shared defines for jerry-core, jerry-libm, js_tooling and # jerry-port (part of applib). ############################################# wrap_quotes = lambda s: '"{}"'.format(s) jerry_common_defines_dict = { 'JERRY_BRANCH_NAME': wrap_quotes(run_cmd('git symbolic-ref -q HEAD')), 'JERRY_COMMIT_HASH': wrap_quotes(run_cmd('git rev-parse HEAD')), 'JERRY_BUILD_DATE': wrap_quotes(run_cmd('date +%d/%m/%Y')), 'CONFIG_ECMA_NUMBER_TYPE': 'CONFIG_ECMA_NUMBER_FLOAT64', 'CONFIG_DISABLE_PRINT_BUILTIN': '', 'JERRY_DISABLE_HEAVY_DEBUG': '', 'JERRY_ENABLE_SNAPSHOT_SAVE': '', 'JERRY_ENABLE_ERROR_MESSAGES': '1', } jerry_common_defines = [ '{}={}'.format(k, v) for k, v in jerry_common_defines_dict.iteritems()] bld(export_defines=jerry_common_defines, name='jerry_common_config') # Build jerry_runtime_config. # These are not used by js_tooling ############################################# jerry_common_runtime_defines_dict = { 'CONFIG_MEM_HEAP_AREA_SIZE': JERRY_RUNTIME_HEAP_SIZE_KB * 1024, 'JMEM_STATS': '1', } jerry_common_runtime_defines = [ '{}={}'.format(k, v) for k, v in jerry_common_runtime_defines_dict.iteritems()] bld(export_defines=jerry_common_runtime_defines, name='jerry_runtime_config') # Build jerry_port_includes ############################################# bld(export_includes=_get_jerry_include_dirs(bld), name='jerry_port_includes') # If the current build doesn't want javascript, just build a header-only library so the # headers will continue to be available if not bld.capability('HAS_JAVASCRIPT') or bld.variant in ('prf', 'applib', 'test_rocky_emx'): bld(export_includes=['jerry-core'], name='jerry_core') return # Define flags common to both jerry-core and jerry-libm ############################################# # cflags from Makefile.pebble, used in both jerry-libm and jerry-core pebble_cflags = ['-Wno-error=format', '-Wno-error=unused-parameter', '-Wno-error=unused-variable', '-Wno-error=unused-function', '-Wno-pedantic'] if bld.variant == 'test': pebble_cflags += ['-Wno-conversion', '-Wno-unknown-warning-option'] # cflags from COMPILE_FLAGS_JERRY CMakeLists.txt, passed to both compile and link stages # in the original build script for the jerry-core sources compile_flags_jerry = ['-fno-builtin', '-fno-stack-protector', '-g', '-gdwarf-4', '-Wall', '-Werror=all', '-Wextra', '-Werror=extra', '-Wformat-nonliteral', '-Werror=format-nonliteral', '-Winit-self', '-Werror=init-self', '-Wconversion', '-Werror=conversion', '-Wsign-conversion', '-Werror=sign-conversion', '-Wformat-security', '-Werror=format-security', '-Wmissing-declarations', '-Werror=missing-declarations', '-Wno-stack-protector', '-Wno-attributes', '-Wlogical-op', '-Werror=logical-op', '-Wno-strict-aliasing' ] # cflags from C_FLAGS_JERRY CMakeLists.txt, passed to only the compile stage # in the original build script to both jerry-core and fblibm c_flags_jerry = ['-std=c99'] # Build the jerry-core static library ############################################# jerry_core_env = bld.env.derive() all_jerry_flags = compile_flags_jerry + c_flags_jerry + pebble_cflags if bld.variant == 'test': all_jerry_flags.append('-DJERRY_VALGRIND') jerry_core_env.append_value('CFLAGS', all_jerry_flags) jerry_core_env.append_value('DEFINES', [ 'CONFIG_ECMA_LCACHE_DISABLE', # PBL-40394: Hash table didn't fit. 'JERRY_ENABLE_SNAPSHOT_EXEC', 'JERRY_NDEBUG' ]) jerry_core_include_dirs = _get_jerry_include_dirs(bld) jerry_core_env.append_value('INCLUDES', [bld.path.find_node(d).abspath() for d in jerry_core_include_dirs]) jerry_core_source_excl = [ 'jcontext/jcontext.c', # implementation provided by our own jerry_port.c ] jerry_core_sources = sum( [bld.path.ant_glob(d + '/*.c', excl=' '.join(jerry_core_source_excl)) for d in JERRY_CORE_DIRS], []) pbl_jcontext_inc_h_node = bld.srcnode.find_node( 'src/fw/applib/rockyjs/pbl_jcontext.inc.h') pbl_jcontext_inc_h_rel_path = pbl_jcontext_inc_h_node.path_from(bld.path) bld.stlib(source=jerry_core_sources, target='jerry_core', export_includes=['jerry-core'], use=['jerry_common_config', 'jerry_runtime_config'], inject_include_files=[pbl_jcontext_inc_h_rel_path], env=jerry_core_env) # Build the jerry-libm static library ############################################# jerry_libm_env = bld.env.derive() compile_flags_libm = ['-Wno-error=parentheses', '-Wno-error=sign-compare', '-Wno-error=sign-conversion', '-Wno-error=strict-aliasing', '-Wno-error=unknown-pragmas', '-Wno-error=missing-declarations', '-Wno-error=maybe-uninitialized', '-Wno-error=unused-but-set-variable', '-Wno-error=unused-variable', '-Wno-error=conversion', '-Wno-sign-conversion', '-Wno-sign-compare', '-Wno-parentheses', '-Wno-maybe-uninitialized', '-Wno-unknown-pragmas', '-Wno-unused-but-set-variable', '-Wno-unused-variable', '-fno-lto'] all_libm_flags = compile_flags_libm + c_flags_jerry + pebble_cflags jerry_libm_env.append_value('CFLAGS', all_libm_flags) jerry_libm_dir = 'jerry-libm' jerry_libm_env.append_value('INCLUDES', [jerry_libm_dir + '/include']) jerry_libm_sources = bld.path.ant_glob(jerry_libm_dir + '/*.c') bld.stlib(source=jerry_libm_sources, target='libm', name='jerry_libm', use=['jerry_common_config', 'jerry_runtime_config'], env=jerry_libm_env) if bld.variant == 'test': return jerry_build_js_compiler(bld) # vim:filetype=python