Example #1
0
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))
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)
Example #7
0
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)