Build emscripten caches in sandbox

This makes it so that we actually build the various standard
library-like things built within the sandbox rather than being some
random files that I generate ad-hoc and copy into the correct folder.

This requires patching emcc so that it adds the necessary -isystem flags
when building those libraries.

Change-Id: I7b71b36cbbafd511df5d7a8396794aeee2403a05
diff --git a/build_tests/BUILD b/build_tests/BUILD
index 7d30723..07b84fe 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -8,6 +8,22 @@
     srcs = ["helloworld.cc"],
 )
 
+emcc_binary(
+    name = "webgl.html",
+    srcs = ["webgl_draw_triangle.c"],
+)
+
+emcc_binary(
+    name = "webgl2.html",
+    srcs = ["webgl2_draw_packed_triangle.c"],
+    # Enable WEBGL2 (-s is used by the emscripten
+    # compiler to specify sundry options).
+    linkopts = [
+        "-s",
+        "USE_WEBGL2=1",
+    ],
+)
+
 cc_test(
     name = "gflags_build_test",
     size = "small",
diff --git a/build_tests/webgl2_draw_packed_triangle.c b/build_tests/webgl2_draw_packed_triangle.c
new file mode 100644
index 0000000..5dd74d7
--- /dev/null
+++ b/build_tests/webgl2_draw_packed_triangle.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018 The Emscripten Authors.  All rights reserved.
+ * Emscripten is available under two separate licenses, the MIT license and the
+ * University of Illinois/NCSA Open Source License.  Both these licenses can be
+ * found in the LICENSE file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <emscripten/emscripten.h>
+#include <emscripten/html5.h>
+#include <GLES3/gl3.h>
+
+GLuint compile_shader(GLenum shaderType, const char *src)
+{
+  GLuint shader = glCreateShader(shaderType);
+  glShaderSource(shader, 1, &src, NULL);
+  glCompileShader(shader);
+
+  GLint isCompiled = 0;
+  glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
+  if (!isCompiled)
+  {
+    GLint maxLength = 0;
+    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
+    char *buf = (char*)malloc(maxLength+1);
+    glGetShaderInfoLog(shader, maxLength, &maxLength, buf);
+    printf("%s\n", buf);
+    free(buf);
+    return 0;
+  }
+
+   return shader;
+}
+
+GLuint create_program(GLuint vertexShader, GLuint fragmentShader)
+{
+   GLuint program = glCreateProgram();
+   glAttachShader(program, vertexShader);
+   glAttachShader(program, fragmentShader);
+   glBindAttribLocation(program, 0, "apos");
+   glBindAttribLocation(program, 1, "acolor");
+   glLinkProgram(program);
+   return program;
+}
+
+int main()
+{
+  EmscriptenWebGLContextAttributes attr;
+  emscripten_webgl_init_context_attributes(&attr);
+#ifdef EXPLICIT_SWAP
+  attr.explicitSwapControl = 1;
+#endif
+  attr.majorVersion = 2;
+  EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context("#canvas", &attr);
+  assert(ctx && "Failed to create WebGL2 context");
+  emscripten_webgl_make_context_current(ctx);
+
+  static const char vertex_shader[] =
+    "#version 100\n"
+    "attribute vec4 apos;"
+    "attribute vec4 acolor;"
+    "varying vec4 color;"
+    "void main() {"
+      "color = acolor;"
+      "gl_Position = apos;"
+    "}";
+  GLuint vs = compile_shader(GL_VERTEX_SHADER, vertex_shader);
+
+  static const char fragment_shader[] =
+    "#version 100\n"
+    "precision lowp float;"
+    "varying vec4 color;"
+    "void main() {"
+      "gl_FragColor = color;"
+    "}";
+  GLuint fs = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);
+
+  GLuint program = create_program(vs, fs);
+  glUseProgram(program);
+
+  static const uint32_t pos_and_color[] = {
+  //  1,0,y,x,    a,b,g,r
+    0x400b36cd, 0xc00003ff,
+    0x400b3533, 0xc00ffc00,
+    0x4004cc00, 0xfff00000,
+  };
+
+  GLuint vbo;
+  glGenBuffers(1, &vbo);
+  glBindBuffer(GL_ARRAY_BUFFER, vbo);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(pos_and_color), pos_and_color, GL_STATIC_DRAW);
+  glVertexAttribPointer(0, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 8, 0);
+//  printf("%d\n", glGetError());
+#if 0
+  switch (glGetError()) {
+    case GL_NO_ERROR:
+      std::cout << "No error!";
+      break;
+    case GL_INVALID_ENUM:
+      std::cout << "Invliad enum.";
+      break;
+  }
+#endif
+  assert(glGetError() == GL_NO_ERROR && "glVertexAttribPointer with GL_INT_2_10_10_10_REV failed");
+  glVertexAttribPointer(1, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 8, (void*)4);
+  assert(glGetError() == GL_NO_ERROR && "glVertexAttribPointer with GL_UNSIGNED_INT_2_10_10_10_REV failed");
+
+  glEnableVertexAttribArray(0);
+  glEnableVertexAttribArray(1);
+
+  glClearColor(0.3f,0.3f,0.3f,1);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glDrawArrays(GL_TRIANGLES, 0, 3);
+
+#ifdef EXPLICIT_SWAP
+  emscripten_webgl_commit_frame();
+#endif
+
+#ifdef REPORT_RESULT
+  REPORT_RESULT(0);
+#endif
+}
diff --git a/build_tests/webgl_draw_triangle.c b/build_tests/webgl_draw_triangle.c
new file mode 100644
index 0000000..be88173
--- /dev/null
+++ b/build_tests/webgl_draw_triangle.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 The Emscripten Authors.  All rights reserved.
+ * Emscripten is available under two separate licenses, the MIT license and the
+ * University of Illinois/NCSA Open Source License.  Both these licenses can be
+ * found in the LICENSE file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <emscripten/emscripten.h>
+#include <emscripten/html5.h>
+#include <GLES2/gl2.h>
+
+GLuint compile_shader(GLenum shaderType, const char *src)
+{
+  GLuint shader = glCreateShader(shaderType);
+  glShaderSource(shader, 1, &src, NULL);
+  glCompileShader(shader);
+
+  GLint isCompiled = 0;
+  glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
+  if (!isCompiled)
+  {
+    GLint maxLength = 0;
+    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
+    char *buf = (char*)malloc(maxLength+1);
+    glGetShaderInfoLog(shader, maxLength, &maxLength, buf);
+    printf("%s\n", buf);
+    free(buf);
+    return 0;
+  }
+
+   return shader;
+}
+
+GLuint create_program(GLuint vertexShader, GLuint fragmentShader)
+{
+   GLuint program = glCreateProgram();
+   glAttachShader(program, vertexShader);
+   glAttachShader(program, fragmentShader);
+   glBindAttribLocation(program, 0, "apos");
+   glBindAttribLocation(program, 1, "acolor");
+   glLinkProgram(program);
+   return program;
+}
+
+int main()
+{
+  EmscriptenWebGLContextAttributes attr;
+  emscripten_webgl_init_context_attributes(&attr);
+#ifdef EXPLICIT_SWAP
+  attr.explicitSwapControl = 1;
+#endif
+#ifdef DRAW_FROM_CLIENT_MEMORY
+  // This test verifies that drawing from client-side memory when enableExtensionsByDefault==false works.
+  attr.enableExtensionsByDefault = 0;
+#endif
+
+  EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context("#canvas", &attr);
+  emscripten_webgl_make_context_current(ctx);
+
+  static const char vertex_shader[] =
+    "attribute vec4 apos;"
+    "attribute vec4 acolor;"
+    "varying vec4 color;"
+    "void main() {"
+      "color = acolor;"
+      "gl_Position = apos;"
+    "}";
+  GLuint vs = compile_shader(GL_VERTEX_SHADER, vertex_shader);
+
+  static const char fragment_shader[] =
+    "precision lowp float;"
+    "varying vec4 color;"
+    "void main() {"
+      "gl_FragColor = color;"
+    "}";
+  GLuint fs = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);
+
+  GLuint program = create_program(vs, fs);
+  glUseProgram(program);
+
+  static const float pos_and_color[] = {
+  //     x,     y, r, g, b
+     -0.6f, -0.6f, 1, 0, 0,
+      0.6f, -0.6f, 0, 1, 0,
+      0.f,   0.6f, 0, 0, 1,
+  };
+
+#ifdef DRAW_FROM_CLIENT_MEMORY
+  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 20, pos_and_color);
+  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 20, (void*)(pos_and_color+2));
+#else
+  GLuint vbo;
+  glGenBuffers(1, &vbo);
+  glBindBuffer(GL_ARRAY_BUFFER, vbo);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(pos_and_color), pos_and_color, GL_STATIC_DRAW);
+  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 20, 0);
+  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8);
+#endif
+  glEnableVertexAttribArray(0);
+  glEnableVertexAttribArray(1);
+
+  glClearColor(0.3f,0.3f,0.3f,1);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glDrawArrays(GL_TRIANGLES, 0, 3);
+
+#ifdef EXPLICIT_SWAP
+  emscripten_webgl_commit_frame();
+#endif
+
+#ifdef REPORT_RESULT
+  REPORT_RESULT(0);
+#endif
+}