Merge remote-tracking branch 'aosp/upstream-master' into update-shaderc

Includes:
c607253 Avoid -fPIC for MinGW builds
1927f30 Allow override of SPVTOOLS_LOCAL_PATH
bcadbc1 Move spirv-tools build from third_party/Android.mk
3fde660 Update CHANGES
c815335 Adapt to Glslang generator version number change
259ca18 Travis CI: use make to build
16f8253 Add HLSL legalization passes to compiler.cc
e089609 Add SPIRV-Tools optimizer files for linker
84c9dd9 Added more opt passes to PassId enum
b58a21a Fix typos in README.md
5c4fd69 Allow SPIRV-Headers to be checked out at third_party/
c677f26 Include SPIRV-Tools before glslang
8aa64c6 Appveyor: stop downloading pip
c8ba3e4 Check _WIN32 instead of WIN32 for building shared library
00c9fe4 Appveyor: Stop deploying to BinTray
97e0e13 Appveyor: deploy to BinTray instead of GitHub Release page
0b99bfa Serialize inclusions by the CountingIncluder
4cdf49e Fix the build by changing deploy repo
6db3870 Deploy Appveyor build artifacts to GitHub Releases
7ad5b69 SPIRV-Tools added source/validate_bitwise.cpp
4138101 SPIRV-Tools added source/opt/eliminate_dead_functions_pass.cpp
61eb9ff Android: Fix generation of 1.2 grammar tables
c77e1e9 SPIRV-Tools added source/validate_logicals.cpp
eadd549 SPIRV-Tools added source/opt/strength_reduction_pass.cpp
c56b7dc Add shared library variant for libshaderc
777c9ff SPIRV-Tools added validate_arithmetics.cpp

Test: checkbuild.py on Linux; unit tests on Windows
Change-Id: Iea56c8d560ce09a38f03a89067629e47b40e1def
diff --git a/.appveyor.yml b/.appveyor.yml
index 2b903bb..14dfce6 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -14,7 +14,6 @@
 
 environment:
   PYTHON_PATH: "C:/Python27"
-  PYTHON_PACKAGE_PATH: "C:/Python27/Scripts"
 
 configuration:
   - Debug
@@ -26,16 +25,14 @@
 
 # scripts that are called at very beginning, before repo cloning
 init:
-  - ps: (new-object net.webclient).DownloadFile('https://bootstrap.pypa.io/get-pip.py', 'C:/get-pip.py')
-  - "%PYTHON_PATH%/python.exe C:/get-pip.py"
-  - "%PYTHON_PACKAGE_PATH%/pip.exe install nose"
+  - "%PYTHON_PATH%/Scripts/pip.exe install nose"
 
 # scripts that run after cloning repository
 install:
   - git clone https://github.com/google/googletest.git          third_party/googletest
   - git clone https://github.com/google/glslang.git             third_party/glslang
   - git clone https://github.com/KhronosGroup/SPIRV-Tools.git   third_party/spirv-tools
-  - git clone https://github.com/KhronosGroup/SPIRV-Headers.git third_party/spirv-tools/external/spirv-headers
+  - git clone https://github.com/KhronosGroup/SPIRV-Headers.git third_party/spirv-headers
 
 build:
   parallel: true  # enable MSBuild parallel builds
@@ -49,6 +46,25 @@
 test_script:
   - ctest -C %CONFIGURATION% --output-on-failure
 
+after_test:
+  # For debug build, the generated dll has a postfix "d" in its name.
+  - ps: >-
+      If ($env:configuration -Match "Debug") {
+        $env:SHADERC_DLL="shaderc_sharedd.dll"
+        $env:ZIP_FILENAME="shaderc-tot-windows-x64-debug.zip"
+      } Else {
+        $env:SHADERC_DLL="shaderc_shared.dll"
+        $env:ZIP_FILENAME="shaderc-tot-windows-x64-release.zip"
+      }
+  - cp libshaderc\%CONFIGURATION%\%SHADERC_DLL% install\lib\
+  - cd install
+  - 7z a %ZIP_FILENAME% bin\glslc.exe include\shaderc\* lib\shaderc_combined.lib lib\%SHADERC_DLL%
+
+artifacts:
+  - path: build\install\$(ZIP_FILENAME)
+    name: shaderc-artifacts
+  - path: build\install\bin\glslc.exe
+
 notifications:
   - provider: Email
     to:
diff --git a/.gitignore b/.gitignore
index 58aafa4..eac7e02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,5 +8,6 @@
 third_party/glslang/
 third_party/googletest/
 third_party/spirv-tools/
+third_party/spirv-headers/
 android_test/libs
 .DS_Store
diff --git a/.travis.yml b/.travis.yml
index 82e4ad7..cc98c66 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,12 +44,9 @@
   apt:
     packages:
       - clang-3.6
-      - ninja-build
       - lcov
 
 before_install:
-  # Install ninja on macOS.
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja; fi
   - if [[ "$BUILD_NDK" == "ON" ]]; then
       git clone --depth=1 https://github.com/urho3d/android-ndk.git $HOME/android-ndk;
       export ANDROID_NDK=$HOME/android-ndk;
@@ -71,7 +68,7 @@
   - git clone --depth=1 https://github.com/google/googletest          third_party/googletest
   - git clone --depth=1 https://github.com/google/glslang             third_party/glslang
   - git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Tools   third_party/spirv-tools
-  - git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers third_party/spirv-tools/external/spirv-headers
+  - git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers third_party/spirv-headers
 
 script:
   - mkdir build && cd build
@@ -80,19 +77,17 @@
             -DANDROID_NATIVE_API_LEVEL=android-9
             -DCMAKE_BUILD_TYPE=Release
             -DANDROID_ABI="armeabi-v7a with NEON"
-            -DSHADERC_SKIP_TESTS=ON
-            -GNinja ..;
+            -DSHADERC_SKIP_TESTS=ON ..;
     else
       cmake -DCMAKE_BUILD_TYPE=${SHADERC_BUILD_TYPE:-Debug}
-            -DENABLE_CODE_COVERAGE=${SHADERC_CODE_COVERAGE:-OFF}
-            -GNinja ..;
+            -DENABLE_CODE_COVERAGE=${SHADERC_CODE_COVERAGE:-OFF} ..;
     fi
-  - ninja
   - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
       export NPROC=`nproc`;
     else
       export NPROC=`sysctl -n hw.ncpu`;
     fi
+  - make -j${NPROC}
   - if [[ "$BUILD_NDK" != "ON" ]]; then ctest -j${NPROC} --output-on-failure; fi
 
 after_success:
diff --git a/CHANGES b/CHANGES
index a5bf028..eda9691 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
 Revision history for Shaderc
 
 v2017.2-dev 2017-03-10
+ - Add a shared library version of libshaderc
  - Support GLSL 4.6 and ESSL 3.2
  - Add options for automatically set bindings for (uniform) resources that
    don't have bindings set in shader source.
@@ -9,6 +10,10 @@
  - Add option to use HLSL resource register numbers for bindings.
  - HLSL compilation now defaults to HLSL packing rules.
    (This change is inherited from Glslang commit 7cca140.)
+ - HLSL compilation runs SPIR-V "legalization" transforms to reduce
+   manipulation of opaque handles (e.g. images), to satisfy Vulkan rules.
+ - Adapt to Glslang generator version number update to 2, to indicate
+   a fix for code generation for atomicCounterDecrement.
  - CMake install rules uses GNUInstallDirs.  For example, install to lib64
    when that is the norm for the target system.
 
diff --git a/README.md b/README.md
index 5cf81e0..cb4b41d 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,10 @@
 
 ## Getting and building Shaderc
 
+**Experimental:** On Windows, instead of building from source, you can get the
+artifacts built by [Appveyor][appveyor] for the top of the tree of the master
+branch under the "Artifacts" tab of a certain job.
+
 1) Check out the source code:
 
 ```sh
@@ -79,7 +83,7 @@
 git clone https://github.com/google/googletest.git
 git clone https://github.com/google/glslang.git
 git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
-git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
+git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers
 cd $SOURCE_DIR/
 ```
 
@@ -171,7 +175,7 @@
 
 Optionally, the following tools may be installed on any OS:
 
- - [`asciidoctor`](http://asciidoctor.org/): for generating documenation.
+ - [`asciidoctor`](http://asciidoctor.org/): for generating documentation.
    - [`pygments.rb`](https://rubygems.org/gems/pygments.rb) required by
      `asciidoctor` for syntax highlighting.
  - [`nosetests`](https://nose.readthedocs.io): for testing the Python code.
@@ -184,7 +188,7 @@
 To create a Docker image containing Shaderc command line tools, issue the
 following command in `${SOURCE_DIR}`: `docker build -t <IMAGE-NAME> .`.
 The created image will have all the command line tools installed at
-`/usr/local` interally, and a data volume mounted at `/code`.
+`/usr/local` internally, and a data volume mounted at `/code`.
 
 Assume `<IMAGE-NAME>` is `shaderc/shaderc` from now on.
 
@@ -238,3 +242,4 @@
 [spirv-tools]: https://github.com/KhronosGroup/SPIRV-Tools
 [pyshaderc]: https://github.com/realitix/pyshaderc
 [shaderc-rs]: https://github.com/google/shaderc-rs
+[appveyor]: https://ci.appveyor.com/project/dneto0/shaderc
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index 95b4993..ed3c733 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -9,7 +9,10 @@
 
 function(shaderc_default_c_compile_options TARGET)
   if (NOT "${MSVC}")
-    target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+    target_compile_options(${TARGET} PRIVATE -Wall -Werror -fvisibility=hidden)
+    if (NOT "${MINGW}")
+      target_compile_options(${TARGET} PRIVATE -fPIC)
+    endif()
     if (ENABLE_CODE_COVERAGE)
       # The --coverage option is a synonym for -fprofile-arcs -ftest-coverage
       # when compiling.
diff --git a/glslc/test/assembly.py b/glslc/test/assembly.py
index aad9e6d..54b9dce 100644
--- a/glslc/test/assembly.py
+++ b/glslc/test/assembly.py
@@ -21,7 +21,7 @@
     return """
     ; SPIR-V
     ; Version: 1.0
-    ; Generator: Google Shaderc over Glslang; 1
+    ; Generator: Google Shaderc over Glslang; 2
     ; Bound: 6
     ; Schema: 0"""
 
diff --git a/glslc/test/expect.py b/glslc/test/expect.py
index 1909b4f..690dd87 100644
--- a/glslc/test/expect.py
+++ b/glslc/test/expect.py
@@ -167,7 +167,7 @@
                 return False, 'Incorrect SPV binary: wrong version number'
             # Shaderc-over-Glslang (0x000d....) or
             # SPIRV-Tools (0x0007....) generator number
-            if read_word(preamble, 2, little_endian) != 0x000d0001 and \
+            if read_word(preamble, 2, little_endian) != 0x000d0002 and \
                     read_word(preamble, 2, little_endian) != 0x00070000:
                 return False, ('Incorrect SPV binary: wrong generator magic '
                                'number')
@@ -193,7 +193,7 @@
 
         if (line1 != '; SPIR-V\n' or
             line2 != '; Version: 1.0\n' or
-            line3 != '; Generator: Google Shaderc over Glslang; 1\n'):
+            line3 != '; Generator: Google Shaderc over Glslang; 2\n'):
             return False, 'Incorrect SPV assembly'
 
         return True, ''
diff --git a/glslc/test/option_dash_cap_O.py b/glslc/test/option_dash_cap_O.py
index f990daa..2a5c0cf 100644
--- a/glslc/test/option_dash_cap_O.py
+++ b/glslc/test/option_dash_cap_O.py
@@ -23,7 +23,7 @@
 ASSEMBLY_WITH_DEBUG = [
     '; SPIR-V\n',
     '; Version: 1.0\n',
-    '; Generator: Google Shaderc over Glslang; 1\n',
+    '; Generator: Google Shaderc over Glslang; 2\n',
     '; Bound: 6\n',
     '; Schema: 0\n',
     '               OpCapability Shader\n',
@@ -44,7 +44,7 @@
 ASSEMBLY_WITHOUT_DEBUG = [
     '; SPIR-V\n',
     '; Version: 1.0\n',
-    '; Generator: Google Shaderc over Glslang; 1\n',
+    '; Generator: Google Shaderc over Glslang; 2\n',
     '; Bound: 6\n',
     '; Schema: 0\n',
     '               OpCapability Shader\n',
diff --git a/libshaderc/CMakeLists.txt b/libshaderc/CMakeLists.txt
index 6b91fce..2a5372d 100644
--- a/libshaderc/CMakeLists.txt
+++ b/libshaderc/CMakeLists.txt
@@ -3,16 +3,25 @@
 # Even though shaderc.hpp is a headers-only library, adding
 # a dependency here will force clients of the library to rebuild
 # when it changes.
-add_library(shaderc STATIC
+set(SHADERC_SOURCES
   include/shaderc/shaderc.h
   include/shaderc/shaderc.hpp
   src/shaderc.cc
   src/shaderc_private.h
 )
 
+add_library(shaderc STATIC ${SHADERC_SOURCES})
 shaderc_default_compile_options(shaderc)
 target_include_directories(shaderc PUBLIC include PRIVATE ${glslang_SOURCE_DIR})
 
+add_library(shaderc_shared SHARED ${SHADERC_SOURCES})
+shaderc_default_compile_options(shaderc_shared)
+target_include_directories(shaderc_shared PUBLIC include PRIVATE ${glslang_SOURCE_DIR})
+target_compile_definitions(shaderc_shared
+    PRIVATE SHADERC_IMPLEMENTATION
+    PUBLIC SHADERC_SHAREDLIB
+)
+
 if(SHADERC_ENABLE_INSTALL)
   install(
     FILES
@@ -21,19 +30,21 @@
     DESTINATION
       ${CMAKE_INSTALL_INCLUDEDIR}/shaderc)
 
-  install(TARGETS shaderc
+  install(TARGETS shaderc shaderc_shared
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 endif(SHADERC_ENABLE_INSTALL)
 
-
 find_package(Threads)
-target_link_libraries(shaderc PRIVATE
-  glslang OSDependent OGLCompiler glslang ${CMAKE_THREAD_LIBS_INIT})
-target_link_libraries(shaderc PRIVATE shaderc_util)
-target_link_libraries(shaderc PRIVATE SPIRV)  # from glslang
-target_link_libraries(shaderc PRIVATE SPIRV-Tools)
+set(SHADERC_LIBS
+  glslang OSDependent OGLCompiler glslang ${CMAKE_THREAD_LIBS_INIT}
+  shaderc_util
+  SPIRV # from glslang
+  SPIRV-Tools
+)
 
+target_link_libraries(shaderc PRIVATE ${SHADERC_LIBS})
+target_link_libraries(shaderc_shared PRIVATE ${SHADERC_LIBS})
 
 shaderc_add_tests(
   TEST_PREFIX shaderc
@@ -45,6 +56,15 @@
     shaderc_cpp
     shaderc_private)
 
+shaderc_add_tests(
+  TEST_PREFIX shaderc_shared
+  LINK_LIBS shaderc_shared SPIRV-Tools
+  INCLUDE_DIRS include ${shaderc_SOURCE_DIR}/libshaderc_util/include ${glslang_SOURCE_DIR}
+               ${spirv-tools_SOURCE_DIR}/include
+  TEST_NAMES
+    shaderc
+    shaderc_cpp
+    shaderc_private)
 
 shaderc_combine_static_lib(shaderc_combined shaderc)
 
diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/shaderc.h
index 9e31e8b..d24e67d 100644
--- a/libshaderc/include/shaderc/shaderc.h
+++ b/libshaderc/include/shaderc/shaderc.h
@@ -23,6 +23,25 @@
 #include <stddef.h>
 #include <stdint.h>
 
+// SHADERC_EXPORT tags symbol that will be exposed by the shared library.
+#if defined(SHADERC_SHAREDLIB)
+    #if defined(_WIN32)
+        #if defined(SHADERC_IMPLEMENTATION)
+            #define SHADERC_EXPORT __declspec(dllexport)
+        #else
+            #define SHADERC_EXPORT __declspec(dllimport)
+        #endif
+    #else
+        #if defined(SHADERC_IMPLEMENTATION)
+            #define SHADERC_EXPORT __attribute__((visibility("default")))
+        #else
+            #define SHADERC_EXPORT
+        #endif
+    #endif
+#else
+    #define SHADERC_EXPORT
+#endif
+
 // Source language kind.
 typedef enum {
   shaderc_source_language_glsl,
@@ -235,12 +254,12 @@
 // no synchronization; concurrent invocation of these functions on the SAME
 // object requires synchronization IF AND ONLY IF some of them take a non-const
 // argument.
-shaderc_compiler_t shaderc_compiler_initialize(void);
+SHADERC_EXPORT shaderc_compiler_t shaderc_compiler_initialize(void);
 
 // Releases the resources held by the shaderc_compiler_t.
 // After this call it is invalid to make any future calls to functions
 // involving this shaderc_compiler_t.
-void shaderc_compiler_release(shaderc_compiler_t);
+SHADERC_EXPORT void shaderc_compiler_release(shaderc_compiler_t);
 
 // An opaque handle to an object that manages options to a single compilation
 // result.
@@ -251,18 +270,20 @@
 // A return of NULL indicates that there was an error initializing the options.
 // Any function operating on shaderc_compile_options_t must offer the
 // basic thread-safety guarantee.
-shaderc_compile_options_t shaderc_compile_options_initialize(void);
+SHADERC_EXPORT shaderc_compile_options_t
+    shaderc_compile_options_initialize(void);
 
 // Returns a copy of the given shaderc_compile_options_t.
 // If NULL is passed as the parameter the call is the same as
 // shaderc_compile_options_init.
-shaderc_compile_options_t shaderc_compile_options_clone(
+SHADERC_EXPORT shaderc_compile_options_t shaderc_compile_options_clone(
     const shaderc_compile_options_t options);
 
 // Releases the compilation options. It is invalid to use the given
 // shaderc_compile_options_t object in any future calls. It is safe to pass
 // NULL to this function, and doing such will have no effect.
-void shaderc_compile_options_release(shaderc_compile_options_t options);
+SHADERC_EXPORT void shaderc_compile_options_release(
+    shaderc_compile_options_t options);
 
 // Adds a predefined macro to the compilation options. This has the same
 // effect as passing -Dname=value to the command-line compiler.  If value
@@ -275,21 +296,21 @@
 // modified or deleted after this function has returned. In case of adding
 // a valueless macro, the value argument should be a null pointer or the
 // value_length should be 0u.
-void shaderc_compile_options_add_macro_definition(
+SHADERC_EXPORT void shaderc_compile_options_add_macro_definition(
     shaderc_compile_options_t options, const char* name, size_t name_length,
     const char* value, size_t value_length);
 
 // Sets the source language.  The default is GLSL.
-void shaderc_compile_options_set_source_language(
+SHADERC_EXPORT void shaderc_compile_options_set_source_language(
     shaderc_compile_options_t options, shaderc_source_language lang);
 
 // Sets the compiler mode to generate debug information in the output.
-void shaderc_compile_options_set_generate_debug_info(
+SHADERC_EXPORT void shaderc_compile_options_set_generate_debug_info(
     shaderc_compile_options_t options);
 
 // Sets the compiler optimization level to the given level. Only the last one
 // takes effect if multiple calls of this function exist.
-void shaderc_compile_options_set_optimization_level(
+SHADERC_EXPORT void shaderc_compile_options_set_optimization_level(
     shaderc_compile_options_t options, shaderc_optimization_level level);
 
 // Forces the GLSL language version and profile to a given pair. The version
@@ -297,7 +318,7 @@
 // Version and profile specified here overrides the #version annotation in the
 // source. Use profile: 'shaderc_profile_none' for GLSL versions that do not
 // define profiles, e.g. versions below 150.
-void shaderc_compile_options_set_forced_version_profile(
+SHADERC_EXPORT void shaderc_compile_options_set_forced_version_profile(
     shaderc_compile_options_t options, int version, shaderc_profile profile);
 
 // Source text inclusion via #include is supported with a pair of callbacks
@@ -349,7 +370,7 @@
     void* user_data, shaderc_include_result* include_result);
 
 // Sets includer callback functions.
-void shaderc_compile_options_set_include_callbacks(
+SHADERC_EXPORT void shaderc_compile_options_set_include_callbacks(
     shaderc_compile_options_t options, shaderc_include_resolve_fn resolver,
     shaderc_include_result_release_fn result_releaser, void* user_data);
 
@@ -357,67 +378,69 @@
 // mode. When both suppress-warnings and warnings-as-errors modes are
 // turned on, warning messages will be inhibited, and will not be emitted
 // as error messages.
-void shaderc_compile_options_set_suppress_warnings(
+SHADERC_EXPORT void shaderc_compile_options_set_suppress_warnings(
     shaderc_compile_options_t options);
 
 // Sets the target shader environment, affecting which warnings or errors will
 // be issued.  The version will be for distinguishing between different versions
 // of the target environment.  "0" is the only supported version at this point
-void shaderc_compile_options_set_target_env(shaderc_compile_options_t options,
-                                            shaderc_target_env target,
-                                            uint32_t version);
+SHADERC_EXPORT void shaderc_compile_options_set_target_env(
+    shaderc_compile_options_t options,
+    shaderc_target_env target,
+    uint32_t version);
 
 // Sets the compiler mode to treat all warnings as errors. Note the
 // suppress-warnings mode overrides this option, i.e. if both
 // warning-as-errors and suppress-warnings modes are set, warnings will not
 // be emitted as error messages.
-void shaderc_compile_options_set_warnings_as_errors(
+SHADERC_EXPORT void shaderc_compile_options_set_warnings_as_errors(
     shaderc_compile_options_t options);
 
 // Sets a resource limit.
-void shaderc_compile_options_set_limit(
+SHADERC_EXPORT void shaderc_compile_options_set_limit(
     shaderc_compile_options_t options, shaderc_limit limit, int value);
 
 // Sets whether the compiler should automatically assign bindings to uniforms
 // that aren't already explicitly bound in the shader source.
-void shaderc_compile_options_set_auto_bind_uniforms(
+SHADERC_EXPORT void shaderc_compile_options_set_auto_bind_uniforms(
     shaderc_compile_options_t options, bool auto_bind);
 
 // Sets whether the compiler should use HLSL IO mapping rules for bindings.
 // Defaults to false.
-void shaderc_compile_options_set_hlsl_io_mapping(
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_io_mapping(
     shaderc_compile_options_t options, bool hlsl_iomap);
 
 // Sets whether the compiler should determine block member offsets using HLSL
 // packing rules instead of standard GLSL rules.  Defaults to false.  Only
 // affects GLSL compilation.  HLSL rules are always used when compiling HLSL.
-void shaderc_compile_options_set_hlsl_offsets(
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_offsets(
     shaderc_compile_options_t options, bool hlsl_offsets);
 
 // Sets the base binding number used for for a uniform resource type when
 // automatically assigning bindings.  For GLSL compilation, sets the lowest
 // automatically assigned number.  For HLSL compilation, the regsiter number
 // assigned to the resource is added to this specified base.
-void shaderc_compile_options_set_binding_base(shaderc_compile_options_t options,
-                                              shaderc_uniform_kind kind,
-                                              uint32_t base);
+SHADERC_EXPORT void shaderc_compile_options_set_binding_base(
+    shaderc_compile_options_t options,
+    shaderc_uniform_kind kind,
+    uint32_t base);
 
 // Like shaderc_compile_options_set_binding_base, but only takes effect when
 // compiling a given shader stage.  The stage is assumed to be one of vertex,
 // fragment, tessellation evaluation, tesselation control, geometry, or compute.
-void shaderc_compile_options_set_binding_base_for_stage(
+SHADERC_EXPORT void shaderc_compile_options_set_binding_base_for_stage(
     shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
     shaderc_uniform_kind kind, uint32_t base);
 
 // Sets a descriptor set and binding for an HLSL register in the given stage.
 // This method keeps a copy of the string data.
-void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
     shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
     const char* reg, const char* set, const char* binding);
 
 // Like shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage,
 // but affects all shader stages.
-void shaderc_compile_options_set_hlsl_register_set_and_binding(
+SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding(
     shaderc_compile_options_t options, const char* reg, const char* set,
     const char* binding);
 
@@ -444,7 +467,7 @@
 // present.  May be safely called from multiple threads without explicit
 // synchronization. If there was failure in allocating the compiler object,
 // null will be returned.
-shaderc_compilation_result_t shaderc_compile_into_spv(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -453,7 +476,7 @@
 // Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text
 // instead of a SPIR-V binary module.  The SPIR-V assembly syntax is as defined
 // by the SPIRV-Tools open source project.
-shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -461,7 +484,7 @@
 
 // Like shaderc_compile_into_spv, but the result contains preprocessed source
 // code instead of a SPIR-V binary module
-shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
     const shaderc_compiler_t compiler, const char* source_text,
     size_t source_text_size, shaderc_shader_kind shader_kind,
     const char* input_file_name, const char* entry_point_name,
@@ -476,7 +499,7 @@
 // May be safely called from multiple threads without explicit synchronization.
 // If there was failure in allocating the compiler object, null will be
 // returned.
-shaderc_compilation_result_t shaderc_assemble_into_spv(
+SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv(
     const shaderc_compiler_t compiler, const char* source_assembly,
     size_t source_assembly_size,
     const shaderc_compile_options_t additional_options);
@@ -486,23 +509,23 @@
 
 // Releases the resources held by the result object. It is invalid to use the
 // result object for any further operations.
-void shaderc_result_release(shaderc_compilation_result_t result);
+SHADERC_EXPORT void shaderc_result_release(shaderc_compilation_result_t result);
 
 // Returns the number of bytes of the compilation output data in a result
 // object.
-size_t shaderc_result_get_length(const shaderc_compilation_result_t result);
+SHADERC_EXPORT size_t shaderc_result_get_length(const shaderc_compilation_result_t result);
 
 // Returns the number of warnings generated during the compilation.
-size_t shaderc_result_get_num_warnings(
+SHADERC_EXPORT size_t shaderc_result_get_num_warnings(
     const shaderc_compilation_result_t result);
 
 // Returns the number of errors generated during the compilation.
-size_t shaderc_result_get_num_errors(const shaderc_compilation_result_t result);
+SHADERC_EXPORT size_t shaderc_result_get_num_errors(const shaderc_compilation_result_t result);
 
 // Returns the compilation status, indicating whether the compilation succeeded,
 // or failed due to some reasons, like invalid shader stage or compilation
 // errors.
-shaderc_compilation_status shaderc_result_get_compilation_status(
+SHADERC_EXPORT shaderc_compilation_status shaderc_result_get_compilation_status(
     const shaderc_compilation_result_t);
 
 // Returns a pointer to the start of the compilation output data bytes, either
@@ -510,21 +533,21 @@
 // binary, this is guaranteed to be castable to a uint32_t*. If the result
 // contains assembly text or preprocessed source text, the pointer will point to
 // the resulting array of characters.
-const char* shaderc_result_get_bytes(const shaderc_compilation_result_t result);
+SHADERC_EXPORT const char* shaderc_result_get_bytes(const shaderc_compilation_result_t result);
 
 // Returns a null-terminated string that contains any error messages generated
 // during the compilation.
-const char* shaderc_result_get_error_message(
+SHADERC_EXPORT const char* shaderc_result_get_error_message(
     const shaderc_compilation_result_t result);
 
 // Provides the version & revision of the SPIR-V which will be produced
-void shaderc_get_spv_version(unsigned int* version, unsigned int* revision);
+SHADERC_EXPORT void shaderc_get_spv_version(unsigned int* version, unsigned int* revision);
 
 // Parses the version and profile from a given null-terminated string
 // containing both version and profile, like: '450core'. Returns false if
 // the string can not be parsed. Returns true when the parsing succeeds. The
 // parsed version and profile are returned through arguments.
-bool shaderc_parse_version_profile(const char* str, int* version,
+SHADERC_EXPORT bool shaderc_parse_version_profile(const char* str, int* version,
                                    shaderc_profile* profile);
 
 #ifdef __cplusplus
diff --git a/libshaderc/src/common_shaders_for_test.h b/libshaderc/src/common_shaders_for_test.h
index 858bf99..8ecf1f9 100644
--- a/libshaderc/src/common_shaders_for_test.h
+++ b/libshaderc/src/common_shaders_for_test.h
@@ -189,7 +189,7 @@
 const char* kMinimalShaderDisassemblySubstrings[] = {
     "; SPIR-V\n"
     "; Version: 1.0\n"
-    "; Generator: Google Shaderc over Glslang; 1\n"
+    "; Generator: Google Shaderc over Glslang; 2\n"
     "; Bound:",
 
     "               OpCapability Shader\n",
@@ -201,7 +201,7 @@
 const char kMinimalShaderAssembly[] = R"(
     ; SPIR-V
     ; Version: 1.0
-    ; Generator: Google Shaderc over Glslang; 1
+    ; Generator: Google Shaderc over Glslang; 2
     ; Bound: 6
     ; Schema: 0
 
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
index 8755674..35c74dc 100644
--- a/libshaderc_util/include/libshaderc_util/compiler.h
+++ b/libshaderc_util/include/libshaderc_util/compiler.h
@@ -186,6 +186,7 @@
         auto_binding_base_(),
         hlsl_iomap_(false),
         hlsl_offsets_(false),
+        hlsl_legalization_enabled_(true),
         hlsl_explicit_bindings_() {}
 
   // Requests that the compiler place debug information into the object code,
@@ -196,6 +197,9 @@
   // effect if multiple calls of this method exist.
   void SetOptimizationLevel(OptimizationLevel level);
 
+  // Enables or disables HLSL legalization passes.
+  void EnableHlslLegalization(bool hlsl_legalization_enabled);
+
   // When a warning is encountered it treat it as an error.
   void SetWarningsAsErrors();
 
@@ -442,6 +446,10 @@
   // packing rules instead of standard GLSL rules.
   bool hlsl_offsets_;
 
+  // True if the compiler should perform legalization optimization passes if
+  // source language is HLSL.
+  bool hlsl_legalization_enabled_;
+
   // A sequence of triples, each triple representing a specific HLSL register
   // name, and the set and binding numbers it should be mapped to, but in
   // the form of strings.  This is how Glslang wants to consume the data.
diff --git a/libshaderc_util/include/libshaderc_util/counting_includer.h b/libshaderc_util/include/libshaderc_util/counting_includer.h
index c773a62..3e6b0a6 100644
--- a/libshaderc_util/include/libshaderc_util/counting_includer.h
+++ b/libshaderc_util/include/libshaderc_util/counting_includer.h
@@ -19,9 +19,13 @@
 
 #include "glslang/Public/ShaderLang.h"
 
+#include "libshaderc_util/mutex.h"
+
 namespace shaderc_util {
 
 // An Includer that counts how many #include directives it saw.
+// Inclusions are internally serialized, but releasing a previous result
+// can occur concurrently.
 class CountingIncluder : public glslang::TShader::Includer {
  public:
   // Done as .store(0) instead of in the initializer list for the following
@@ -42,13 +46,16 @@
   // requesting source.  For the semantics of the result, see the base class.
   // Also increments num_include_directives and returns the results of
   // include_delegate(filename).  Subclasses should override include_delegate()
-  // instead of this method.
+  // instead of this method.  Inclusions are serialized.
   glslang::TShader::Includer::IncludeResult* includeSystem(
       const char* requested_source, const char* requesting_source,
       size_t include_depth) final {
     ++num_include_directives_;
-    return include_delegate(requested_source, requesting_source,
-                            IncludeType::System, include_depth);
+    include_mutex_.lock();
+    auto result = include_delegate(requested_source, requesting_source,
+                                   IncludeType::System, include_depth);
+    include_mutex_.unlock();
+    return result;
   }
 
   // Like includeSystem, but for "local" include search.
@@ -56,8 +63,11 @@
       const char* requested_source, const char* requesting_source,
       size_t include_depth) final {
     ++num_include_directives_;
-    return include_delegate(requested_source, requesting_source,
-                            IncludeType::Local, include_depth);
+    include_mutex_.lock();
+    auto result = include_delegate(requested_source, requesting_source,
+                                   IncludeType::Local, include_depth);
+    include_mutex_.unlock();
+    return result;
   }
 
   // Releases the given IncludeResult.
@@ -81,6 +91,10 @@
 
   // The number of #include directive encountered.
   std::atomic_int num_include_directives_;
+
+  // A mutex to protect against concurrent inclusions.  We can't trust
+  // our delegates to be safe for concurrent inclusions.
+  shaderc_util::mutex include_mutex_;
 };
 }
 
diff --git a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
index b02e15d..f5b0315 100644
--- a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
+++ b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
@@ -41,7 +41,25 @@
 enum class PassId {
   kNullPass,
   kStripDebugInfo,
+  kEliminateDeadFunctions,
+  kFlattenDecoration,
+  kFreezeSpecConstantValue,
+  kFoldSpecConstantOpAndComposite,
   kUnifyConstant,
+  kEliminateDeadConstant,
+  kStrengthReduction,
+  kBlockMerge,
+  kInlineExhaustive,
+  kInlineOpaque,
+  kLocalSingleBlockLoadStoreElim,
+  kDeadBranchElim,
+  kLocalMultiStoreElim,
+  kLocalAccessChainConvert,
+  kLocalSingleStoreElim,
+  kInsertExtractElim,
+  kCommonUniformElim,
+  kAggressiveDCE,
+  kCompactIds,
 };
 
 // Optimizes the given binary. Passes are registered in the exact order as shown
diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc
index c620721..da23549 100644
--- a/libshaderc_util/src/compiler.cc
+++ b/libshaderc_util/src/compiler.cc
@@ -243,8 +243,13 @@
   // 'spirv' is an alias for the compilation_output_data. This alias is added
   // to serve as an input for the call to DissassemblyBinary.
   std::vector<uint32_t>& spirv = compilation_output_data;
+  glslang::SpvOptions options;
+  options.generateDebugInfo = false;
+  options.disableOptimizer = true;
+  options.optimizeSize = false;
   // Note the call to GlslangToSpv also populates compilation_output_data.
-  glslang::GlslangToSpv(*program.getIntermediate(used_shader_stage), spirv);
+  glslang::GlslangToSpv(*program.getIntermediate(used_shader_stage), spirv,
+			&options);
 
   // Set the tool field (the top 16-bits) in the generator word to
   // 'Shaderc over Glslang'.
@@ -254,10 +259,36 @@
   spirv[generator_word_index] =
       (spirv[generator_word_index] & 0xffff) | (shaderc_generator_word << 16);
 
-  if (!enabled_opt_passes_.empty()) {
+  std::vector<PassId> opt_passes;
+
+  if (hlsl_legalization_enabled_ && source_language_ == SourceLanguage::HLSL) {
+    // If from HLSL, run this passes to "legalize" the SPIR-V for Vulkan
+    // eg. forward and remove memory writes of opaque types.
+    opt_passes.push_back(PassId::kInlineExhaustive);
+    opt_passes.push_back(PassId::kLocalAccessChainConvert);
+    opt_passes.push_back(PassId::kLocalSingleBlockLoadStoreElim);
+    opt_passes.push_back(PassId::kLocalSingleStoreElim);
+    opt_passes.push_back(PassId::kInsertExtractElim);
+    opt_passes.push_back(PassId::kAggressiveDCE);
+    opt_passes.push_back(PassId::kDeadBranchElim);
+    opt_passes.push_back(PassId::kBlockMerge);
+    opt_passes.push_back(PassId::kLocalMultiStoreElim);
+    opt_passes.push_back(PassId::kInsertExtractElim);
+    opt_passes.push_back(PassId::kAggressiveDCE);
+    opt_passes.push_back(PassId::kEliminateDeadConstant);
+    opt_passes.push_back(PassId::kEliminateDeadFunctions);
+
+    // TODO(atgoo, dneto0, greg-lunarg):
+    // Add PassId::kCommonUniformElim when AMD driver issues are resolved.
+    // Add dead var/type elimination passes when available.
+  }
+
+  opt_passes.insert(
+      opt_passes.end(), enabled_opt_passes_.begin(), enabled_opt_passes_.end());
+
+  if (!opt_passes.empty()) {
     std::string opt_errors;
-    if (!SpirvToolsOptimize(target_env_, enabled_opt_passes_, &spirv,
-                            &opt_errors)) {
+    if (!SpirvToolsOptimize(target_env_, opt_passes, &spirv, &opt_errors)) {
       *error_stream << "shaderc: internal error: compilation succeeded but "
                        "failed to optimize: "
                     << opt_errors << "\n";
@@ -331,6 +362,10 @@
   }
 }
 
+void Compiler::EnableHlslLegalization(bool hlsl_legalization_enabled) {
+  hlsl_legalization_enabled_ = hlsl_legalization_enabled;
+}
+
 void Compiler::SetSuppressWarnings() { suppress_warnings_ = true; }
 
 std::tuple<bool, std::string, std::string> Compiler::PreprocessShader(
diff --git a/libshaderc_util/src/compiler_test.cc b/libshaderc_util/src/compiler_test.cc
index fe8689c..fa447d1 100644
--- a/libshaderc_util/src/compiler_test.cc
+++ b/libshaderc_util/src/compiler_test.cc
@@ -110,6 +110,27 @@
        buffer B { float x; vec3 foo; } my_ssbo;
        void main() { my_ssbo.x = 1.0; })";
 
+const char kHlslShaderForLegalizationTest[] = R"(
+struct CombinedTextureSampler {
+ Texture2D tex;
+ SamplerState sampl;
+};
+
+float4 sampleTexture(CombinedTextureSampler c, float2 loc) {
+ return c.tex.Sample(c.sampl, loc);
+};
+
+Texture2D gTex;
+SamplerState gSampler;
+
+float4 main(float2 loc: A) : SV_Target {
+ CombinedTextureSampler cts;
+ cts.tex = gTex;
+ cts.sampl = gSampler;
+
+ return sampleTexture(cts, loc);
+})";
+
 // Returns the disassembly of the given SPIR-V binary, as a string.
 // Assumes the disassembly will be successful when targeting Vulkan.
 std::string Disassemble(const std::vector<uint32_t> binary) {
@@ -662,4 +683,32 @@
       << disassembly;
 }
 
+TEST_F(CompilerTest, HlslLegalizationEnabledNoSizeOpt) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpFunctionCall"))) << disassembly;
+  EXPECT_THAT(disassembly, HasSubstr("OpName")) << disassembly;
+}
+
+TEST_F(CompilerTest, HlslLegalizationEnabledWithSizeOpt) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  compiler_.SetOptimizationLevel(Compiler::OptimizationLevel::Size);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpFunctionCall"))) << disassembly;
+  EXPECT_THAT(disassembly, Not(HasSubstr("OpName"))) << disassembly;
+}
+
+TEST_F(CompilerTest, HlslLegalizationDisabled) {
+  compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL);
+  compiler_.EnableHlslLegalization(false);
+  const auto words =
+      SimpleCompilationBinary(kHlslShaderForLegalizationTest, EShLangFragment);
+  const auto disassembly = Disassemble(words);
+  EXPECT_THAT(disassembly, HasSubstr("OpFunctionCall")) << disassembly;
+}
+
 }  // anonymous namespace
diff --git a/libshaderc_util/src/spirv_tools_wrapper.cc b/libshaderc_util/src/spirv_tools_wrapper.cc
index 273d1ba..87dbfca 100644
--- a/libshaderc_util/src/spirv_tools_wrapper.cc
+++ b/libshaderc_util/src/spirv_tools_wrapper.cc
@@ -105,9 +105,63 @@
       case PassId::kStripDebugInfo:
         optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
         break;
+      case PassId::kEliminateDeadFunctions:
+        optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass());
+        break;
+      case PassId::kFlattenDecoration:
+        optimizer.RegisterPass(spvtools::CreateFlattenDecorationPass());
+        break;
+      case PassId::kFreezeSpecConstantValue:
+        optimizer.RegisterPass(spvtools::CreateFreezeSpecConstantValuePass());
+        break;
+      case PassId::kFoldSpecConstantOpAndComposite:
+        optimizer.RegisterPass(spvtools::CreateFoldSpecConstantOpAndCompositePass());
+        break;
       case PassId::kUnifyConstant:
         optimizer.RegisterPass(spvtools::CreateUnifyConstantPass());
         break;
+      case PassId::kEliminateDeadConstant:
+        optimizer.RegisterPass(spvtools::CreateEliminateDeadConstantPass());
+        break;
+      case PassId::kStrengthReduction:
+        optimizer.RegisterPass(spvtools::CreateStrengthReductionPass());
+        break;
+      case PassId::kBlockMerge:
+        optimizer.RegisterPass(spvtools::CreateBlockMergePass());
+        break;
+      case PassId::kInlineExhaustive:
+        optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
+        break;
+      case PassId::kInlineOpaque:
+        optimizer.RegisterPass(spvtools::CreateInlineOpaquePass());
+        break;
+      case PassId::kLocalSingleBlockLoadStoreElim:
+        optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass());
+        break;
+      case PassId::kDeadBranchElim:
+        optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
+        break;
+      case PassId::kLocalMultiStoreElim:
+        optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass());
+        break;
+      case PassId::kLocalAccessChainConvert:
+        optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass());
+        break;
+      case PassId::kLocalSingleStoreElim:
+        optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass());
+        break;
+      case PassId::kInsertExtractElim:
+        optimizer.RegisterPass(spvtools::CreateInsertExtractElimPass());
+        break;
+      case PassId::kCommonUniformElim:
+        optimizer.RegisterPass(spvtools::CreateCommonUniformElimPass());
+        break;
+      case PassId::kAggressiveDCE:
+        optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
+        break;
+      case PassId::kCompactIds:
+        optimizer.RegisterPass(spvtools::CreateCompactIdsPass());
+        break;
     }
   }
 
diff --git a/third_party/Android.mk b/third_party/Android.mk
index 582955f..0ce3dba 100644
--- a/third_party/Android.mk
+++ b/third_party/Android.mk
@@ -104,209 +104,11 @@
 LOCAL_STATIC_LIBRARIES:=OSDependent OGLCompiler SPIRV HLSL
 include $(BUILD_STATIC_LIBRARY)
 
+# Set the location of SPIRV-Tools.
+# Allow the user to override it, but default it to under our third_party directory.
+ifeq ($(SPVTOOLS_LOCAL_PATH),)
+  SPVTOOLS_LOCAL_PATH:=$(THIRD_PARTY_PATH)/spirv-tools
+endif
 
-SPVTOOLS_LOCAL_PATH := $(THIRD_PARTY_PATH)/spirv-tools
-LOCAL_PATH := $(SPVTOOLS_LOCAL_PATH)
-SPVTOOLS_OUT_PATH=$(if $(call host-path-is-absolute,$(TARGET_OUT)),$(TARGET_OUT),$(abspath $(TARGET_OUT)))
-SPVHEADERS_LOCAL_PATH := $(THIRD_PARTY_PATH)/spirv-tools/external/spirv-headers
-
-SPVTOOLS_SRC_FILES := \
-		source/assembly_grammar.cpp \
-		source/binary.cpp \
-		source/diagnostic.cpp \
-		source/disassemble.cpp \
-		source/ext_inst.cpp \
-		source/enum_string_mapping.cpp \
-		source/extensions.cpp \
-		source/id_descriptor.cpp \
-		source/libspirv.cpp \
-		source/name_mapper.cpp \
-		source/opcode.cpp \
-		source/operand.cpp \
-		source/parsed_operand.cpp \
-		source/print.cpp \
-		source/software_version.cpp \
-		source/spirv_endian.cpp \
-		source/spirv_target_env.cpp \
-		source/spirv_validator_options.cpp \
-		source/table.cpp \
-		source/text.cpp \
-		source/text_handler.cpp \
-		source/util/bit_stream.cpp \
-		source/util/parse_number.cpp \
-		source/util/string_utils.cpp \
-		source/val/basic_block.cpp \
-		source/val/construct.cpp \
-		source/val/function.cpp \
-		source/val/instruction.cpp \
-		source/val/validation_state.cpp \
-		source/validate.cpp \
-		source/validate_cfg.cpp \
-		source/validate_capability.cpp \
-		source/validate_datarules.cpp \
-		source/validate_decorations.cpp \
-		source/validate_id.cpp \
-		source/validate_instruction.cpp \
-		source/validate_layout.cpp \
-		source/validate_type_unique.cpp
-
-SPVTOOLS_OPT_SRC_FILES := \
-		source/opt/aggressive_dead_code_elim_pass.cpp \
-		source/opt/basic_block.cpp \
-		source/opt/block_merge_pass.cpp \
-		source/opt/build_module.cpp \
-		source/opt/compact_ids_pass.cpp \
-		source/opt/common_uniform_elim_pass.cpp \
-		source/opt/dead_branch_elim_pass.cpp \
-		source/opt/def_use_manager.cpp \
-		source/opt/eliminate_dead_constant_pass.cpp \
-		source/opt/flatten_decoration_pass.cpp \
-		source/opt/fold_spec_constant_op_and_composite_pass.cpp \
-		source/opt/freeze_spec_constant_value_pass.cpp \
-		source/opt/function.cpp \
-		source/opt/inline_pass.cpp \
-		source/opt/inline_exhaustive_pass.cpp \
-		source/opt/inline_opaque_pass.cpp \
-		source/opt/insert_extract_elim.cpp \
-		source/opt/instruction.cpp \
-		source/opt/ir_loader.cpp \
-		source/opt/local_access_chain_convert_pass.cpp \
-		source/opt/local_single_block_elim_pass.cpp \
-		source/opt/local_single_store_elim_pass.cpp \
-		source/opt/local_ssa_elim_pass.cpp \
-		source/opt/mem_pass.cpp \
-		source/opt/module.cpp \
-		source/opt/optimizer.cpp \
-		source/opt/pass.cpp \
-		source/opt/pass_manager.cpp \
-		source/opt/set_spec_constant_default_value_pass.cpp \
-		source/opt/strip_debug_info_pass.cpp \
-		source/opt/type_manager.cpp \
-		source/opt/types.cpp \
-		source/opt/unify_const_pass.cpp
-# Locations of grammar files.
-SPV_CORE10_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/spirv.core.grammar.json
-SPV_CORE11_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.1/spirv.core.grammar.json
-SPV_GLSL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/extinst.glsl.std.450.grammar.json
-SPV_OPENCL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/extinst.opencl.std.100.grammar.json
-
-define gen_spvtools_grammar_tables
-$(call generate-file-dir,$(1)/core.insts-1.0.inc)
-$(1)/core.insts-1.0.inc $(1)/operand.kinds-1.0.inc $(1)/glsl.std.450.insts-1.0.inc $(1)/opencl.std.insts-1.0.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE10_GRAMMAR) \
-        $(SPV_GLSL_GRAMMAR) \
-        $(SPV_OPENCL_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE10_GRAMMAR) \
-		                --extinst-glsl-grammar=$(SPV_GLSL_GRAMMAR) \
-		                --extinst-opencl-grammar=$(SPV_OPENCL_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.0.inc \
-		                --glsl-insts-output=$(1)/glsl.std.450.insts-1.0.inc \
-		                --opencl-insts-output=$(1)/opencl.std.insts-1.0.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.0.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.0   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-1.1.inc $(1)/operand.kinds-1.1.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE11_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.1.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.1.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.1   : instructions & operands <= grammar JSON files"
-$(1)/core.insts-1.2.inc $(1)/operand.kinds-1.2.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE11_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \
-		                --core-insts-output=$(1)/core.insts-1.2.inc \
-		                --operand-kinds-output=$(1)/operand.kinds-1.2.inc
-		@echo "[$(TARGET_ARCH_ABI)] Grammar v1.2   : instructions & operands <= grammar JSON files"
-$(SPVTOOLS_LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc $(1)/core.insts-1.2.inc
-$(SPVTOOLS_LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc $(1)/operand.kinds-1.2.inc
-$(SPVTOOLS_LOCAL_PATH)/source/ext_inst.cpp: $(1)/glsl.std.450.insts-1.0.inc $(1)/opencl.std.insts-1.0.inc
-endef
-$(eval $(call gen_spvtools_grammar_tables,$(SPVTOOLS_OUT_PATH)))
-
-define gen_spvtools_vendor_tables
-$(call generate-file-dir,$(1)/$(2).insts.inc)
-$(1)/$(2).insts.inc : \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPVTOOLS_LOCAL_PATH)/source/extinst.$(2).grammar.json
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		    --extinst-vendor-grammar=$(SPVTOOLS_LOCAL_PATH)/source/extinst.$(2).grammar.json \
-		    --vendor-insts-output=$(1)/$(2).insts.inc
-		@echo "[$(TARGET_ARCH_ABI)] Vendor extended instruction set: $(2) tables <= grammar"
-$(SPVTOOLS_LOCAL_PATH)/source/ext_inst.cpp: $(1)/$(2).insts.inc
-endef
-# Vendor extended instruction sets, with grammars from SPIRV-Tools source tree.
-SPV_NONSTANDARD_EXTINST_GRAMMARS=$(foreach F,$(wildcard $(SPVTOOLS_LOCAL_PATH)/source/extinst.*.grammar.json),$(patsubst extinst.%.grammar.json,%,$(notdir $F)))
-$(foreach E,$(SPV_NONSTANDARD_EXTINST_GRAMMARS),$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),$E)))
-
-define gen_spvtools_enum_string_mapping
-$(call generate-file-dir,$(1)/extension_enum.inc.inc)
-$(1)/extension_enum.inc $(1)/enum_string_mapping.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-        $(SPV_CORE11_GRAMMAR)
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_grammar_tables.py \
-		                --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \
-		                --extension-enum-output=$(1)/extension_enum.inc \
-		                --enum-string-mapping-output=$(1)/enum_string_mapping.inc
-		@echo "[$(TARGET_ARCH_ABI)] Generate enum<->string mapping <= grammar JSON files"
-# Generated header extension_enum.inc is transitively included by table.h, which is
-# used pervasively.  Capture the pervasive dependency.
-$(foreach F,$(SPVTOOLS_SRC_FILES) $(SPVTOOLS_OPT_SRC_FILES),$(SPVTOOLS_LOCAL_PATH)/$F ) \
-  : $(1)/extension_enum.inc
-$(SPVTOOLS_LOCAL_PATH)/source/enum_string_mapping.cpp: $(1)/enum_string_mapping.inc
-endef
-$(eval $(call gen_spvtools_enum_string_mapping,$(SPVTOOLS_OUT_PATH)))
-
-define gen_spvtools_build_version_inc
-$(call generate-file-dir,$(1)/dummy_filename)
-$(1)/build-version.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/update_build_version.py \
-        $(SPVTOOLS_LOCAL_PATH)/CHANGES
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/update_build_version.py \
-		                $(SPVTOOLS_LOCAL_PATH) $(1)/build-version.inc
-		@echo "[$(TARGET_ARCH_ABI)] Generate       : build-version.inc <= CHANGES"
-$(SPVTOOLS_LOCAL_PATH)/source/software_version.cpp: $(1)/build-version.inc
-endef
-$(eval $(call gen_spvtools_build_version_inc,$(SPVTOOLS_OUT_PATH)))
-
-define gen_spvtools_generators_inc
-$(call generate-file-dir,$(1)/dummy_filename)
-$(1)/generators.inc: \
-        $(SPVTOOLS_LOCAL_PATH)/utils/generate_registry_tables.py \
-        $(SPVHEADERS_LOCAL_PATH)/include/spirv/spir-v.xml
-		@$(HOST_PYTHON) $(SPVTOOLS_LOCAL_PATH)/utils/generate_registry_tables.py \
-		                --xml=$(SPVHEADERS_LOCAL_PATH)/include/spirv/spir-v.xml \
-				--generator-output=$(1)/generators.inc
-		@echo "[$(TARGET_ARCH_ABI)] Generate       : generators.inc <= spir-v.xml"
-$(SPVTOOLS_LOCAL_PATH)/source/opcode.cpp: $(1)/generators.inc
-endef
-$(eval $(call gen_spvtools_generators_inc,$(SPVTOOLS_OUT_PATH)))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := SPIRV-Tools
-LOCAL_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include \
-		$(SPVTOOLS_LOCAL_PATH)/source \
-		$(SPVTOOLS_LOCAL_PATH)/external/spirv-headers/include \
-		$(SPVTOOLS_OUT_PATH)
-LOCAL_EXPORT_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror
-LOCAL_SRC_FILES:= $(SPVTOOLS_SRC_FILES)
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := SPIRV-Tools-opt
-LOCAL_C_INCLUDES := \
-		$(SPVTOOLS_LOCAL_PATH)/include \
-		$(SPVTOOLS_LOCAL_PATH)/source \
-		$(SPVTOOLS_LOCAL_PATH)/external/spirv-headers/include \
-		$(SPVTOOLS_OUT_PATH)
-LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror
-LOCAL_STATIC_LIBRARIES:=SPIRV-Tools
-LOCAL_SRC_FILES:= $(SPVTOOLS_OPT_SRC_FILES)
-include $(BUILD_STATIC_LIBRARY)
+# Now include the SPIRV-Tools dependency
+include $(SPVTOOLS_LOCAL_PATH)/Android.mk
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index ace4e31..d00b14a 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -7,6 +7,8 @@
   "Location of googletest source")
 set(SHADERC_SPIRV_TOOLS_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/spirv-tools" CACHE STRING
   "Location of spirv-tools source")
+set(SHADERC_SPIRV_HEADERS_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/spirv-headers" CACHE STRING
+  "Location of spirv-headers source")
 set(SHADERC_GLSLANG_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/glslang" CACHE STRING
   "Location of glslang source")
 
@@ -26,6 +28,22 @@
 
 set(OLD_PLATFORM_TOOLSET ${CMAKE_GENERATOR_TOOLSET})
 
+if (IS_DIRECTORY ${SHADERC_SPIRV_HEADERS_DIR})
+  add_subdirectory(${SHADERC_SPIRV_HEADERS_DIR} spirv-headers)
+endif()
+
+# Check SPIRV-Tools before glslang since it is a dependency of glslang.
+if (IS_DIRECTORY ${SHADERC_SPIRV_TOOLS_DIR})
+  if ("${SHADERC_SKIP_TESTS}")
+    # Also skip building tests in SPIRV-Tools.
+    set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests")
+  endif()
+  add_subdirectory(${SHADERC_SPIRV_TOOLS_DIR} spirv-tools)
+endif()
+if (NOT TARGET SPIRV-Tools)
+  message(FATAL_ERROR "SPIRV-Tools was not found - required for compilation")
+endif()
+
 if (IS_DIRECTORY ${SHADERC_GLSLANG_DIR})
   add_subdirectory(${SHADERC_GLSLANG_DIR} glslang)
 endif()
@@ -40,17 +58,6 @@
       "Platform Toolset" FORCE)
 endif()
 
-if (IS_DIRECTORY ${SHADERC_SPIRV_TOOLS_DIR})
-  if ("${SHADERC_SKIP_TESTS}")
-    # Also skip building tests in SPIRV-Tools.
-    set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests")
-  endif()
-  add_subdirectory(${SHADERC_SPIRV_TOOLS_DIR} spirv-tools)
-endif()
-if (NOT TARGET SPIRV-Tools)
-  message(FATAL_ERROR "SPIRV-Tools was not found - required for compilation")
-endif()
-
 if(${SHADERC_ENABLE_TESTS})
   # Configure out-of-source-directory tests for glslang.
   # The glslang project uses a bash script called "runtests" to run tests.