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/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"