コード例 #1
0
ファイル: emconfigure.py プロジェクト: mkonicek/wasm
def run():
    if len(sys.argv) < 2 or sys.argv[1] in ('--version', '--help'):
        print('''\
emconfigure is a helper for configure, setting various environment
variables so that emcc etc. are used. Typical usage:

  emconfigure ./configure [FLAGS]

(but you can run any command instead of configure)''',
              file=sys.stderr)
        return 1

    args = sys.argv[1:]

    if 'cmake' in args:
        print(
            'error: use `emcmake` rather then `emconfigure` for cmake projects',
            file=sys.stderr)
        return 1

    env = building.get_building_env()
    # When we configure via a ./configure script, don't do config-time
    # compilation with emcc, but instead do builds natively with Clang. This
    # is a heuristic emulation that may or may not work.
    env['EMMAKEN_JUST_CONFIGURE'] = '1'
    print('configure: ' + shared.shlex_join(args), file=sys.stderr)
    try:
        shared.check_call(args, env=env)
        return 0
    except CalledProcessError as e:
        return e.returncode
コード例 #2
0
def run():
    if len(sys.argv) < 2 or sys.argv[1] in ('--version', '--help'):
        print('''\
emcmake is a helper for cmake, setting various environment
variables so that emcc etc. are used. Typical usage:

  emcmake cmake [FLAGS]
''',
              file=sys.stderr)
        return 1

    args = sys.argv[1:]

    def has_substr(args, substr):
        return any(substr in s for s in args)

    # Append the Emscripten toolchain file if the user didn't specify one.
    if not has_substr(args, '-DCMAKE_TOOLCHAIN_FILE'):
        args.append('-DCMAKE_TOOLCHAIN_FILE=' + utils.path_from_root(
            'cmake', 'Modules', 'Platform', 'Emscripten.cmake'))

    if not has_substr(args, '-DCMAKE_CROSSCOMPILING_EMULATOR'):
        node_js = config.NODE_JS[0]
        args.append(f'-DCMAKE_CROSSCOMPILING_EMULATOR={node_js}')

    # On Windows specify MinGW Makefiles or ninja if we have them and no other
    # toolchain was specified, to keep CMake from pulling in a native Visual
    # Studio, or Unix Makefiles.
    if utils.WINDOWS and '-G' not in args:
        if utils.which('mingw32-make'):
            args += ['-G', 'MinGW Makefiles']
        elif utils.which('ninja'):
            args += ['-G', 'Ninja']
        else:
            print(
                'emcmake: no compatible cmake generator found; Please install ninja or mingw32-make, or specify a generator explicitly using -G',
                file=sys.stderr)
            return 1

    # CMake has a requirement that it wants sh.exe off PATH if MinGW Makefiles
    # is being used. This happens quite often, so do this automatically on
    # behalf of the user. See
    # http://www.cmake.org/Wiki/CMake_MinGW_Compiler_Issues
    if utils.WINDOWS and 'MinGW Makefiles' in args:
        env = building.remove_sh_exe_from_path(os.environ)
    else:
        env = None

    print('configure: ' + shared.shlex_join(args), file=sys.stderr)
    try:
        shared.check_call(args, env=env)
        return 0
    except CalledProcessError as e:
        return e.returncode
コード例 #3
0
ファイル: emcmake.py プロジェクト: nmrugg/emscripten
def run():
    if len(sys.argv) < 2 or sys.argv[1] in ('--version', '--help'):
        print('''\
emcmake is a helper for cmake, setting various environment
variables so that emcc etc. are used. Typical usage:

  emcmake cmake [FLAGS]
''',
              file=sys.stderr)
        return 1

    args = sys.argv[1:]

    def has_substr(args, substr):
        return any(substr in s for s in args)

    # Append the Emscripten toolchain file if the user didn't specify one.
    if not has_substr(args, '-DCMAKE_TOOLCHAIN_FILE'):
        args.append(
            '-DCMAKE_TOOLCHAIN_FILE=' +
            utils.path_from_root('cmake/Modules/Platform/Emscripten.cmake'))

    if not has_substr(args, '-DCMAKE_CROSSCOMPILING_EMULATOR'):
        node_js = config.NODE_JS[0]
        args.append(f'-DCMAKE_CROSSCOMPILING_EMULATOR={node_js}')

    # On Windows specify MinGW Makefiles or ninja if we have them and no other
    # toolchain was specified, to keep CMake from pulling in a native Visual
    # Studio, or Unix Makefiles.
    if utils.WINDOWS and '-G' not in args:
        if utils.which('mingw32-make'):
            args += ['-G', 'MinGW Makefiles']
        elif utils.which('ninja'):
            args += ['-G', 'Ninja']
        else:
            print(
                'emcmake: no compatible cmake generator found; Please install ninja or mingw32-make, or specify a generator explicitly using -G',
                file=sys.stderr)
            return 1

    print('configure: ' + shared.shlex_join(args), file=sys.stderr)
    try:
        shared.check_call(args)
        return 0
    except CalledProcessError as e:
        return e.returncode
コード例 #4
0
def run():
  if len(sys.argv) < 2 or sys.argv[1] in ('--version', '--help'):
    print('''\
emcmake is a helper for cmake, setting various environment
variables so that emcc etc. are used. Typical usage:

  emcmake cmake [FLAGS]
''', file=sys.stderr)
    return 1

  args = sys.argv[1:]

  def has_substr(args, substr):
    return any(substr in s for s in args)

  # Append the Emscripten toolchain file if the user didn't specify one.
  if not has_substr(args, '-DCMAKE_TOOLCHAIN_FILE'):
    args.append('-DCMAKE_TOOLCHAIN_FILE=' + utils.path_from_root('cmake/Modules/Platform/Emscripten.cmake'))

  if not has_substr(args, '-DCMAKE_CROSSCOMPILING_EMULATOR'):
    node_js = config.NODE_JS[0]
    # In order to allow cmake to run code built with pthreads we need to pass some extra flags to node.
    # Note that we also need --experimental-wasm-bulk-memory which is true by default and hence not added here
    # See https://github.com/emscripten-core/emscripten/issues/15522
    args.append(f'-DCMAKE_CROSSCOMPILING_EMULATOR={node_js};--experimental-wasm-threads')

  # On Windows specify MinGW Makefiles or ninja if we have them and no other
  # toolchain was specified, to keep CMake from pulling in a native Visual
  # Studio, or Unix Makefiles.
  if utils.WINDOWS and not any(arg.startswith('-G') for arg in args):
    if utils.which('mingw32-make'):
      args += ['-G', 'MinGW Makefiles']
    elif utils.which('ninja'):
      args += ['-G', 'Ninja']
    else:
      print('emcmake: no compatible cmake generator found; Please install ninja or mingw32-make, or specify a generator explicitly using -G', file=sys.stderr)
      return 1

  print('configure: ' + shared.shlex_join(args), file=sys.stderr)
  try:
    shared.check_call(args)
    return 0
  except CalledProcessError as e:
    return e.returncode
コード例 #5
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)
コード例 #6
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', text=True)
    show('Generating C code... ' + src_file[1])
    os.write(src_file[0], '\n'.join(code).encode())

    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...')

    if any('libcxxabi' in f for f in cflags):
        compiler = shared.EMXX
    else:
        compiler = shared.EMCC

    # -Oz optimizes enough to avoid warnings on code size/num locals
    cmd = [compiler] + cflags + [
        '-o',
        js_file[1],
        src_file[1],
        '-O0',
        '-Werror',
        '-Wno-format',
        '-nostdlib',
        compiler_rt,
        '-sMEMORY64=' + str(settings.MEMORY64),
        '-sBOOTSTRAPPING_STRUCT_INFO=1',
        '-sLLD_REPORT_UNDEFINED=1',
        '-sSTRICT',
        # Use SINGLE_FILE=1 so there is only a single
        # file to cleanup.
        '-sSINGLE_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 settings.LTO:
        cmd += ['-flto=' + settings.LTO]

    show(shared.shlex_join(cmd))
    try:
        subprocess.check_call(cmd, env=system_libs.clean_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])
    args = []
    if settings.MEMORY64:
        args += ['--experimental-wasm-bigint']
    info = shared.run_js_tool(js_file[1], node_args=args,
                              stdout=shared.PIPE).splitlines()

    if not DEBUG:
        # 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)