123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #!/usr/bin/env python
- #
- # Copyright 2019 the V8 project authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """\
- Helper script for compiling and running the Wasm C/C++ API examples.
- Usage: tools/run-wasm-api-tests.py outdir tempdir [filters...]
- "outdir" is the build output directory containing libwee8, e.g. out/x64.release
- "tempdir" is a temporary dir where this script may put its artifacts. It is
- the caller's responsibility to clean it up afterwards.
- By default, this script builds and runs all examples, both the respective
- C and C++ versions, both with GCC ("gcc" and "g++" binaries found in $PATH)
- and V8's bundled Clang in third_party/llvm-build/. You can use any number
- of "filters" arguments to run only a subset:
- - "c": run C versions of examples
- - "cc": run C++ versions of examples
- - "gcc": compile with GCC
- - "clang": compile with Clang
- - "hello" etc.: run "hello" example
- """
- from __future__ import print_function
- import os
- import shutil
- import subprocess
- import sys
- CFLAGS = "-DDEBUG -Wall -Werror -O0 -ggdb -fsanitize=address"
- CHECKOUT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- WASM_PATH = os.path.join(CHECKOUT_PATH, "third_party", "wasm-api")
- CLANG_PATH = os.path.join(CHECKOUT_PATH, "third_party", "llvm-build",
- "Release+Asserts", "bin")
- EXAMPLES = ["hello", "callback", "trap", "reflect", "global", "table",
- "memory", "finalize", "serialize", "threads", "hostref", "multi",
- "start"]
- CLANG = {
- "name": "Clang",
- "c": os.path.join(CLANG_PATH, "clang"),
- "cc": os.path.join(CLANG_PATH, "clang++"),
- "ldflags": "-fsanitize-memory-track-origins -fsanitize-memory-use-after-dtor",
- }
- GCC = {
- "name": "GCC",
- "c": "gcc",
- "cc": "g++",
- "ldflags": "",
- }
- C = {
- "name": "C",
- "suffix": "c",
- "cflags": "",
- }
- CXX = {
- "name": "C++",
- "suffix": "cc",
- "cflags": "-std=c++11",
- }
- MIN_ARGS = 3 # Script, outdir, tempdir
- def _Call(cmd_list, silent=False):
- cmd = " ".join(cmd_list)
- if not silent: print("# %s" % cmd)
- return subprocess.call(cmd, shell=True)
- class Runner(object):
- def __init__(self, name, outdir, tempdir):
- self.name = name
- self.outdir = outdir
- self.tempdir = tempdir
- self.src_file_basename = os.path.join(WASM_PATH, "example", name)
- self.dst_file_basename = os.path.join(tempdir, name)
- self.lib_file = os.path.join(outdir, "obj", "libwee8.a")
- if not os.path.exists(self.lib_file):
- print("libwee8 library not found, make sure to pass the outdir as "
- "first argument; see --help")
- sys.exit(1)
- src_wasm_file = self.src_file_basename + ".wasm"
- dst_wasm_file = self.dst_file_basename + ".wasm"
- shutil.copyfile(src_wasm_file, dst_wasm_file)
- def _Error(self, step, lang, compiler, code):
- print("Error: %s failed. To repro: tools/run-wasm-api-tests.py "
- "%s %s %s %s %s" %
- (step, self.outdir, self.tempdir, self.name, lang,
- compiler["name"].lower()))
- return code
- def CompileAndRun(self, compiler, language):
- print("==== %s %s/%s ====" %
- (self.name, language["name"], compiler["name"]))
- lang = language["suffix"]
- src_file = self.src_file_basename + "." + lang
- exe_file = self.dst_file_basename + "-" + lang
- obj_file = exe_file + ".o"
- # Compile.
- c = _Call([compiler[lang], "-c", language["cflags"], CFLAGS,
- "-I", WASM_PATH, "-o", obj_file, src_file])
- if c: return self._Error("compilation", lang, compiler, c)
- # Link.
- c = _Call([compiler["cc"], CFLAGS, compiler["ldflags"], obj_file,
- "-o", exe_file, self.lib_file, "-ldl -pthread"])
- if c: return self._Error("linking", lang, compiler, c)
- # Execute.
- exe_file = "./%s-%s" % (self.name, lang)
- c = _Call(["cd", self.tempdir, ";", exe_file])
- if c: return self._Error("execution", lang, compiler, c)
- return 0
- def Main(args):
- if (len(args) < MIN_ARGS or args[1] in ("-h", "--help", "help")):
- print(__doc__)
- return 1
- outdir = sys.argv[1]
- tempdir = sys.argv[2]
- result = 0
- examples = EXAMPLES
- compilers = (GCC, CLANG)
- languages = (C, CXX)
- if len(args) > MIN_ARGS:
- custom_compilers = []
- custom_languages = []
- custom_examples = []
- for i in range(MIN_ARGS, len(args)):
- arg = args[i]
- if arg == "c" and C not in custom_languages:
- custom_languages.append(C)
- elif arg in ("cc", "cpp", "cxx", "c++") and CXX not in custom_languages:
- custom_languages.append(CXX)
- elif arg in ("gcc", "g++") and GCC not in custom_compilers:
- custom_compilers.append(GCC)
- elif arg in ("clang", "clang++") and CLANG not in custom_compilers:
- custom_compilers.append(CLANG)
- elif arg in EXAMPLES and arg not in custom_examples:
- custom_examples.append(arg)
- else:
- print("Didn't understand '%s'" % arg)
- return 1
- if custom_compilers:
- compilers = custom_compilers
- if custom_languages:
- languages = custom_languages
- if custom_examples:
- examples = custom_examples
- for example in examples:
- runner = Runner(example, outdir, tempdir)
- for compiler in compilers:
- for language in languages:
- c = runner.CompileAndRun(compiler, language)
- if c: result = c
- if result:
- print("\nFinished with errors.")
- else:
- print("\nFinished successfully.")
- return result
- if __name__ == "__main__":
- sys.exit(Main(sys.argv))
|