Publish the C++ interface.
diff --git a/CHANGES b/CHANGES
index f06161a..aa74481 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
 Revision history for SPIRV-Tools
 
 v2016.6-dev 2016-09-16
+ - Published the C++ interface for assembling, disassembling, validation, and
+   optimization.
 
 v2016.5 2016-09-16
  - Support SPV_KHR_shader_ballot in assembler, disassembler, parser.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e881ca5..6470973 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -153,8 +153,13 @@
 
 add_subdirectory(test)
 
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.h
-  DESTINATION include/spirv-tools/)
+install(
+  FILES
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.hpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/optimizer.hpp
+  DESTINATION
+    include/spirv-tools/)
 
 add_test(NAME spirv-tools-copyrights
          COMMAND ${PYTHON_EXECUTABLE} utils/check_copyright.py
diff --git a/README.md b/README.md
index f9da4d4..0c5d049 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
 on a common static library.  The library contains all of the implementation
 details, and is used in the standalone tools whilst also enabling integration
 into other code bases directly. The optimizer implementation resides in its
-own library.
+own library, which depends on the core library.
 
 The interfaces are still under development, and are expected to change.
 
@@ -59,17 +59,18 @@
 
 ### Optimizer
 
-*Warning:* The optimizer is still under development and its library interface is
-not yet published.
+*Warning:* The optimizer is still under development.
 
 Currently supported optimizations:
-* [Strip debug info](source/opt/strip_debug_info_pass.h)
-* [Freeze spec constant](source/opt/freeze_spec_constant_value_pass.h)
-* [Fold `OpSpecConstantOp` and `OpSpecConstantComposite`](source/opt/fold_spec_constant_op_and_composite_pass.h)
-* [Unify constants](source/opt/unify_const_pass.h)
-* [Eliminate dead constant](source/opt/eliminate_dead_constant_pass.h)
+* Strip debug info
+* Set spec constant default value
+* Freeze spec constant
+* Fold `OpSpecConstantOp` and `OpSpecConstantComposite`
+* Unify constants
+* Eliminate dead constant
 
-For the latest list, please refer to `spirv-opt --help`.
+For the latest list with detailed documentation, please refer to
+[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp).
 
 ## Source code
 
@@ -161,23 +162,31 @@
 
 ### Usage
 
-The library provides a C API, but the internals use C++11.
+The internals of the library use C++11 features, and are exposed via both a C
+and C++ API.
 
 In order to use the library from an application, the include path should point
 to `<spirv-dir>/include`, which will enable the application to include the
-header `<spirv-dir>/include/spirv-tools/libspirv.h` then linking against the
-static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or
+header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against
+the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or
 `<spirv-build-dir>/source/SPIRV-Tools.lib`.
+For optimization, the header file is
+`<spirv-dir>/include/spirv-tools/optimizer.hpp`, and the static library is
+`<spirv-build-dir>/source/libSPIRV-Tools-opt.a` or
+`<spirv-build-dir>/source/SPIRV-Tools-opt.lib`.
 
 * `SPIRV-Tools` CMake target: Creates the static library:
   * `<spirv-build-dir>/source/libSPIRV-Tools.a` on Linux and OS X.
   * `<spirv-build-dir>/source/libSPIRV-Tools.lib` on Windows.
+* `SPIRV-Tools-opt` CMake target: Creates the static library:
+  * `<spirv-build-dir>/source/libSPIRV-Tools-opt.a` on Linux and OS X.
+  * `<spirv-build-dir>/source/libSPIRV-Tools-opt.lib` on Windows.
 
 #### Entry points
 
 The interfaces are still under development, and are expected to change.
 
-There are three main entry points into the library.
+There are five main entry points into the library in the C interface:
 
 * `spvTextToBinary`: An assembler, translating text to a binary SPIR-V module.
 * `spvBinaryToText`: A disassembler, translating a binary SPIR-V module to
@@ -186,6 +195,12 @@
   for the header and each parsed instruction.  The disassembler is implemented
   as a client of `spvBinaryParse`.
 * `spvValidate` implements the validator functionality. *Incomplete*
+* `spvValidateBinary` implements the validator functionality. *Incomplete*
+
+The C++ interface is comprised of two classes, `SpirvTools` and `Optimizer`,
+both in the `spvtools` namespace.
+* `SpirvTools` provides `Assemble`, `Disassemble`, and `Validate` methods.
+* `Optimizer` provides methods for registering and running optimization passes.
 
 ## Command line tools
 
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
index f128a9e..84a3b29 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
@@ -56,6 +56,21 @@
   SPV_FORCE_32_BIT_ENUM(spv_result_t)
 } spv_result_t;
 
+// Severity levels of messages communicated to the consumer.
+typedef enum spv_message_level_t {
+  SPV_MSG_FATAL,           // Unrecoverable error due to environment.
+                           // Will exit the program immediately. E.g.,
+                           // out of memory.
+  SPV_MSG_INTERNAL_ERROR,  // Unrecoverable error due to SPIRV-Tools
+                           // internals.
+                           // Will exit the program immediately. E.g.,
+                           // unimplemented feature.
+  SPV_MSG_ERROR,           // Normal error due to user input.
+  SPV_MSG_WARNINING,       // Warning information.
+  SPV_MSG_INFO,            // General information.
+  SPV_MSG_DEBUG,           // Debug information.
+} spv_message_level_t;
+
 typedef enum spv_endianness_t {
   SPV_ENDIANNESS_LITTLE,
   SPV_ENDIANNESS_BIG,
diff --git a/source/opt/libspirv.hpp b/include/spirv-tools/libspirv.hpp
similarity index 91%
rename from source/opt/libspirv.hpp
rename to include/spirv-tools/libspirv.hpp
index ab18f14..8a1f0d5 100644
--- a/source/opt/libspirv.hpp
+++ b/include/spirv-tools/libspirv.hpp
@@ -15,15 +15,22 @@
 #ifndef SPIRV_TOOLS_LIBSPIRV_HPP_
 #define SPIRV_TOOLS_LIBSPIRV_HPP_
 
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "message.h"
 #include "spirv-tools/libspirv.h"
 
 namespace spvtools {
 
+// Message consumer. The C strings for source and message are only alive for the
+// specific invocation.
+using MessageConsumer = std::function<void(
+    spv_message_level_t /* level */, const char* /* source */,
+    const spv_position_t& /* position */, const char* /* message */
+    )>;
+
 // C++ interface for SPIRV-Tools functionalities. It wraps the context
 // (including target environment and the corresponding SPIR-V grammar) and
 // provides methods for assembling, disassembling, and validating.
diff --git a/source/opt/optimizer.hpp b/include/spirv-tools/optimizer.hpp
similarity index 99%
rename from source/opt/optimizer.hpp
rename to include/spirv-tools/optimizer.hpp
index 8a84dfd..f856e3b 100644
--- a/source/opt/optimizer.hpp
+++ b/include/spirv-tools/optimizer.hpp
@@ -21,7 +21,6 @@
 #include <vector>
 
 #include "libspirv.hpp"
-#include "message.h"
 
 namespace spvtools {
 
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index e999e6a..0324aea 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -143,6 +143,7 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/disassemble.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/instruction.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/libspirv.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/message.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/name_mapper.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/opcode.cpp
diff --git a/source/diagnostic.cpp b/source/diagnostic.cpp
index 0c467d5..916552c 100644
--- a/source/diagnostic.cpp
+++ b/source/diagnostic.cpp
@@ -14,12 +14,10 @@
 
 #include "diagnostic.h"
 
-#include <assert.h>
-#include <string.h>
-
+#include <cassert>
+#include <cstring>
 #include <iostream>
 
-#include "spirv-tools/libspirv.h"
 #include "table.h"
 
 // Diagnostic API
@@ -70,22 +68,22 @@
 
 DiagnosticStream::~DiagnosticStream() {
   if (error_ != SPV_FAILED_MATCH && consumer_ != nullptr) {
-    auto level = spvtools::SPV_MSG_ERROR;
+    auto level = SPV_MSG_ERROR;
     switch (error_) {
       case SPV_SUCCESS:
       case SPV_REQUESTED_TERMINATION:  // Essentially success.
-        level = spvtools::SPV_MSG_INFO;
+        level = SPV_MSG_INFO;
         break;
       case SPV_WARNING:
-        level = spvtools::SPV_MSG_WARNINING;
+        level = SPV_MSG_WARNINING;
         break;
       case SPV_UNSUPPORTED:
       case SPV_ERROR_INTERNAL:
       case SPV_ERROR_INVALID_TABLE:
-        level = spvtools::SPV_MSG_INTERNAL_ERROR;
+        level = SPV_MSG_INTERNAL_ERROR;
         break;
       case SPV_ERROR_OUT_OF_MEMORY:
-        level = spvtools::SPV_MSG_FATAL;
+        level = SPV_MSG_FATAL;
         break;
       default:
         break;
@@ -98,9 +96,9 @@
                                     spv_diagnostic* diagnostic) {
   assert(diagnostic && *diagnostic == nullptr);
 
-  auto create_diagnostic = [diagnostic](
-      spvtools::spv_message_level_t, const char*,
-      const spv_position_t& position, const char* message) {
+  auto create_diagnostic = [diagnostic](spv_message_level_t, const char*,
+                                        const spv_position_t& position,
+                                        const char* message) {
     auto p = position;
     spvDiagnosticDestroy(*diagnostic);  // Avoid memory leak.
     *diagnostic = spvDiagnosticCreate(&p, message);
diff --git a/source/diagnostic.h b/source/diagnostic.h
index 9bf9ae2..72d537a 100644
--- a/source/diagnostic.h
+++ b/source/diagnostic.h
@@ -15,12 +15,10 @@
 #ifndef LIBSPIRV_DIAGNOSTIC_H_
 #define LIBSPIRV_DIAGNOSTIC_H_
 
-#include <iostream>
 #include <sstream>
 #include <utility>
 
-#include "message.h"
-#include "spirv-tools/libspirv.h"
+#include "spirv-tools/libspirv.hpp"
 
 namespace libspirv {
 
diff --git a/source/opt/libspirv.cpp b/source/libspirv.cpp
similarity index 96%
rename from source/opt/libspirv.cpp
rename to source/libspirv.cpp
index fe09ed5..dcbfa15 100644
--- a/source/opt/libspirv.cpp
+++ b/source/libspirv.cpp
@@ -12,10 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "libspirv.hpp"
+#include "spirv-tools/libspirv.hpp"
 
-#include "ir_loader.h"
-#include "make_unique.h"
 #include "message.h"
 #include "table.h"
 
diff --git a/source/message.h b/source/message.h
index 7139cee..4843054 100644
--- a/source/message.h
+++ b/source/message.h
@@ -15,37 +15,12 @@
 #ifndef SPIRV_TOOLS_MESSAGE_H_
 #define SPIRV_TOOLS_MESSAGE_H_
 
-#include <functional>
 #include <string>
 
-#include "spirv-tools/libspirv.h"
+#include "spirv-tools/libspirv.hpp"
 
 namespace spvtools {
 
-// TODO(antiagainst): This eventually should be in the C++ interface.
-
-// Severity levels of messages communicated to the consumer.
-typedef enum spv_message_level_t {
-  SPV_MSG_FATAL,           // Unrecoverable error due to environment.
-                           // Will exit the program immediately. E.g.,
-                           // out of memory.
-  SPV_MSG_INTERNAL_ERROR,  // Unrecoverable error due to SPIRV-Tools
-                           // internals.
-                           // Will exit the program immediately. E.g.,
-                           // unimplemented feature.
-  SPV_MSG_ERROR,           // Normal error due to user input.
-  SPV_MSG_WARNINING,       // Warning information.
-  SPV_MSG_INFO,            // General information.
-  SPV_MSG_DEBUG,           // Debug information.
-} spv_message_level_t;
-
-// Message consumer. The C strings for source and message are only alive for the
-// specific invocation.
-using MessageConsumer = std::function<void(
-    spv_message_level_t /* level */, const char* /* source */,
-    const spv_position_t& /* position */, const char* /* message */
-    )>;
-
 // A message consumer that ignores all messages.
 inline void IgnoreMessage(spv_message_level_t, const char*,
                           const spv_position_t&, const char*) {}
diff --git a/source/opt/CMakeLists.txt b/source/opt/CMakeLists.txt
index 2fab5fc..7bc47ac 100644
--- a/source/opt/CMakeLists.txt
+++ b/source/opt/CMakeLists.txt
@@ -22,12 +22,10 @@
   freeze_spec_constant_value_pass.h
   instruction.h
   ir_loader.h
-  libspirv.hpp
   log.h
   module.h
   null_pass.h
   reflect.h
-  optimizer.hpp
   pass.h
   passes.h
   pass_manager.h
@@ -45,7 +43,6 @@
   freeze_spec_constant_value_pass.cpp
   instruction.cpp
   ir_loader.cpp
-  libspirv.cpp
   module.cpp
   set_spec_constant_default_value_pass.cpp
   optimizer.cpp
@@ -58,6 +55,14 @@
 
 spvtools_default_compile_options(SPIRV-Tools-opt)
 target_include_directories(SPIRV-Tools-opt
-  PRIVATE ${spirv-tools_SOURCE_DIR}/include
+  PUBLIC ${spirv-tools_SOURCE_DIR}/include
   PUBLIC ${SPIRV_HEADER_INCLUDE_DIR}
 )
+# We need the assembling and disassembling functionalities in the main library.
+target_link_libraries(SPIRV-Tools-opt
+  PUBLIC ${SPIRV_TOOLS})
+
+install(TARGETS SPIRV-Tools-opt
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
diff --git a/source/opt/build_module.cpp b/source/opt/build_module.cpp
index 1a4bc37..2800c09 100644
--- a/source/opt/build_module.cpp
+++ b/source/opt/build_module.cpp
@@ -15,7 +15,6 @@
 #include "build_module.h"
 
 #include "ir_loader.h"
-#include "libspirv.hpp"
 #include "make_unique.h"
 #include "table.h"
 
diff --git a/source/opt/build_module.h b/source/opt/build_module.h
index e3464c8..1dc2c11 100644
--- a/source/opt/build_module.h
+++ b/source/opt/build_module.h
@@ -19,9 +19,8 @@
 #include <string>
 #include <vector>
 
-#include "message.h"
 #include "module.h"
-#include "spirv-tools/libspirv.h"
+#include "spirv-tools/libspirv.hpp"
 
 namespace spvtools {
 
diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp
index da337db..abe5b93 100644
--- a/source/opt/optimizer.cpp
+++ b/source/opt/optimizer.cpp
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "optimizer.hpp"
+#include "spirv-tools/optimizer.hpp"
 
 #include "build_module.h"
 #include "make_unique.h"
diff --git a/source/table.h b/source/table.h
index a1f5277..6b86313 100644
--- a/source/table.h
+++ b/source/table.h
@@ -26,12 +26,12 @@
 // The known SPIR-V extensions.
 // TODO(dneto): Consider auto-generating this list?
 enum class Extension {
-  kSPV_KHR_shader_ballot
+  kSPV_KHR_shader_ballot,
 };
 
 using ExtensionSet = EnumSet<Extension>;
 
-} // namespace libspirv
+}  // namespace libspirv
 
 typedef struct spv_opcode_desc_t {
   const char* name;
diff --git a/source/validate_cfg.cpp b/source/validate_cfg.cpp
index 321acbb..ac81f75 100644
--- a/source/validate_cfg.cpp
+++ b/source/validate_cfg.cpp
@@ -14,10 +14,10 @@
 
 #include "validate.h"
 
-#include <cassert>
-
 #include <algorithm>
+#include <cassert>
 #include <functional>
+#include <iostream>
 #include <map>
 #include <string>
 #include <tuple>
diff --git a/test/BinaryParse.cpp b/test/BinaryParse.cpp
index d207f10..4ccf84d 100644
--- a/test/BinaryParse.cpp
+++ b/test/BinaryParse.cpp
@@ -284,7 +284,7 @@
   auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
   int invocation = 0;
   SetContextMessageConsumer(
-      ctx, [&invocation](spvtools::spv_message_level_t, const char*,
+      ctx, [&invocation](spv_message_level_t, const char*,
                          const spv_position_t&, const char*) { ++invocation; });
 
   EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS));
@@ -303,11 +303,10 @@
   auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
   int invocation = 0;
   SetContextMessageConsumer(
-      ctx,
-      [&invocation](spvtools::spv_message_level_t level, const char* source,
-                    const spv_position_t& position, const char* message) {
+      ctx, [&invocation](spv_message_level_t level, const char* source,
+                         const spv_position_t& position, const char* message) {
         ++invocation;
-        EXPECT_EQ(spvtools::SPV_MSG_ERROR, level);
+        EXPECT_EQ(SPV_MSG_ERROR, level);
         EXPECT_STREQ("input", source);
         EXPECT_EQ(0u, position.line);
         EXPECT_EQ(0u, position.column);
@@ -332,7 +331,7 @@
   auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
   int invocation = 0;
   SetContextMessageConsumer(
-      ctx, [&invocation](spvtools::spv_message_level_t, const char*,
+      ctx, [&invocation](spv_message_level_t, const char*,
                          const spv_position_t&, const char*) { ++invocation; });
 
   EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS));
@@ -352,7 +351,7 @@
   auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
   int invocation = 0;
   SetContextMessageConsumer(
-      ctx, [&invocation](spvtools::spv_message_level_t, const char*,
+      ctx, [&invocation](spv_message_level_t, const char*,
                          const spv_position_t&, const char*) { ++invocation; });
 
   words.push_back(0xffffffff);  // Certainly invalid instruction header.
diff --git a/test/TextLiteral.cpp b/test/TextLiteral.cpp
index cfc7584..c866bda 100644
--- a/test/TextLiteral.cpp
+++ b/test/TextLiteral.cpp
@@ -169,7 +169,7 @@
                                        libspirv::IdTypeClass type) {
   spv_instruction_t inst;
   std::string message;
-  auto capture_message = [&message](spvtools::spv_message_level_t, const char*,
+  auto capture_message = [&message](spv_message_level_t, const char*,
                                     const spv_position_t&,
                                     const char* m) { message = m; };
   libspirv::IdType expected_type{test.bitwidth, test.is_signed, type};
@@ -185,7 +185,7 @@
                          libspirv::IdTypeClass type) {
   spv_instruction_t inst;
   std::string message;
-  auto capture_message = [&message](spvtools::spv_message_level_t, const char*,
+  auto capture_message = [&message](spv_message_level_t, const char*,
                                     const spv_position_t&,
                                     const char* m) { message = m; };
   libspirv::IdType expected_type{test.bitwidth, test.is_signed, type};
diff --git a/test/cpp_interface.cpp b/test/cpp_interface.cpp
index b7ca5b7..a4fc1e8 100644
--- a/test/cpp_interface.cpp
+++ b/test/cpp_interface.cpp
@@ -15,7 +15,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-#include "opt/optimizer.hpp"
+#include "spirv-tools/optimizer.hpp"
 #include "spirv/1.1/spirv.h"
 
 namespace {
diff --git a/test/opt/CMakeLists.txt b/test/opt/CMakeLists.txt
index 737239d..6a7d604 100644
--- a/test/opt/CMakeLists.txt
+++ b/test/opt/CMakeLists.txt
@@ -14,48 +14,48 @@
 
 add_spvtools_unittest(TARGET instruction
   SRCS test_instruction.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET ir_loader
   SRCS test_ir_loader.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_manager
   SRCS module_utils.h
        test_pass_manager.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_strip_debug_info
   SRCS test_strip_debug_info.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_freeze_spec_const
   SRCS test_freeze_spec_const.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_eliminate_dead_const
   SRCS test_eliminate_dead_const.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_utils
   SRCS test_utils.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET def_use
   SRCS test_def_use.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET assembly_builder
   SRCS test_assembly_builder.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET types
@@ -65,36 +65,36 @@
 
 add_spvtools_unittest(TARGET type_manager
   SRCS test_type_manager.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET iterator
   SRCS test_iterator.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET module
   SRCS module_utils.h
        test_module.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_fold_spec_const_op_composite
   SRCS test_fold_spec_const_op_composite.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_unify_const
   SRCS test_unify_const.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET pass_set_spec_const_default_value
   SRCS test_set_spec_const_default_value.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
 
 add_spvtools_unittest(TARGET line_debug_info
   SRCS test_line_debug_info.cpp pass_utils.cpp
-  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+  LIBS SPIRV-Tools-opt
 )
diff --git a/test/opt/pass_fixture.h b/test/opt/pass_fixture.h
index dedd356..d19a2a5 100644
--- a/test/opt/pass_fixture.h
+++ b/test/opt/pass_fixture.h
@@ -23,10 +23,10 @@
 #include <gtest/gtest.h>
 
 #include "opt/build_module.h"
-#include "opt/libspirv.hpp"
 #include "opt/make_unique.h"
 #include "opt/pass_manager.h"
 #include "opt/passes.h"
+#include "spirv-tools/libspirv.hpp"
 
 namespace spvtools {
 
diff --git a/test/opt/test_def_use.cpp b/test/opt/test_def_use.cpp
index 6e2af62..8d8057a 100644
--- a/test/opt/test_def_use.cpp
+++ b/test/opt/test_def_use.cpp
@@ -20,8 +20,8 @@
 
 #include "opt/build_module.h"
 #include "opt/def_use_manager.h"
-#include "opt/libspirv.hpp"
 #include "pass_utils.h"
+#include "spirv-tools/libspirv.hpp"
 
 namespace {
 
diff --git a/test/opt/test_ir_loader.cpp b/test/opt/test_ir_loader.cpp
index 4ef49bd..11fe019 100644
--- a/test/opt/test_ir_loader.cpp
+++ b/test/opt/test_ir_loader.cpp
@@ -15,8 +15,9 @@
 #include <gtest/gtest.h>
 #include <algorithm>
 
+#include "message.h"
 #include "opt/build_module.h"
-#include "opt/libspirv.hpp"
+#include "spirv-tools/libspirv.hpp"
 
 namespace {
 
diff --git a/test/opt/test_module.cpp b/test/opt/test_module.cpp
index e76817b..c7e4907 100644
--- a/test/opt/test_module.cpp
+++ b/test/opt/test_module.cpp
@@ -17,9 +17,10 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
+#include "message.h"
 #include "opt/build_module.h"
-#include "opt/libspirv.hpp"
 #include "opt/module.h"
+#include "spirv-tools/libspirv.hpp"
 
 #include "module_utils.h"