2019-04-17 17:27:15 +00:00
|
|
|
#!/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
|
|
|
|
|
2019-04-26 08:41:16 +00:00
|
|
|
CFLAGS = "-DDEBUG -Wall -Werror -O0 -ggdb -fsanitize=address"
|
2019-04-17 17:27:15 +00:00
|
|
|
|
|
|
|
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",
|
2019-08-20 14:08:31 +00:00
|
|
|
"memory", "finalize", "serialize", "threads", "hostref", "multi"]
|
2019-04-17 17:27:15 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2019-04-26 08:41:16 +00:00
|
|
|
def _Error(self, step, lang, compiler, code):
|
2019-04-17 17:27:15 +00:00
|
|
|
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()))
|
2019-04-26 08:41:16 +00:00
|
|
|
return code
|
2019-04-17 17:27:15 +00:00
|
|
|
|
|
|
|
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])
|
2019-04-26 08:41:16 +00:00
|
|
|
if c: return self._Error("compilation", lang, compiler, c)
|
2019-04-17 17:27:15 +00:00
|
|
|
# Link.
|
|
|
|
c = _Call([compiler["cc"], CFLAGS, compiler["ldflags"], obj_file,
|
|
|
|
"-o", exe_file, self.lib_file, "-ldl -pthread"])
|
2019-04-26 08:41:16 +00:00
|
|
|
if c: return self._Error("linking", lang, compiler, c)
|
2019-04-17 17:27:15 +00:00
|
|
|
# Execute.
|
|
|
|
exe_file = "./%s-%s" % (self.name, lang)
|
|
|
|
c = _Call(["cd", self.tempdir, ";", exe_file])
|
2019-04-26 08:41:16 +00:00
|
|
|
if c: return self._Error("execution", lang, compiler, c)
|
2019-04-17 17:27:15 +00:00
|
|
|
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
|
2019-05-08 11:29:40 +00:00
|
|
|
if result:
|
|
|
|
print("\nFinished with errors.")
|
|
|
|
else:
|
|
|
|
print("\nFinished successfully.")
|
2019-04-17 17:27:15 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
sys.exit(Main(sys.argv))
|