Add web assembly compiler
This does the bare minimum to get the emscripten web assembly compiler
into our code base. There's still some things that'll need to be
improved, but this makes it possible to compile C++ code to web assembly
and run it on a web-page.
Incomplete list of TODOs:
-Improve handling of cached files.
-Figure out exactly how we deploy the webpages to the roborio.
-Figure out what, if anything, needs to be done to import WebGL.
-Actually use WebAssembly somewhere.
-Get a better idea of how the wrapper scripts for the WebAssembly work.
Change-Id: I91db4019395d6488f17f37769032da60fe519f4e
diff --git a/WORKSPACE b/WORKSPACE
index 4dc3f78..b1d5b52 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -416,6 +416,38 @@
url = "https://github.com/bazelbuild/rules_typescript/archive/0.21.0.zip",
)
+emscripten_version = "1.38.31"
+http_archive(
+ name = "emscripten_toolchain",
+ urls = ["https://github.com/emscripten-core/emscripten/archive/" + emscripten_version + ".tar.gz"],
+ strip_prefix = "emscripten-" + emscripten_version,
+ # TODO(james): Once a functioning release contains this patch, convert
+ # to that. See https://github.com/emscripten-core/emscripten/pull/9048
+ patches = ["@//debian:emscripten_toolchain.patch"],
+ sha256 = "c87e42cb6a104094e7daf2b7e61ac835f83674ac0168f533455838a1129cc764",
+ build_file_content = """
+filegroup(
+ name = 'all',
+ visibility = ['//visibility:public'],
+ srcs = glob(['**']),
+)
+""",
+)
+
+new_http_archive(
+ name = "emscripten_clang",
+ sha256 = "a0c2f2c5a897577f40af0fdf68dcf3cf65557ff20c081df26678c066a4fed4b1",
+ strip_prefix = "emscripten-llvm-e" + emscripten_version,
+ url = "https://s3.amazonaws.com/mozilla-games/emscripten/packages/llvm/tag/linux_64bit/emscripten-llvm-e" + emscripten_version + ".tar.gz",
+ build_file_content = """
+filegroup(
+ name = 'all',
+ visibility = ['//visibility:public'],
+ srcs = glob(['**']),
+)
+""",
+)
+
# Fetch our Bazel dependencies that aren't distributed on npm
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
diff --git a/build_tests/BUILD b/build_tests/BUILD
index a341358..7d30723 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -1,6 +1,12 @@
load("//tools/build_rules:ruby.bzl", "ruby_binary")
load("//aos/build:queues.bzl", "queue_library")
load("@com_google_protobuf//:protobuf.bzl", "cc_proto_library")
+load("//tools/cpp/emscripten:defs.bzl", "emcc_binary")
+
+emcc_binary(
+ name = "helloworld.html",
+ srcs = ["helloworld.cc"],
+)
cc_test(
name = "gflags_build_test",
diff --git a/build_tests/helloworld.cc b/build_tests/helloworld.cc
new file mode 100644
index 0000000..c034e96
--- /dev/null
+++ b/build_tests/helloworld.cc
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main() {
+ printf("Hello, World!\n");
+}
diff --git a/debian/emscripten_toolchain.patch b/debian/emscripten_toolchain.patch
new file mode 100644
index 0000000..8a659d1
--- /dev/null
+++ b/debian/emscripten_toolchain.patch
@@ -0,0 +1,33 @@
+--- emcc.py
++++ emcc.py
+@@ -206,6 +206,9 @@ class EmccOptions(object):
+ # Defaults to using the native EOL on each platform (\r\n on Windows, \n on
+ # Linux & MacOS)
+ self.output_eol = os.linesep
++ # Whether we will expand the full path of any input files to remove any
++ # symlinks.
++ self.expand_symlinks = True
+
+
+ def use_source_map(options):
+@@ -859,7 +862,9 @@ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR P
+ '-current_version', '-I', '-L', '-include-pch'):
+ continue # ignore this gcc-style argument
+
+- if os.path.islink(arg) and get_file_suffix(os.path.realpath(arg)) in SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS:
++ if (options.expand_symlinks
++ and os.path.islink(arg)
++ and get_file_suffix(os.path.realpath(arg)) in SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS):
+ arg = os.path.realpath(arg)
+
+ if not arg.startswith('-'):
+@@ -2516,6 +2521,8 @@ def parse_args(newargs):
+ settings_changes.append('SIMD=1')
+ elif newargs[i] == '-mno-simd128':
+ settings_changes.append('SIMD=0')
++ elif newargs[i] == '-no-canonical-prefixes':
++ options.expand_symlinks = False
+
+ if should_exit:
+ sys.exit(0)
+
diff --git a/tools/BUILD b/tools/BUILD
index 6993e5f..ac76ee9 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -14,11 +14,21 @@
)
config_setting(
+ name = "compiler_emscripten",
+ values = {"compiler": "emscripten"},
+)
+
+config_setting(
name = "cpu_k8",
values = {"cpu": "k8"},
)
config_setting(
+ name = "cpu_web",
+ values = {"cpu": "web"},
+)
+
+config_setting(
name = "cpu_roborio",
values = {"cpu": "roborio"},
)
@@ -59,6 +69,8 @@
environment(name = "roborio")
+environment(name = "web")
+
environment(name = "cortex-m4f")
environment(name = "cortex-m4f-k22")
@@ -73,6 +85,7 @@
environments = [
":k8",
":roborio",
+ ":web",
":armhf-debian",
":cortex-m4f",
":cortex-m4f-k22",
diff --git a/tools/build_rules/select.bzl b/tools/build_rules/select.bzl
index 7e6501c..45ba612 100644
--- a/tools/build_rules/select.bzl
+++ b/tools/build_rules/select.bzl
@@ -3,6 +3,11 @@
# quickly find issues where something new isn't handled.
# It will also make adding ORs when it makes sense easy to do nicely.
+# TODO(james): Decide what to do about webassembly/emscripten CPU and
+# compiler configurations. Bazel does not seem to handle the fact that a select
+# statement may not logically need to be evaluated for certain configurations
+# (e.g., most targets can't be build for --cpu=web, so handling "web" in the
+# cpu_select should notionally be unnecessary).
all_cpus = [
"amd64",
"roborio",
@@ -47,6 +52,7 @@
'@//tools:cpu_armhf': values['armhf'],
'@//tools:cpu_cortex_m4f': values['cortex-m'],
'@//tools:cpu_cortex_m4f_k22': values['cortex-m'],
+ '@//tools:cpu_web': None,
})
"""A select wrapper for address space sizes.
@@ -67,6 +73,7 @@
'@//tools:cpu_armhf': values['32'],
'@//tools:cpu_cortex_m4f': values['32'],
'@//tools:cpu_cortex_m4f_k22': values['32'],
+ '@//tools:cpu_web': None,
})
"""A select wrapper for compilers.
@@ -85,4 +92,5 @@
return select({
'@//tools:compiler_gcc': values['gcc'],
'@//tools:compiler_clang': values['clang'],
+ '@//tools:compiler_emscripten': None,
})
diff --git a/tools/ci/run-tests.sh b/tools/ci/run-tests.sh
index f39492d..5649510 100755
--- a/tools/ci/run-tests.sh
+++ b/tools/ci/run-tests.sh
@@ -6,7 +6,7 @@
readonly M4F_TARGETS='//...'
readonly COMMON='-c opt --stamp=no --curses=no --color=no --symlink_prefix=/'
-# Put everything in different output bases so we can get 4 bazel servers
+# Put everything in different output bases so we can get 5 bazel servers
# running and keep them all warm.
# Include --config=eigen to enable Eigen assertions so that we catch potential
@@ -31,3 +31,8 @@
${COMMON} \
--cpu=cortex-m4f \
${M4F_TARGETS}
+
+bazel --output_base=../web_output_base build \
+ ${COMMON} \
+ --cpu=web \
+ ${TARGETS}
diff --git a/tools/cpp/BUILD b/tools/cpp/BUILD
index d2e2fda..c2c285d 100644
--- a/tools/cpp/BUILD
+++ b/tools/cpp/BUILD
@@ -12,6 +12,7 @@
"//tools:has_tsan": [],
"//tools:cpu_cortex_m4f": [],
"//tools:cpu_cortex_m4f_k22": [],
+ "//tools:cpu_web": [],
"//conditions:default": ["//third_party/gperftools:tcmalloc"],
}),
)
@@ -34,6 +35,7 @@
"armhf-debian|clang": "cc-compiler-armhf-debian",
"cortex-m4f|gcc": "cc-compiler-cortex-m4f",
"cortex-m4f-k22|gcc": "cc-compiler-cortex-m4f-k22",
+ "web|emscripten": "//tools/cpp/emscripten:cc_emscripten",
},
)
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index c7a846f..75110f4 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -16,6 +16,10 @@
toolchain_identifier: "stub_armeabi-v7a"
}
default_toolchain {
+ cpu: "web"
+ toolchain_identifier: "emscripten_toolchain"
+}
+default_toolchain {
cpu: "armhf-debian"
toolchain_identifier: "clang_linux_armhf"
}
@@ -330,6 +334,153 @@
}
}
toolchain {
+ toolchain_identifier: "emscripten_toolchain"
+ host_system_name: "web"
+ target_system_name: "emscripten-unknown-emscripten"
+ target_cpu: "web"
+ target_libc: "unknown"
+ compiler: "emscripten"
+ abi_version: "unknown"
+ abi_libc_version: "unknown"
+ tool_path {
+ name: "gcc"
+ path: "emscripten/emcc.sh"
+ }
+ tool_path {
+ name: "ld"
+ path: "emscripten/emcc.sh"
+ }
+ tool_path {
+ name: "ar"
+ path: "emscripten/emar.sh"
+ }
+ tool_path {
+ name: "cpp"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "gcov"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "nm"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "objdump"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "objcopy"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "strip"
+ path: "/bin/false"
+ }
+ compiler_flag: "-isystem"
+ compiler_flag: "external/emscripten_toolchain/system/include"
+ compiler_flag: "-fno-exceptions"
+ compiler_flag: "-fdiagnostics-color=always"
+ compiler_flag: "-Wall"
+ compiler_flag: "-Werror"
+ compiler_flag: "-ffunction-sections"
+ compiler_flag: "-fdata-sections"
+ linker_flag: "-no-canonical-prefixes"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/libcxx"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/lib/libcxxabi/include"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/compat"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/SSE"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/libc"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/lib/libc/musl/arch/emscripten"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/local/include"
+ unfiltered_cxx_flag: "-no-canonical-prefixes"
+ unfiltered_cxx_flag: "-Wno-builtin-macro-redefined"
+ unfiltered_cxx_flag: "-D__DATE__=\"redacted\""
+ unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\""
+ unfiltered_cxx_flag: "-D__TIME__=\"redacted\""
+ feature {
+ name: "opt"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=0"
+ flag: "-O2"
+ flag: "--closure"
+ flag: "1"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "dbg"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=1"
+ }
+ flag_group {
+ flag: "-fno-omit-frame-pointer"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "fastbuild"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=0"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "all_modes"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "assemble"
+ action: "c-compile"
+ flag_group {
+ flag: "-std=gnu99"
+ }
+ }
+ flag_set {
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-std=gnu++1y"
+ }
+ }
+ }
+}
+toolchain {
toolchain_identifier: "roborio_linux"
host_system_name: "roborio"
target_system_name: "roborio"
diff --git a/tools/cpp/emscripten/BUILD b/tools/cpp/emscripten/BUILD
new file mode 100644
index 0000000..dd304e1
--- /dev/null
+++ b/tools/cpp/emscripten/BUILD
@@ -0,0 +1,38 @@
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "all",
+ srcs = [
+ "emar.sh",
+ "emcc.sh",
+ ":emscripten_cache_content",
+ "@emscripten_clang//:all",
+ "@emscripten_toolchain//:all",
+ "@nodejs//:bin/node",
+ ],
+)
+
+# TODO(james): There is a set of static files that emscripten will always
+# attempt to either rebuild or source from a cache. Ideally, we would make
+# the build of these files part of the normal build process; however, the
+# emscripten compiler handles sandboxing poorly for these files and so it
+# is simplest to just manually run emscripten outside of the sandbox and
+# copy over the cache folder for now.
+filegroup(
+ name = "emscripten_cache_content",
+ srcs = glob(["emscripten_cache/**/*"]),
+)
+
+cc_toolchain(
+ name = "cc_emscripten",
+ all_files = ":all",
+ compiler_files = ":all",
+ cpu = "web",
+ dwp_files = ":empty",
+ dynamic_runtime_libs = [":empty"],
+ linker_files = ":all",
+ objcopy_files = ":empty",
+ static_runtime_libs = [":empty"],
+ strip_files = ":empty",
+ supports_param_files = 0,
+)
diff --git a/tools/cpp/emscripten/defs.bzl b/tools/cpp/emscripten/defs.bzl
new file mode 100644
index 0000000..721e895
--- /dev/null
+++ b/tools/cpp/emscripten/defs.bzl
@@ -0,0 +1,51 @@
+# Sourced from https://github.com/ribrdb/rules_emscripten/blob/master/toolchain/defs.bzl
+# TODO(james): Specialize this more for our purposes--e.g.,
+# we probably will only actually use one set of the possible options.
+def emcc_binary(name,
+ memory_init_file=0,
+ wasm=True,
+ worker=False,
+ linkopts=[],
+ **kwargs):
+ includejs = False
+ includehtml = False
+ linkopts = list(linkopts)
+ if name.endswith(".html"):
+ basename = name[:-5]
+ includehtml = True
+ includejs = True
+ elif name.endswith(".js"):
+ basename = name[:-3]
+ includejs = True
+ outputs = []
+ if includejs:
+ outputs.append(basename + ".js")
+ if wasm:
+ outputs.append(basename + ".wasm")
+ if memory_init_file:
+ outputs.append(basename + ".mem")
+ if worker:
+ outputs.append(basename + ".worker.js")
+ linkopts.append('--proxy-to-worker')
+
+ if includehtml:
+ outputs.append(basename + ".html")
+ if not wasm:
+ linkopts.append('-s WASM=0')
+ linkopts.append('--memory-init-file %d' % memory_init_file)
+ if includejs:
+ tarfile = name + ".tar"
+ # we'll generate a tarfile and extract multiple outputs
+ native.cc_binary(name=tarfile, linkopts=linkopts, restricted_to = ["//tools:web"], **kwargs)
+ native.genrule(
+ name="emcc_extract_" + tarfile,
+ srcs=[tarfile],
+ outs=outputs,
+ output_to_bindir=1,
+ testonly=kwargs.get('testonly'),
+ restricted_to = ["//tools:web"],
+ cmd="""
+ tar xf $< -C "$(@D)"/$$(dirname "%s")
+ """ % [outputs[0]])
+ else:
+ native.cc_binary(name=name, linkopts=linkopts, restricted_to = ["//tools:web"], **kwargs)
diff --git a/tools/cpp/emscripten/emar.sh b/tools/cpp/emscripten/emar.sh
new file mode 100755
index 0000000..a94fb0b
--- /dev/null
+++ b/tools/cpp/emscripten/emar.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Originally sourced from https://github.com/ribrdb/rules_emscripten
+set -euo pipefail
+EM_CONFIG="LLVM_ROOT='external/emscripten_clang';"
+EM_CONFIG+="EMSCRIPTEN_NATIVE_OPTIMIZER='external/emscripten_clang/optimizer';"
+EM_CONFIG+="BINARYEN_ROOT='external/emscripten_clang/binaryen';"
+EM_CONFIG+="NODE_JS='external/nodejs/bin/node';"
+EM_CONFIG+="EMSCRIPTEN_ROOT='external/emscripten_toolchain';"
+EM_CONFIG+="SPIDERMONKEY_ENGINE='';"
+EM_CONFIG+="V8_ENGINE='';"
+EM_CONFIG+="TEMP_DIR='tmp';"
+EM_CONFIG+="COMPILER_ENGINE=NODE_JS;"
+EM_CONFIG+="JS_ENGINES=[NODE_JS];"
+export EM_CONFIG
+
+export EM_EXCLUSIVE_CACHE_ACCESS=1
+export EMCC_SKIP_SANITY_CHECK=1
+export EMCC_WASM_BACKEND=0
+export EMMAKEN_NO_SDK=1
+
+python external/emscripten_toolchain/emar.py "$@"
diff --git a/tools/cpp/emscripten/emcc.sh b/tools/cpp/emscripten/emcc.sh
new file mode 100755
index 0000000..52ed893
--- /dev/null
+++ b/tools/cpp/emscripten/emcc.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# Originally sourced from https://github.com/ribrdb/rules_emscripten
+set -euo pipefail
+EM_CONFIG="LLVM_ROOT='$(pwd -P)/external/emscripten_clang';"
+EM_CONFIG+="EMSCRIPTEN_NATIVE_OPTIMIZER='external/emscripten_clang/optimizer';"
+EM_CONFIG+="BINARYEN_ROOT='external/emscripten_clang/binaryen';"
+EM_CONFIG+="NODE_JS='$(pwd -P)/external/nodejs/bin/node';"
+EM_CONFIG+="EMSCRIPTEN_ROOT='external/emscripten_toolchain';"
+EM_CONFIG+="SPIDERMONKEY_ENGINE='';"
+EM_CONFIG+="V8_ENGINE='';"
+EM_CONFIG+="TEMP_DIR='tmp';"
+EM_CONFIG+="COMPILER_ENGINE=NODE_JS;"
+EM_CONFIG+="JS_ENGINES=[NODE_JS];"
+export EM_CONFIG
+
+export EM_EXCLUSIVE_CACHE_ACCESS=1
+export EMCC_SKIP_SANITY_CHECK=1
+# export EMCC_DEBUG=2
+export EMCC_WASM_BACKEND=0
+export EMMAKEN_NO_SDK=1
+
+mkdir -p "tmp/emscripten_cache"
+export EM_CACHE="$(pwd -P)/tmp/emscripten_cache"
+export EMCC_TEMP_DIR="$(pwd -P)/tmp"
+
+# Prepare the cache content so emscripten doesn't try to rebuild it all the time
+cache_source=tools/cpp/emscripten/emscripten_cache
+if [ -d toolchain/emscripten_cache ]; then
+ cache_source=toolchain/emscripten_cache
+elif [ -d external/rules_emscripten/toolchain/emscripten_cache ]; then
+ cache_source=external/rules_emscripten/toolchain/emscripten_cache
+fi
+(
+ cd tmp/emscripten_cache;
+ for n in "../../$cache_source"/*;do
+ ln -s "$n"
+ done
+)
+
+argv=("$@")
+tarfile=
+# Find the -o option, and strip the .tar from it.
+for (( i=0; i<$#; i++ )); do
+ if [[ "x${argv[i]}" == x-o ]]; then
+ arg=${argv[$((i+1))]}
+ if [[ "x$arg" == x*.tar ]];then
+ tarfile="$(cd $(dirname "$arg"); pwd -P)/$(basename "$arg")"
+ emfile="$(dirname "$arg")/$(basename $arg .tar)"
+ basearg="$(basename "$(basename "$(basename "$emfile" .js)" .html)" .wasm)"
+ baseout="$(dirname "$arg")/$basearg"
+ argv[$((i+1))]="$emfile"
+ fi
+ fi
+done
+python external/emscripten_toolchain/emcc.py "${argv[@]}"
+# Now create the tarfile
+shopt -s extglob
+if [ "x$tarfile" != x ]; then
+ outdir="$(dirname "$baseout")"
+ outbase="$(basename "$baseout")"
+ (
+ cd "$outdir";
+ tar cf "$tarfile" "$outbase."?(html|js|wasm|mem|data|worker.js)
+ )
+fi
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/binaryen_tag_version_82.txt b/tools/cpp/emscripten/emscripten_cache/asmjs/binaryen_tag_version_82.txt
new file mode 100644
index 0000000..01e1f09
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/binaryen_tag_version_82.txt
@@ -0,0 +1 @@
+version_82
\ No newline at end of file
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/generated_struct_info.json b/tools/cpp/emscripten/emscripten_cache/asmjs/generated_struct_info.json
new file mode 100644
index 0000000..1e636fd
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/generated_struct_info.json
@@ -0,0 +1 @@
+{"structs":{"utsname":{"sysname":0,"nodename":65,"domainname":325,"machine":260,"version":195,"release":130,"__size__":390},"sockaddr":{"sa_data":2,"sa_family":0,"__size__":16},"VRDisplayCapabilities":{"maxLayers":12,"hasPosition":0,"hasExternalDisplay":4,"canPresent":8,"__size__":16},"timespec":{"tv_sec":0,"tv_nsec":4,"__size__":8},"utimbuf":{"modtime":4,"actime":0,"__size__":8},"EmscriptenVisibilityChangeEvent":{"hidden":0,"visibilityState":4,"__size__":8},"SDL_MouseButtonEvent":{"timestamp":4,"button":16,"state":17,"windowID":8,"which":12,"y":24,"x":20,"padding2":19,"type":0,"padding1":18,"__size__":28},"sockaddr_in":{"sin_port":2,"sin_addr":{"s_addr":4,"__size__":4},"sin_family":0,"sin_zero":8,"__size__":16},"pthread":{"tsd":116,"attr":120,"canceldisable":72,"locale":188,"threadStatus":0,"tsd_used":60,"pid":56,"robust_list":168,"stack":92,"cancelasync":76,"tid":52,"threadExitCode":4,"detached":80,"profilerBlock":20,"self":24,"stack_size":96,"__size__":244},"stat":{"st_rdev":28,"st_mtim":{"tv_sec":64,"tv_nsec":68,"__size__":8},"st_blocks":52,"st_atim":{"tv_sec":56,"tv_nsec":60,"__size__":8},"st_nlink":16,"__st_ino_truncated":8,"st_ctim":{"tv_sec":72,"tv_nsec":76,"__size__":8},"st_mode":12,"st_blksize":48,"__st_dev_padding":4,"st_dev":0,"st_size":40,"st_gid":24,"__st_rdev_padding":32,"st_uid":20,"st_ino":80,"__size__":88},"SDL_KeyboardEvent":{"repeat":9,"keysym":12,"state":8,"windowID":4,"__size__":28,"type":0,"padding3":11,"padding2":10},"SDL_MouseMotionEvent":{"yrel":32,"timestamp":4,"state":16,"windowID":8,"which":12,"xrel":28,"y":24,"x":20,"type":0,"__size__":36},"SDL_Rect":{"y":4,"x":0,"h":12,"w":8,"__size__":16},"itimerspec":{"it_interval":{"tv_sec":0,"tv_nsec":4,"__size__":8},"it_value":{"tv_sec":8,"tv_nsec":12,"__size__":8},"__size__":16},"iovec":{"iov_len":4,"iov_base":0,"__size__":8},"timezone":{"tz_dsttime":4,"tz_minuteswest":0,"__size__":8},"flock":{"l_whence":2,"l_type":0,"l_start":8,"__size__":32,"l_len":16,"l_pid":24},"EmscriptenOrientationChangeEvent":{"orientationIndex":0,"orientationAngle":4,"__size__":8},"statfs":{"f_bsize":4,"f_bavail":16,"f_fsid":28,"f_files":20,"f_frsize":40,"f_namelen":36,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flags":44,"__size__":64},"addrinfo":{"ai_flags":0,"ai_next":28,"ai_canonname":24,"ai_socktype":8,"ai_addr":20,"ai_protocol":12,"ai_family":4,"ai_addrlen":16,"__size__":32},"emscripten_fetch_t":{"status":42,"userData":4,"readyState":40,"__proxyState":108,"url":8,"totalBytes":32,"__attributes":112,"numBytes":16,"dataOffset":24,"statusText":44,"data":12,"id":0,"__size__":200},"SDL_ResizeEvent":{"h":8,"type":0,"w":4,"__size__":12},"tms":{"tms_stime":4,"tms_utime":0,"tms_cstime":12,"tms_cutime":8,"__size__":16},"SDL_Color":{"unused":3,"r":0,"b":2,"g":1,"__size__":4},"EmscriptenKeyboardEvent":{"code":32,"charValue":120,"locale":88,"shiftKey":72,"altKey":76,"which":160,"metaKey":80,"location":64,"key":0,"ctrlKey":68,"charCode":152,"keyCode":156,"repeat":84,"__size__":164},"emscripten_fetch_attr_t":{"userName":64,"userData":32,"withCredentials":56,"onerror":40,"requestHeaders":72,"onprogress":44,"onsuccess":36,"overriddenMimeType":76,"requestDataSize":84,"requestData":80,"requestMethod":0,"destinationPath":60,"timeoutMSecs":52,"attributes":48,"password":68,"__size__":88},"rusage":{"ru_msgrcv":56,"ru_utime":{"tv_sec":0,"tv_usec":4,"__size__":8},"ru_isrss":28,"ru_stime":{"tv_sec":8,"tv_usec":12,"__size__":8},"ru_nsignals":60,"ru_nivcsw":68,"ru_msgsnd":52,"ru_nswap":40,"ru_minflt":32,"ru_nvcsw":64,"ru_ixrss":20,"ru_inblock":44,"ru_idrss":24,"ru_maxrss":16,"ru_oublock":48,"ru_majflt":36,"__size__":136},"div_t":{"quot":0,"rem":4,"__size__":8},"timeval":{"tv_sec":0,"tv_usec":4,"__size__":8},"rlimit":{"rlim_cur":0,"rlim_max":8,"__size__":16},"in6_addr":{"__in6_union":{"__s6_addr16":0,"__s6_addr":0,"__s6_addr32":0,"__size__":16},"__size__":16},"tm":{"tm_sec":0,"tm_hour":8,"tm_mday":12,"tm_isdst":32,"tm_year":20,"tm_zone":40,"tm_mon":16,"tm_yday":28,"tm_gmtoff":36,"tm_wday":24,"tm_min":4,"__size__":44},"EmscriptenWebGLContextAttributes":{"majorVersion":32,"stencil":8,"renderViaOffscreenBackBuffer":52,"preserveDrawingBuffer":20,"failIfMajorPerformanceCaveat":28,"explicitSwapControl":44,"antialias":12,"depth":4,"minorVersion":36,"proxyContextToMainThread":48,"premultipliedAlpha":16,"enableExtensionsByDefault":40,"alpha":0,"powerPreference":24,"__size__":56},"EmscriptenBatteryEvent":{"dischargingTime":8,"level":16,"charging":24,"chargingTime":0,"__size__":32},"protoent":{"p_aliases":4,"p_proto":8,"p_name":0,"__size__":12},"SDL_Surface":{"userdata":24,"locked":28,"clip_rect":36,"format":4,"h":12,"refcount":56,"map":52,"flags":0,"w":8,"pitch":16,"lock_data":32,"pixels":20,"__size__":60},"EmscriptenTouchEvent":{"touches":20,"shiftKey":8,"altKey":12,"metaKey":16,"ctrlKey":4,"__size__":1684,"numTouches":0},"EmscriptenFocusEvent":{"id":128,"nodeName":0,"__size__":256},"sockaddr_in6":{"sin6_family":0,"sin6_flowinfo":4,"sin6_scope_id":24,"sin6_addr":{"__in6_union":{"__s6_addr16":8,"__s6_addr":8,"__s6_addr32":8,"__size__":16},"__size__":16},"__size__":28,"sin6_port":2},"SDL_JoyAxisEvent":{"__size__":12,"type":0,"value":8,"which":4,"padding2":7,"padding1":6,"axis":5},"netent":{"n_name":0,"n_net":12,"n_addrtype":8,"n_aliases":4,"__size__":16},"SDL_PixelFormat":{"palette":4,"Gloss":29,"Bmask":20,"Bloss":30,"Rloss":28,"format":0,"Gshift":33,"Aloss":31,"BitsPerPixel":8,"refcount":36,"next":40,"padding":10,"Rmask":12,"Bshift":34,"Gmask":16,"BytesPerPixel":9,"Amask":24,"Rshift":32,"Ashift":35,"__size__":44},"SDL_JoyButtonEvent":{"type":0,"button":5,"state":6,"which":4,"padding1":7,"__size__":8},"VRQuaternion":{"y":4,"x":0,"z":8,"w":12,"__size__":16},"in_addr":{"s_addr":0,"__size__":4},"EmscriptenDeviceOrientationEvent":{"timestamp":0,"beta":16,"alpha":8,"__size__":40,"gamma":24,"absolute":32},"libc":{"global_locale":40,"__size__":64},"SDL_WindowEvent":{"data2":16,"type":0,"data1":12,"windowID":4,"__size__":20,"padding1":9,"event":8,"padding3":11,"padding2":10},"SDL_Keysym":{"scancode":0,"mod":8,"unicode":12,"sym":4,"__size__":16},"cmsghdr":{"cmsg_type":8,"cmsg_level":4,"cmsg_len":0,"__size__":12},"VREyeParameters":{"offset":{"y":4,"x":0,"z":8,"__size__":12},"renderWidth":12,"renderHeight":16,"__size__":20},"EmscriptenUiEvent":{"windowInnerWidth":12,"detail":0,"scrollLeft":32,"documentBodyClientHeight":8,"windowInnerHeight":16,"scrollTop":28,"windowOuterHeight":24,"windowOuterWidth":20,"documentBodyClientWidth":4,"__size__":36},"thread_profiler_block":{"threadStatus":0,"timeSpentInStatus":16,"currentStatusStartTime":8,"name":72,"__size__":104},"pollfd":{"fd":0,"events":4,"revents":6,"__size__":8},"VRFrameData":{"pose":{"linearVelocity":{"y":280,"x":276,"z":284,"__size__":12},"orientation":{"y":304,"x":300,"z":308,"w":312,"__size__":16},"angularAcceleration":{"y":332,"x":328,"z":336,"__size__":12},"poseFlags":340,"angularVelocity":{"y":320,"x":316,"z":324,"__size__":12},"linearAcceleration":{"y":292,"x":288,"z":296,"__size__":12},"position":{"y":268,"x":264,"z":272,"__size__":12},"__size__":80},"rightViewMatrix":200,"timestamp":0,"leftProjectionMatrix":8,"leftViewMatrix":72,"rightProjectionMatrix":136,"__size__":344},"dirent":{"d_name":19,"d_off":8,"d_ino":0,"d_reclen":16,"d_type":18,"__size__":280},"EmscriptenTouchPoint":{"clientX":12,"clientY":16,"identifier":0,"targetX":36,"targetY":40,"isChanged":28,"canvasY":48,"canvasX":44,"pageX":20,"pageY":24,"screenY":8,"screenX":4,"onTarget":32,"__size__":52},"VRLayerInit":{"source":0,"rightBounds":20,"leftBounds":4,"__size__":36},"EmscriptenDeviceMotionEvent":{"timestamp":0,"accelerationIncludingGravityZ":48,"accelerationIncludingGravityX":32,"accelerationIncludingGravityY":40,"accelerationY":16,"accelerationX":8,"rotationRateBeta":64,"accelerationZ":24,"rotationRateGamma":72,"rotationRateAlpha":56,"__size__":80},"SDL_AudioSpec":{"padding":10,"userdata":20,"format":4,"channels":6,"callback":16,"samples":8,"freq":0,"size":12,"silence":7,"__size__":24},"hostent":{"h_addrtype":8,"h_addr_list":16,"h_name":0,"__size__":20,"h_aliases":4,"h_length":12},"SDL_MouseWheelEvent":{"timestamp":4,"windowID":8,"which":12,"y":20,"x":16,"type":0,"__size__":24},"linger":{"l_onoff":0,"l_linger":4,"__size__":8},"SDL_version":{"major":0,"patch":2,"minor":1,"__size__":3},"statvfs":{"f_bsize":0,"f_bavail":16,"f_fsid":32,"f_favail":28,"f_files":20,"f_frsize":4,"f_blocks":8,"f_ffree":24,"f_bfree":12,"f_flag":40,"f_namemax":44,"__size__":72},"EmscriptenFullscreenChangeEvent":{"elementWidth":264,"screenWidth":272,"nodeName":8,"elementHeight":268,"fullscreenEnabled":4,"screenHeight":276,"isFullscreen":0,"id":136,"__size__":280},"EmscriptenWheelEvent":{"deltaX":72,"deltaY":80,"deltaZ":88,"deltaMode":96,"mouse":0,"__size__":104},"VRPose":{"linearVelocity":{"y":16,"x":12,"z":20,"__size__":12},"orientation":{"y":40,"x":36,"z":44,"w":48,"__size__":16},"angularAcceleration":{"y":68,"x":64,"z":72,"__size__":12},"poseFlags":76,"angularVelocity":{"y":56,"x":52,"z":60,"__size__":12},"linearAcceleration":{"y":28,"x":24,"z":32,"__size__":12},"position":{"y":4,"x":0,"z":8,"__size__":12},"__size__":80},"SDL_TouchFingerEvent":{"timestamp":4,"dy":36,"touchId":8,"pressure":40,"dx":32,"type":0,"y":28,"x":24,"fingerId":16,"__size__":48},"SDL_AudioCVT":{"len_ratio":32,"len_cvt":24,"rate_incr":8,"filters":40,"len":20,"needed":0,"filter_index":80,"src_format":4,"len_mult":28,"__size__":88,"buf":16,"dst_format":6},"VRVector3":{"y":4,"x":0,"z":8,"__size__":12},"EmscriptenPointerlockChangeEvent":{"id":132,"nodeName":4,"isActive":0,"__size__":260},"EmscriptenMouseEvent":{"clientX":16,"clientY":20,"targetX":52,"buttons":42,"timestamp":0,"button":40,"targetY":56,"altKey":32,"canvasY":64,"metaKey":36,"movementX":44,"movementY":48,"shiftKey":28,"ctrlKey":24,"screenY":12,"screenX":8,"canvasX":60,"__size__":72},"msghdr":{"msg_iov":8,"msg_iovlen":12,"msg_namelen":4,"msg_controllen":20,"msg_flags":24,"msg_name":0,"msg_control":16,"__size__":28},"EmscriptenGamepadEvent":{"index":1300,"analogButton":528,"timestamp":0,"numButtons":12,"mapping":1368,"digitalButton":1040,"connected":1296,"numAxes":8,"__size__":1432,"id":1304,"axis":16},"SDL_Palette":{"ncolors":0,"colors":4,"version":8,"refcount":12,"__size__":16},"EmscriptenFullscreenStrategy":{"canvasResizedCallbackUserData":16,"canvasResolutionScaleMode":4,"scaleMode":0,"canvasResizedCallbackTargetThread":20,"canvasResizedCallback":12,"filteringMode":8,"__size__":24},"timeb":{"dstflag":8,"timezone":6,"time":0,"millitm":4,"__size__":12},"SDL_TextInputEvent":{"text":8,"windowID":4,"type":0,"__size__":40}},"defines":{"ETXTBSY":26,"EOF":-1,"EMSCRIPTEN_EVENT_MOUSEOVER":35,"ETOOMANYREFS":109,"ENAMETOOLONG":36,"ENOPKG":65,"UUID_TYPE_DCE_TIME":1,"_SC_XOPEN_LEGACY":129,"_SC_XOPEN_VERSION":89,"F_UNLCK":2,"_SC_BC_DIM_MAX":37,"EL3HLT":46,"S_IFDIR":16384,"EMSCRIPTEN_EVENT_KEYPRESS":1,"EINPROGRESS":115,"_SC_BARRIERS":133,"EMSCRIPTEN_EVENT_TOUCHMOVE":24,"EM_CALLBACK_THREAD_CONTEXT_MAIN_BROWSER_THREAD":1,"SDL_AUDIO_ALLOW_FREQUENCY_CHANGE":1,"AUDIO_U8":8,"EAI_AGAIN":-3,"_PC_MAX_CANON":1,"ENOTSUP":95,"EFBIG":27,"O_CREAT":64,"EMSCRIPTEN_EVENT_POINTERLOCKERROR":38,"_SC_2_PBS_LOCATE":170,"VR_POSE_ANGULAR_VELOCITY":16,"_CS_POSIX_V6_LP64_OFF64_LIBS":1126,"ENOLINK":67,"ABDAY_7":131078,"ABDAY_6":131077,"ABDAY_5":131076,"ABDAY_4":131075,"ABDAY_3":131074,"ABDAY_2":131073,"ABDAY_1":131072,"EL3RST":47,"YESEXPR":327680,"_SC_V6_ILP32_OFFBIG":177,"SDL_MINOR_VERSION":3,"EMSCRIPTEN_WEBGL_CONTEXT_PROXY_FALLBACK":1,"_SC_MEMLOCK":17,"ENOTUNIQ":76,"EMSCRIPTEN_RESULT_FAILED":-6,"ABMON_1":131086,"ELNRNG":48,"UUID_VARIANT_MICROSOFT":2,"EMSCRIPTEN_EVENT_TOUCHSTART":22,"ENOANO":55,"EMSCRIPTEN_EVENT_FOCUSIN":14,"EMSCRIPTEN_EVENT_MOUSEUP":6,"ENOPROTOOPT":92,"POLLIN":1,"S_IALLUGO":4095,"_SC_THREAD_KEYS_MAX":74,"EM_THREAD_STATUS_WAITPROXY":5,"O_RDWR":2,"EREMCHG":78,"AUDIO_S32LSB":32800,"_SC_2_PBS":168,"_SC_TRACE_INHERIT":183,"_SC_REGEXP":155,"_CS_POSIX_V6_LP64_OFF64_CFLAGS":1124,"_SC_DELAYTIMER_MAX":26,"S_IWUGO":146,"S_IFREG":32768,"F_GETLK64":12,"O_DIRECTORY":65536,"POLLHUP":16,"S_IFMT":61440,"F_SETLK64":13,"VR_POSE_LINEAR_VELOCITY":2,"_SC_XOPEN_CRYPT":92,"_PC_CHOWN_RESTRICTED":6,"EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW":0,"E2BIG":7,"ABMON_3":131088,"AM_STR":131110,"SDL_AUDIO_MASK_ENDIAN":4096,"ALT_DIGITS":131119,"EHOSTDOWN":112,"EBFONT":59,"ENOTEMPTY":39,"AUDIO_S16":32784,"TIOCGPGRP":21519,"EBUSY":16,"_SC_MQ_PRIO_MAX":28,"_SC_PAGE_SIZE":30,"EADDRINUSE":98,"ENOTSOCK":88,"PM_STR":131111,"O_WRONLY":1,"_SC_STREAM_MAX":5,"ABMON_9":131094,"ELIBACC":79,"EMSCRIPTEN_FETCH_WAITABLE":128,"S_IFIFO":4096,"EDQUOT":122,"EAI_SYSTEM":-11,"ENOENT":2,"EALREADY":114,"_SC_TIMERS":11,"O_SYNC":1052672,"SEEK_END":2,"EM_THREAD_STATUS_FINISHED":6,"_PC_REC_MIN_XFER_SIZE":16,"_PC_PATH_MAX":4,"_SC_SPORADIC_SERVER":160,"ECOMM":70,"_SC_NPROCESSORS_ONLN":84,"_CS_POSIX_V6_LPBIG_OFFBIG_LIBS":1130,"_PC_MAX_INPUT":2,"_SC_VERSION":29,"_SC_XBS5_LPBIG_OFFBIG":128,"_SC_CLK_TCK":2,"ABMON_2":131087,"EXFULL":54,"ABMON_7":131092,"ABMON_6":131091,"ABMON_5":131090,"ABMON_4":131089,"ENOTDIR":20,"ABMON_8":131093,"VR_EYE_RIGHT":1,"_SC_AIO_MAX":24,"ERA":131116,"POLLWRNORM":256,"_SC_THREAD_PRIO_INHERIT":80,"_PC_2_SYMLINKS":20,"_SC_XBS5_LP64_OFF64":127,"EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE":30,"ENETRESET":102,"EAFNOSUPPORT":97,"VR_POSE_LINEAR_ACCELERATION":4,"MON_3":131100,"EMSCRIPTEN_EVENT_TARGET_WINDOW":2,"MON_1":131098,"EMSCRIPTEN_EVENT_DEVICEORIENTATION":16,"MON_7":131104,"MON_4":131101,"MON_5":131102,"_SC_SPAWN":159,"MON_8":131105,"MON_9":131106,"_CS_POSIX_V6_ILP32_OFF32_LDFLAGS":1117,"S_IFSOCK":49152,"S_IRUGO":292,"SOCK_DGRAM":2,"POLLERR":8,"EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD":2,"EINVAL":22,"_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS":1128,"POLLRDNORM":64,"AUDIO_F32SYS":33056,"_SC_TRACE_SYS_MAX":244,"AI_V4MAPPED":8,"AI_NUMERICHOST":4,"_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS":1,"EHOSTUNREACH":113,"ENOCSI":50,"AF_INET6":10,"EPROTONOSUPPORT":93,"_SC_AIO_PRIO_DELTA_MAX":25,"_SC_MONOTONIC_CLOCK":149,"ETIME":62,"ENOTTY":25,"_SC_XOPEN_ENH_I18N":93,"EAI_SERVICE":-8,"EAGAIN":11,"F_SETLKW64":14,"EMSGSIZE":90,"ELIBEXEC":83,"_SC_MEMORY_PROTECTION":19,"_SC_V6_ILP32_OFF32":176,"EMSCRIPTEN_FULLSCREEN_SCALE_CENTER":3,"SDL_AUDIO_ALLOW_FORMAT_CHANGE":2,"ECANCELED":125,"EMSCRIPTEN_EVENT_TARGET_SCREEN":3,"_SC_SPIN_LOCKS":154,"_SC_XOPEN_SHM":94,"_PC_LINK_MAX":0,"TIOCSPGRP":21520,"EOPNOTSUPP":95,"EMSCRIPTEN_EVENT_MOUSEENTER":33,"EAI_FAIL":-4,"NOEXPR":327681,"_SC_FSYNC":15,"_SC_GETGR_R_SIZE_MAX":69,"EDESTADDRREQ":89,"EADDRNOTAVAIL":99,"AUDIO_S32SYS":32800,"MON_2":131099,"_SC_TRACE_NAME_MAX":243,"_SC_BC_BASE_MAX":36,"EMSCRIPTEN_EVENT_CANVASRESIZED":37,"EPERM":1,"EAI_FAMILY":-6,"O_NOFOLLOW":131072,"SOCK_STREAM":1,"O_APPEND":1024,"_SC_XOPEN_STREAMS":246,"_SC_GETPW_R_SIZE_MAX":70,"MON_6":131103,"EPROTOTYPE":91,"_SC_CPUTIME":138,"ENOMEDIUM":123,"_SC_XBS5_ILP32_OFFBIG":126,"S_IFBLK":24576,"T_FMT_AMPM":131115,"SDL_PIXELFORMAT_RGBA8888":-2042224636,"F_SETLKW":14,"SDL_TOUCH_MOUSEID":-1,"EMSCRIPTEN_EVENT_SCROLL":11,"ELOOP":40,"_SC_OPEN_MAX":4,"EMSCRIPTEN_RESULT_DEFERRED":1,"_SC_2_FORT_RUN":50,"EMSCRIPTEN_EVENT_VISIBILITYCHANGE":21,"EREMOTE":66,"_SC_RE_DUP_MAX":44,"_SC_THREAD_PRIO_PROTECT":81,"_SC_2_PBS_CHECKPOINT":175,"_SC_2_PBS_TRACK":172,"MON_10":131107,"MON_11":131108,"MON_12":131109,"VR_POSE_POSITION":1,"_SC_THREAD_PROCESS_SHARED":82,"TCSETA":21510,"AF_INET":2,"_SC_SHARED_MEMORY_OBJECTS":22,"F_GETFD":1,"EMSCRIPTEN_EVENT_DEVICEMOTION":17,"SDL_MIX_MAXVOLUME":128,"TCGETA":21509,"_PC_ALLOC_SIZE_MIN":18,"TCSETS":21506,"ELIBMAX":82,"_SC_READER_WRITER_LOCKS":153,"EMULTIHOP":72,"_SC_PHYS_PAGES":85,"_SC_MEMLOCK_RANGE":18,"_SC_PRIORITY_SCHEDULING":10,"T_FMT":131114,"AI_ALL":16,"_PC_VDISABLE":8,"THOUSEP":65537,"_SC_TRACE_EVENT_FILTER":182,"ERA_T_FMT":131121,"_SC_THREAD_ATTR_STACKADDR":77,"_SC_THREAD_THREADS_MAX":76,"_SC_LOGIN_NAME_MAX":71,"EMSCRIPTEN_FETCH_LOAD_TO_MEMORY":1,"_SC_2_C_BIND":47,"_PC_NO_TRUNC":7,"ECONNABORTED":103,"EMSCRIPTEN_RESULT_SUCCESS":0,"_SC_SHELL":157,"EFAULT":14,"O_LARGEFILE":32768,"_SC_V6_LP64_OFF64":178,"_CS_GNU_LIBC_VERSION":2,"_SC_SEM_VALUE_MAX":33,"_SC_MQ_OPEN_MAX":27,"AI_ADDRCONFIG":32,"_SC_HOST_NAME_MAX":180,"_SC_THREAD_STACK_MIN":75,"_SC_TIMEOUTS":164,"POLLOUT":4,"_SC_IPV6":235,"_SC_CHILD_MAX":1,"EDOM":33,"_SC_2_PBS_MESSAGE":171,"EILSEQ":84,"UUID_VARIANT_DCE":1,"_SC_2_C_DEV":48,"_SC_TIMER_MAX":35,"FP_ZERO":2,"EPFNOSUPPORT":96,"TIOCSWINSZ":21524,"ENONET":64,"ECHRNG":44,"_SC_THREADS":67,"_SC_REALTIME_SIGNALS":9,"CLOCKS_PER_SEC":1000000,"ERA_D_T_FMT":131120,"ESRCH":3,"D_FMT":131113,"EM_FUNC_SIG_IIII":637534208,"POLLPRI":2,"_PC_ASYNC_IO":10,"DAY_2":131080,"DAY_3":131081,"DAY_1":131079,"DAY_6":131084,"DAY_7":131085,"DAY_4":131082,"DAY_5":131083,"_SC_SYNCHRONIZED_IO":14,"AT_REMOVEDIR":512,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF":1,"IPPROTO_UDP":17,"_SC_MAPPED_FILES":16,"EL2NSYNC":45,"_SC_NGROUPS_MAX":3,"ENOMSG":42,"EISDIR":21,"_SC_SEMAPHORES":21,"AI_NUMERICSERV":1024,"EMSCRIPTEN_RESULT_TIMED_OUT":-8,"EDEADLOCK":35,"EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST":31,"ERA_D_FMT":131118,"EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE":29,"EMSCRIPTEN_FETCH_SYNCHRONOUS":64,"EM_FUNC_SIG_II":570425344,"AUDIO_F32LSB":33056,"_SC_COLL_WEIGHTS_MAX":40,"SO_ERROR":4,"ECONNRESET":104,"AT_SYMLINK_NOFOLLOW":256,"_SC_TRACE_LOG":184,"AUDIO_U16LSB":16,"ESTRPIPE":86,"EMSCRIPTEN_FETCH_REPLACE":16,"ESHUTDOWN":108,"_PC_SOCK_MAXBUF":12,"_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS":1129,"EDEADLK":35,"_CS_POSIX_V6_ILP32_OFF32_CFLAGS":1116,"EBADRQC":56,"EM_FUNC_SIG_III":603979776,"_SC_THREAD_DESTRUCTOR_ITERATIONS":73,"_SC_TYPED_MEMORY_OBJECTS":165,"_SC_TRACE_EVENT_NAME_MAX":242,"_SC_BC_STRING_MAX":39,"_SC_2_SW_DEV":51,"FP_NAN":0,"F_SETOWN":8,"EMSCRIPTEN_EVENT_RESIZE":10,"_SC_ARG_MAX":0,"_SC_THREAD_PRIORITY_SCHEDULING":79,"F_GETLK":12,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF":2,"FIONREAD":21531,"_SC_THREAD_CPUTIME":139,"EMSCRIPTEN_EVENT_POINTERLOCKCHANGE":20,"EM_THREAD_STATUS_NOTSTARTED":0,"_CS_POSIX_V6_ILP32_OFF32_LIBS":1118,"EUNATCH":49,"AUDIO_S8":32776,"EMSCRIPTEN_EVENT_GAMEPADDISCONNECTED":27,"SDL_AUDIO_MASK_BITSIZE":255,"EMSCRIPTEN_WEBGL_CONTEXT_PROXY_ALWAYS":2,"AUDIO_F32MSB":37152,"_CS_POSIX_V6_LP64_OFF64_LDFLAGS":1125,"FP_INFINITE":1,"ECHILD":10,"EAI_MEMORY":-10,"O_TRUNC":512,"ETIMEDOUT":110,"S_IRWXO":7,"_SC_SYMLOOP_MAX":173,"EM_FUNC_SIG_I":536870912,"ENXIO":6,"NI_NUMERICHOST":1,"EMFILE":24,"F_GETOWN":9,"TIME_UTC":1,"EMLINK":31,"F_SETFD":2,"ENFILE":23,"EBADMSG":74,"EM_FUNC_SIG_V":0,"SDL_MAJOR_VERSION":1,"ENOMEM":12,"ENOSR":63,"SDL_AUDIO_ALLOW_ANY_CHANGE":7,"VR_POSE_ANGULAR_ACCELERATION":32,"_SC_CLOCK_SELECTION":137,"_PC_PRIO_IO":11,"ELIBSCN":81,"_SC_V6_LPBIG_OFFBIG":179,"EMSCRIPTEN_EVENT_CLICK":4,"EPIPE":32,"_SC_EXPR_NEST_MAX":42,"_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS":1120,"EBADSLT":57,"AUDIO_S16MSB":36880,"S_ISVTX":512,"EM_PROXIED_CREATE_CONTEXT":622854144,"EMSCRIPTEN_RESULT_UNKNOWN_TARGET":-4,"S_IRWXUGO":511,"_CS_GNU_LIBPTHREAD_VERSION":3,"_PC_REC_MAX_XFER_SIZE":15,"UUID_VARIANT_OTHER":3,"EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED":32,"EM_PROXIED_PTHREAD_CREATE":687865856,"EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT":0,"RADIXCHAR":65536,"AF_UNSPEC":0,"ENOSTR":60,"W_OK":2,"AUDIO_S32":32800,"EACCES":13,"R_OK":4,"EM_HTML5_MEDIUM_STRING_LEN_BYTES":64,"EMSCRIPTEN_EVENT_MOUSEOUT":36,"EMSCRIPTEN_EVENT_FULLSCREENCHANGE":19,"EIO":5,"EMSCRIPTEN_RESULT_NOT_SUPPORTED":-1,"_SC_SIGQUEUE_MAX":34,"EWOULDBLOCK":11,"AUDIO_U16SYS":16,"EMSCRIPTEN_EVENT_FOCUSOUT":15,"EAI_OVERFLOW":-12,"SDL_AUDIO_MASK_DATATYPE":256,"MAP_PRIVATE":2,"_SC_TZNAME_MAX":6,"_CS_PATH":0,"SEEK_SET":0,"EAI_SOCKTYPE":-7,"EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED":-2,"INT_MAX":2147483647,"EMSCRIPTEN_EVENT_KEYDOWN":2,"EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH":1,"_SC_MESSAGE_PASSING":20,"_SC_THREAD_SAFE_FUNCTIONS":68,"ENODATA":61,"_PC_NAME_MAX":3,"O_EXCL":128,"_SC_TRACE_USER_EVENT_MAX":245,"_PC_REC_XFER_ALIGN":17,"EM_FUNC_SIG_VII":67108864,"VR_EYE_LEFT":0,"_SC_RAW_SOCKETS":236,"_SC_2_UPE":97,"EMSCRIPTEN_RESULT_NO_DATA":-7,"EMSCRIPTEN_EVENT_BLUR":12,"_SC_TTY_NAME_MAX":72,"_SC_RTSIG_MAX":31,"ESOCKTNOSUPPORT":94,"_SC_PRIORITIZED_IO":13,"_SC_XOPEN_UNIX":91,"CODESET":14,"IPPROTO_TCP":6,"_PC_REC_INCR_XFER_SIZE":14,"F_SETLK":13,"_PC_FILESIZEBITS":13,"_SC_XBS5_ILP32_OFF32":125,"RAND_MAX":2147483647,"EM_PROXIED_SYSCALL":621805568,"ENOLCK":37,"EMSCRIPTEN_EVENT_TARGET_INVALID":0,"AUDIO_U16":16,"EMSCRIPTEN_EVENT_MOUSELEAVE":34,"VR_POSE_ORIENTATION":8,"_PC_SYNC_IO":9,"EEXIST":17,"FP_NORMAL":4,"O_RDONLY":0,"_SC_SEM_NSEMS_MAX":32,"_SC_IOV_MAX":60,"EPROTO":71,"_SC_TRACE":181,"ESRMNT":69,"EM_HTML5_LONG_STRING_LEN_BYTES":128,"_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS":1121,"EM_PROXIED_RESIZE_OFFSCREENCANVAS":657457152,"INADDR_LOOPBACK":2130706433,"EM_FUNC_SIG_VIII":100663296,"EXDEV":18,"TIOCGWINSZ":21523,"EM_THREAD_STATUS_RUNNING":1,"EMSCRIPTEN_EVENT_BEFOREUNLOAD":28,"EM_THREAD_STATUS_WAITFUTEX":3,"EMSCRIPTEN_RESULT_INVALID_TARGET":-3,"_SC_THREAD_SPORADIC_SERVER":161,"F_SETFL":4,"AI_PASSIVE":1,"EMSCRIPTEN_FETCH_STREAM_DATA":2,"ELIBBAD":80,"_SC_LINE_MAX":43,"D_T_FMT":131112,"TCSETSF":21508,"ERANGE":34,"ESTALE":116,"TCSETSW":21507,"F_DUPFD":0,"AUDIO_F32":33056,"CLOCK_MONOTONIC":1,"EMSCRIPTEN_EVENT_GAMEPADCONNECTED":26,"F_GETOWN_EX":16,"_SC_ASYNCHRONOUS_IO":12,"ENOTRECOVERABLE":131,"ENOBUFS":105,"EIDRM":43,"EMSCRIPTEN_EVENT_ORIENTATIONCHANGE":18,"CRNCYSTR":262159,"EINTR":4,"EADV":68,"ENOSYS":38,"_CS_POSIX_V6_ILP32_OFFBIG_LIBS":1122,"F_GETFL":3,"S_IXUGO":73,"_SC_2_FORT_DEV":49,"SDL_COMPILEDVERSION":1300,"EUSERS":87,"CLOCK_REALTIME":0,"ENODEV":19,"O_DSYNC":4096,"_SC_ATEXIT_MAX":87,"_SC_SAVED_IDS":8,"SOL_SOCKET":1,"S_IFLNK":40960,"AUDIO_S16LSB":32784,"POLLNVAL":32,"EMSCRIPTEN_EVENT_TOUCHCANCEL":25,"EMSCRIPTEN_RESULT_INVALID_PARAM":-5,"EMSCRIPTEN_EVENT_MOUSEDOWN":5,"EM_THREAD_STATUS_SLEEPING":2,"_SC_JOB_CONTROL":7,"NI_NAMEREQD":8,"EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT":2,"EMSCRIPTEN_EVENT_MOUSEMOVE":8,"UUID_TYPE_DCE_RANDOM":4,"ENOTCONN":107,"_SC_ADVISORY_INFO":132,"ENETUNREACH":101,"_SC_XOPEN_REALTIME_THREADS":131,"TCGETS":21505,"_SC_2_LOCALEDEF":52,"_PC_SYMLINK_MAX":19,"EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT":0,"X_OK":1,"EMSCRIPTEN_EVENT_KEYUP":3,"AI_CANONNAME":2,"UUID_VARIANT_NCS":0,"ESPIPE":29,"AUDIO_S32MSB":36896,"EMSCRIPTEN_EVENT_WHEEL":9,"SDL_AUDIO_ALLOW_CHANNELS_CHANGE":4,"_SC_XOPEN_REALTIME":130,"EL2HLT":51,"TCSETAW":21511,"EMSCRIPTEN_FETCH_NO_DOWNLOAD":32,"EAI_NONAME":-2,"_PC_PIPE_BUF":5,"EOWNERDEAD":130,"EROFS":30,"TCSETAF":21512,"ECONNREFUSED":111,"_SC_2_PBS_ACCOUNTING":169,"EMSCRIPTEN_EVENT_FOCUS":13,"AUDIO_S16SYS":32784,"ENETDOWN":100,"ENOEXEC":8,"EMSCRIPTEN_EVENT_TARGET_DOCUMENT":1,"ENOSPC":28,"EBADF":9,"EBADE":52,"EMSCRIPTEN_EVENT_DBLCLICK":7,"EDOTDOT":73,"_SC_THREAD_ATTR_STACKSIZE":78,"EBADFD":77,"O_ACCMODE":2097155,"EBADR":53,"_SC_2_VERSION":46,"S_IFCHR":8192,"SDL_PATCHLEVEL":0,"ABMON_12":131097,"PTHREAD_KEYS_MAX":128,"EISCONN":106,"EMSCRIPTEN_FETCH_APPEND":8,"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE":0,"AUDIO_U16MSB":4112,"EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR":2,"_SC_2_CHAR_TERM":95,"EMSCRIPTEN_EVENT_TOUCHEND":23,"_SC_AIO_LISTIO_MAX":23,"EMSCRIPTEN_FETCH_PERSIST_FILE":4,"_SC_BC_SCALE_MAX":38,"ENOTBLK":15,"EAI_BADFLAGS":-1,"EOVERFLOW":75,"EM_FUNC_SIG_VI":33554432,"SDL_AUDIO_MASK_SIGNED":32768,"EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST":1,"ABMON_11":131096,"ABMON_10":131095,"AT_FDCWD":-100,"EM_HTML5_SHORT_STRING_LEN_BYTES":32}}
\ No newline at end of file
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/libc-wasm.bc b/tools/cpp/emscripten/emscripten_cache/asmjs/libc-wasm.bc
new file mode 100644
index 0000000..50f7172
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/libc-wasm.bc
Binary files differ
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/libc.bc b/tools/cpp/emscripten/emscripten_cache/asmjs/libc.bc
new file mode 100644
index 0000000..7f4adf9
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/libc.bc
Binary files differ
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/libcompiler_rt.a b/tools/cpp/emscripten/emscripten_cache/asmjs/libcompiler_rt.a
new file mode 100644
index 0000000..9468549
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/libcompiler_rt.a
Binary files differ
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/libdlmalloc.bc b/tools/cpp/emscripten/emscripten_cache/asmjs/libdlmalloc.bc
new file mode 100644
index 0000000..def54c3
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/libdlmalloc.bc
Binary files differ
diff --git a/tools/cpp/emscripten/emscripten_cache/asmjs/libpthreads_stub.bc b/tools/cpp/emscripten/emscripten_cache/asmjs/libpthreads_stub.bc
new file mode 100644
index 0000000..b5205d0
--- /dev/null
+++ b/tools/cpp/emscripten/emscripten_cache/asmjs/libpthreads_stub.bc
Binary files differ
diff --git a/tools/cpp/static_crosstool.pb b/tools/cpp/static_crosstool.pb
index 5599c15..6914825 100644
--- a/tools/cpp/static_crosstool.pb
+++ b/tools/cpp/static_crosstool.pb
@@ -18,6 +18,11 @@
}
default_toolchain {
+ cpu: "web"
+ toolchain_identifier: "emscripten_toolchain"
+}
+
+default_toolchain {
cpu: "armhf-debian"
toolchain_identifier: "clang_linux_armhf"
}
@@ -323,6 +328,166 @@
}
toolchain {
+ # This toolchain was initially sourced from https://github.com/ribrdb/rules_emscripten
+ toolchain_identifier: "emscripten_toolchain"
+ host_system_name: "web"
+ target_system_name: "emscripten-unknown-emscripten"
+ target_cpu: "web"
+ target_libc: "unknown"
+ compiler: "emscripten"
+ abi_version: "unknown"
+ abi_libc_version: "unknown"
+ tool_path {
+ name: "gcc"
+ path: "emscripten/emcc.sh"
+ }
+ tool_path {
+ name: "ld"
+ path: "emscripten/emcc.sh"
+ }
+ tool_path {
+ name: "ar"
+ path: "emscripten/emar.sh"
+ }
+ tool_path {
+ name: "cpp"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "gcov"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "nm"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "objdump"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "objcopy"
+ path: "/bin/false"
+ }
+ tool_path {
+ name: "strip"
+ path: "/bin/false"
+ }
+
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/libcxx"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/lib/libcxxabi/include"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/compat"
+ compiler_flag: "-isystem"
+ compiler_flag: "external/emscripten_toolchain/system/include"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/SSE"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/include/libc"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/lib/libc/musl/arch/emscripten"
+ unfiltered_cxx_flag: "-isystem"
+ unfiltered_cxx_flag: "external/emscripten_toolchain/system/local/include"
+
+ # Turn off exceptions since emscripten has issues catching them
+ compiler_flag: "-fno-exceptions"
+
+ unfiltered_cxx_flag: "-no-canonical-prefixes"
+ linker_flag: "-no-canonical-prefixes"
+
+ # Make C++ compilation deterministic. Use linkstamping instead of these
+ # compiler symbols.
+ unfiltered_cxx_flag: "-Wno-builtin-macro-redefined"
+ unfiltered_cxx_flag: "-D__DATE__=\"redacted\""
+ unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\""
+ unfiltered_cxx_flag: "-D__TIME__=\"redacted\""
+ # Enable coloring even if there's no attached terminal. Bazel removes the
+ # escape sequences if --nocolor is specified.
+ compiler_flag: "-fdiagnostics-color=always"
+ compiler_flag: "-Wall"
+ compiler_flag: "-Werror"
+
+ compiler_flag: "-ffunction-sections"
+ compiler_flag: "-fdata-sections"
+
+ feature {
+ name: "opt"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=0"
+ flag: "-O2"
+ flag: "--closure"
+ flag: "1"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "dbg"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=1"
+ }
+ flag_group {
+ flag: "-fno-omit-frame-pointer"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "fastbuild"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "c-compile"
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-DAOS_DEBUG=0"
+ }
+ }
+ implies: "all_modes"
+ }
+ feature {
+ name: "all_modes"
+ flag_set {
+ action: "preprocess-assemble"
+ action: "assemble"
+ action: "c-compile"
+ flag_group {
+ flag: "-std=gnu99"
+ }
+ }
+ flag_set {
+ action: "c++-compile"
+ action: "c++-header-parsing"
+ action: "c++-header-preprocessing"
+ action: "c++-module-compile"
+ flag_group {
+ flag: "-std=gnu++1y"
+ }
+ }
+ }
+}
+
+toolchain {
toolchain_identifier: "roborio_linux"
host_system_name: "roborio"
target_system_name: "roborio"