def generate_minimal_runtime_html(target, options, js_target, target_basename, asm_target, wasm_binary_target, memfile, optimizer): logger.debug('generating HTML for minimal runtime') shell = open(options.shell_path, 'r').read() shell = shell.replace('{{{ DOWNLOAD_JS_AND_WASM_FILES }}}', generate_minimal_runtime_load_statement(target_basename)) temp_files = shared.configuration.get_temp_files() with temp_files.get_file(suffix='.js') as shell_temp: open(shell_temp, 'w').write(shell) shell = shared.read_and_preprocess(shell_temp) if re.search(r'{{{\s*SCRIPT\s*}}}', shell): shared.exit_with_error('--shell-file "' + options.shell_path + '": MINIMAL_RUNTIME uses a different kind of HTML page shell file than the traditional runtime! Please see $EMSCRIPTEN/src/shell_minimal_runtime.html for a template to use as a basis.') shell = shell.replace('{{{ TARGET_BASENAME }}}', target_basename) shell = shell.replace('{{{ EXPORT_NAME }}}', shared.Settings.EXPORT_NAME) shell = line_endings.convert_line_endings(shell, '\n', options.output_eol) with open(target, 'wb') as f: f.write(shared.asbytes(shell))
def generate_minimal_runtime_html(target, options, js_target, target_basename, asm_target, wasm_binary_target, memfile, optimizer): logger.debug('generating HTML for minimal runtime') shell = open(options.shell_path, 'r').read() if shared.Settings.SINGLE_FILE: # No extra files needed to download in a SINGLE_FILE build. shell = shell.replace('{{{ DOWNLOAD_JS_AND_WASM_FILES }}}', '') else: shell = shell.replace( '{{{ DOWNLOAD_JS_AND_WASM_FILES }}}', generate_minimal_runtime_load_statement(target_basename)) temp_files = shared.configuration.get_temp_files() with temp_files.get_file(suffix='.js') as shell_temp: open(shell_temp, 'w').write(shell) shell = shared.read_and_preprocess(shell_temp) if re.search(r'{{{\s*SCRIPT\s*}}}', shell): shared.exit_with_error( '--shell-file "' + options.shell_path + '": MINIMAL_RUNTIME uses a different kind of HTML page shell file than the traditional runtime! Please see $EMSCRIPTEN/src/shell_minimal_runtime.html for a template to use as a basis.' ) shell = shell.replace('{{{ TARGET_BASENAME }}}', target_basename) shell = shell.replace('{{{ EXPORT_NAME }}}', shared.Settings.EXPORT_NAME) shell = shell.replace('{{{ PTHREAD_WORKER_FILE }}}', shared.Settings.PTHREAD_WORKER_FILE) # In SINGLE_FILE build, embed the main .js file into the .html output if shared.Settings.SINGLE_FILE: js_contents = open(js_target).read() shared.try_delete(js_target) else: js_contents = '' shell = shell.replace('{{{ JS_CONTENTS_IN_SINGLE_FILE_BUILD }}}', js_contents) shell = line_endings.convert_line_endings(shell, '\n', options.output_eol) with open(target, 'wb') as f: f.write(shared.asbytes(shell))
def inspect_headers(headers, cpp_opts): code = ['#include <stdio.h>', '#include <stddef.h>'] for header in headers: code.append('#include "' + header['name'] + '"') code.append('int main() {') c_descent('structs', code) for header in headers: for name, struct in header['structs'].items(): gen_inspect_code([name], struct, code) c_ascent(code) c_descent('defines', code) for header in headers: for name, type_ in header['defines'].items(): # Add the necessary python type, if missing. if '%' not in type_: if type_[-1] in ('d', 'i', 'u'): # integer type_ = 'i%' + type_ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): # float type_ = 'f%' + type_ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): # hexadecimal or string type_ = 's%' + type_ c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') show('Generating C code... ' + src_file[1]) os.write(src_file[0], shared.asbytes('\n'.join(code))) js_file = tempfile.mkstemp('.js') # Close all unneeded FDs. os.close(src_file[0]) os.close(js_file[0]) # Remove dangerous env modifications env = os.environ.copy() env['EMCC_FORCE_STDLIBS'] = 'libcompiler_rt' env['EMCC_ONLY_FORCED_STDLIBS'] = '1' info = [] # Compile the program. show('Compiling generated code...') # -Oz optimizes enough to avoid warnings on code size/num locals cmd = [shared.EMCC] + cpp_opts + ['-o', js_file[1], src_file[1], '-O0', '-Werror', '-Wno-format', '-I', shared.path_from_root(), '-s', 'BOOTSTRAPPING_STRUCT_INFO=1', '-s', 'WARN_ON_UNDEFINED_SYMBOLS=0', '-s', 'STRICT=1', # Use SINGLE_FILE=1 so there is only a single # file to cleanup. '-s', 'SINGLE_FILE=1'] # Default behavior for emcc is to warn for binaryen version check mismatches # so we should try to match that behavior. cmd += ['-Wno-error=version-check'] # TODO(sbc): Remove this one we remove the test_em_config_env_var test cmd += ['-Wno-deprecated'] if shared.Settings.LTO: cmd += ['-flto=' + shared.Settings.LTO] show(shared.shlex_join(cmd)) try: subprocess.check_call(cmd, env=env) except subprocess.CalledProcessError as e: sys.stderr.write('FAIL: Compilation failed!: %s\n' % e.cmd) sys.exit(1) # Run the compiled program. show('Calling generated program... ' + js_file[1]) info = shared.run_js_tool(js_file[1], stdout=shared.PIPE).splitlines() # Remove all temporary files. os.unlink(src_file[1]) if os.path.exists(js_file[1]): os.unlink(js_file[1]) # Parse the output of the program into a dict. return parse_c_output(info)
def inspect_headers(headers, cflags): code = ['#include <stdio.h>', '#include <stddef.h>'] for header in headers: code.append('#include "' + header['name'] + '"') code.append('int main() {') c_descent('structs', code) for header in headers: for name, struct in header['structs'].items(): gen_inspect_code([name], struct, code) c_ascent(code) c_descent('defines', code) for header in headers: for name, type_ in header['defines'].items(): # Add the necessary python type, if missing. if '%' not in type_: if type_[-1] in ('d', 'i', 'u'): # integer type_ = 'i%' + type_ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): # float type_ = 'f%' + type_ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): # hexadecimal or string type_ = 's%' + type_ c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') show('Generating C code... ' + src_file[1]) os.write(src_file[0], shared.asbytes('\n'.join(code))) js_file = tempfile.mkstemp('.js') # Check sanity early on before populating the cache with libcompiler_rt # If we don't do this the parallel build of compiler_rt will run while holding the cache # lock and with EM_EXCLUSIVE_CACHE_ACCESS set causing N processes to race to run sanity checks. # While this is not in itself serious problem it is wasteful and noise on stdout. # For the same reason we run this early in embuilder.py and emcc.py. # TODO(sbc): If we can remove EM_EXCLUSIVE_CACHE_ACCESS then this would not longer be needed. shared.check_sanity() compiler_rt = system_libs.Library.get_usable_variations( )['libcompiler_rt'].get_path() # Close all unneeded FDs. os.close(src_file[0]) os.close(js_file[0]) info = [] # Compile the program. show('Compiling generated code...') # -Oz optimizes enough to avoid warnings on code size/num locals cmd = [shared.EMCC] + cflags + [ '-o', js_file[1], src_file[1], '-O0', '-Werror', '-Wno-format', '-nostdlib', compiler_rt, '-s', 'BOOTSTRAPPING_STRUCT_INFO=1', '-s', 'STRICT', # Use SINGLE_FILE=1 so there is only a single # file to cleanup. '-s', 'SINGLE_FILE' ] # Default behavior for emcc is to warn for binaryen version check mismatches # so we should try to match that behavior. cmd += ['-Wno-error=version-check'] # TODO(sbc): Remove this one we remove the test_em_config_env_var test cmd += ['-Wno-deprecated'] if shared.Settings.LTO: cmd += ['-flto=' + shared.Settings.LTO] show(shared.shlex_join(cmd)) try: subprocess.check_call(cmd) except subprocess.CalledProcessError as e: sys.stderr.write('FAIL: Compilation failed!: %s\n' % e.cmd) sys.exit(1) # Run the compiled program. show('Calling generated program... ' + js_file[1]) info = shared.run_js_tool(js_file[1], stdout=shared.PIPE).splitlines() # Remove all temporary files. os.unlink(src_file[1]) if os.path.exists(js_file[1]): os.unlink(js_file[1]) # Parse the output of the program into a dict. return parse_c_output(info)
def inspect_code(headers, cpp_opts, structs, defines): show('Generating C code...') code = ['#include <stdio.h>', '#include <stddef.h>'] # Include all the needed headers. for path in headers: code.append('#include "' + path + '"') code.append('int main() {') c_descent('structs', code) for name, struct in structs.items(): gen_inspect_code([name], struct, code) c_ascent(code) c_descent('defines', code) for name, type_ in defines.items(): # Add the necessary python type, if missing. if '%' not in type_: if type_[-1] in ('d', 'i', 'u'): # integer type_ = 'i%' + type_ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): # float type_ = 'f%' + type_ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): # hexadecimal or string type_ = 's%' + type_ c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') js_file = tempfile.mkstemp('.js') os.write(src_file[0], shared.asbytes('\n'.join(code))) # Close all unneeded FDs. os.close(src_file[0]) os.close(js_file[0]) # Remove dangerous env modifications safe_env = os.environ.copy() for opt in ['EMCC_FORCE_STDLIBS', 'EMCC_ONLY_FORCED_STDLIBS']: if opt in safe_env: del safe_env[opt] # Use binaryen, if necessary binaryen = os.environ.get('EMCC_WASM_BACKEND_BINARYEN') if binaryen: cpp_opts += ['-s', 'BINARYEN=1'] info = [] # Compile the program. show('Compiling generated code...') # -Oz optimizes enough to avoid warnings on code size/num locals cmd = [shared.PYTHON, shared.EMCC] + cpp_opts + [ '-o', js_file[1], src_file[1], '-s', 'BOOTSTRAPPING_STRUCT_INFO=1', '-s', 'WARN_ON_UNDEFINED_SYMBOLS=0', '-Oz', '--js-opts', '0', '--memory-init-file', '0', '-s', 'SINGLE_FILE=1', '-s', 'WASM=0', '-Wno-format' ] if shared.Settings.WASM_OBJECT_FILES: cmd += ['-s', 'WASM_OBJECT_FILES=1'] try: try: subprocess.check_call(cmd, env=safe_env) except subprocess.CalledProcessError: sys.stderr.write('FAIL: Compilation failed!\n') sys.exit(1) # Run the compiled program. show('Calling generated program...') try: info = shared.run_js(js_file[1]).splitlines() except subprocess.CalledProcessError: sys.stderr.write('FAIL: Running the generated program failed!\n') sys.exit(1) finally: # Remove all temporary files. os.unlink(src_file[1]) if os.path.exists(js_file[1]): os.unlink(js_file[1]) # Parse the output of the program into a dict. return parse_c_output(info)
def inspect_code(headers, cpp_opts, structs, defines): show('Generating C code...') code = ['#include <stdio.h>', '#include <stddef.h>'] # Include all the needed headers. for path in headers: code.append('#include "' + path + '"') code.append('int main() {') c_descent('structs', code) for name, struct in structs.items(): gen_inspect_code([name], struct, code) c_ascent(code) c_descent('defines', code) for name, type_ in defines.items(): # Add the necessary python type, if missing. if '%' not in type_: if type_[-1] in ('d', 'i', 'u'): # integer type_ = 'i%' + type_ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): # float type_ = 'f%' + type_ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): # hexadecimal or string type_ = 's%' + type_ c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') js_file = tempfile.mkstemp('.js') os.write(src_file[0], shared.asbytes('\n'.join(code))) # Close all unneeded FDs. os.close(src_file[0]) os.close(js_file[0]) # Remove dangerous env modifications safe_env = os.environ.copy() for opt in ['EMCC_FORCE_STDLIBS', 'EMCC_ONLY_FORCED_STDLIBS']: if opt in safe_env: del safe_env[opt] # Use binaryen, if necessary binaryen = os.environ.get('EMCC_WASM_BACKEND_BINARYEN') if binaryen: cpp_opts += ['-s', 'BINARYEN=1'] info = [] try: try: # Compile the program. show('Compiling generated code...') subprocess.check_call([shared.PYTHON, shared.EMCC] + cpp_opts + ['-o', js_file[1], src_file[1], '-s', 'BOOTSTRAPPING_STRUCT_INFO=1', '-s', 'WARN_ON_UNDEFINED_SYMBOLS=0', '-Oz', '--js-opts', '0', '--memory-init-file', '0'], env=safe_env) # -Oz optimizes enough to avoid warnings on code size/num locals except: sys.stderr.write('FAIL: Compilation failed!\n') sys.exit(1) # Run the compiled program. show('Calling generated program...') try: info = shared.run_js(js_file[1]).splitlines() except subprocess.CalledProcessError: sys.stderr.write('FAIL: Running the generated program failed!\n') sys.exit(1) finally: # Remove all temporary files. os.unlink(src_file[1]) if os.path.exists(js_file[1]): os.unlink(js_file[1]) # Parse the output of the program into a dict. return parse_c_output(info)
def inspect_code(headers, cpp_opts, structs, defines): code = ['#include <stdio.h>', '#include <stddef.h>'] # Include all the needed headers. for path in headers: code.append('#include "' + path + '"') code.append('int main() {') c_descent('structs', code) for name, struct in structs.items(): gen_inspect_code([name], struct, code) c_ascent(code) c_descent('defines', code) for name, type_ in defines.items(): # Add the necessary python type, if missing. if '%' not in type_: if type_[-1] in ('d', 'i', 'u'): # integer type_ = 'i%' + type_ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'): # float type_ = 'f%' + type_ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'): # hexadecimal or string type_ = 's%' + type_ c_set(name, type_, name, code) code.append('return 0;') code.append('}') # Write the source code to a temporary file. src_file = tempfile.mkstemp('.c') show('Generating C code... ' + src_file[1]) os.write(src_file[0], shared.asbytes('\n'.join(code))) js_file = tempfile.mkstemp('.js') # Close all unneeded FDs. os.close(src_file[0]) os.close(js_file[0]) # Remove dangerous env modifications env = os.environ.copy() env['EMCC_FORCE_STDLIBS'] = 'libcompiler_rt' env['EMCC_ONLY_FORCED_STDLIBS'] = '1' info = [] # Compile the program. show('Compiling generated code...') # -Oz optimizes enough to avoid warnings on code size/num locals cmd = [shared.EMCC] + cpp_opts + [ '-o', js_file[1], src_file[1], '-O0', '--js-opts', '0', '--memory-init-file', '0', '-Werror', '-Wno-format', '-s', 'BOOTSTRAPPING_STRUCT_INFO=1', '-s', 'WARN_ON_UNDEFINED_SYMBOLS=0', '-s', 'STRICT=1', '-s', 'SINGLE_FILE=1' ] if not shared.Settings.WASM_BACKEND: # Avoid the binaryen dependency if we are only using fastcomp cmd += ['-s', 'WASM=0', '-Wno-fastcomp'] if shared.Settings.LTO: cmd += ['-flto=' + shared.Settings.LTO] show(cmd) try: subprocess.check_call(cmd, env=env) except subprocess.CalledProcessError as e: sys.stderr.write('FAIL: Compilation failed!: %s\n' % e.cmd) sys.exit(1) # Run the compiled program. show('Calling generated program... ' + js_file[1]) info = shared.run_js_tool(js_file[1], stdout=shared.PIPE).splitlines() # Remove all temporary files. os.unlink(src_file[1]) if os.path.exists(js_file[1]): os.unlink(js_file[1]) # Parse the output of the program into a dict. return parse_c_output(info)