Reimplement the DecorationManager
[platform/upstream/SPIRV-Tools.git] / CMakeLists.txt
index 58d1bef..60c606d 100644 (file)
-# Copyright (c) 2015 The Khronos Group Inc.
+# Copyright (c) 2015-2016 The Khronos Group Inc.
 #
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and/or associated documentation files (the
-# "Materials"), to deal in the Materials without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Materials, and to
-# permit persons to whom the Materials are furnished to do so, subject to
-# the following conditions:
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Materials.
+#     http://www.apache.org/licenses/LICENSE-2.0
 #
-# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
-# KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
-# SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
-#    https://www.khronos.org/registry/
-#
-# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
-
-cmake_minimum_required(VERSION 2.8)
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 2.8.12)
+if (POLICY CMP0048)
+  cmake_policy(SET CMP0048 NEW)
+endif()
+if (POLICY CMP0054)
+  # Avoid dereferencing variables or interpret keywords that have been
+  # quoted or bracketed.
+  # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html
+  cmake_policy(SET CMP0054 NEW)
+endif()
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
 project(spirv-tools)
+enable_testing()
+set(SPIRV_TOOLS "SPIRV-Tools")
+
+include(GNUInstallDirs)
+
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
   add_definitions(-DSPIRV_LINUX)
 elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
   add_definitions(-DSPIRV_WINDOWS)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
+  add_definitions(-DSPIRV_WINDOWS)
 elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
   add_definitions(-DSPIRV_MAC)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
+  add_definitions(-DSPIRV_ANDROID)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
+  add_definitions(-DSPIRV_FREEBSD)
 else()
   message(FATAL_ERROR "Your platform '${CMAKE_SYSTEM_NAME}' is not supported!")
 endif()
 
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
-if (UNIX)
-  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
-elseif(WIN32)
-  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
-endif()
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
 
-if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
   message(STATUS "No build type selected, default to Debug")
   set(CMAKE_BUILD_TYPE "Debug")
 endif()
 
-if(UNIX)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-exceptions -fno-rtti")
-  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
-    set(SPIRV_USE_SANITIZER "" CACHE STRING
-      "Use the clang sanitizer [address|memory|thread|...]")
-    if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "")
-      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${SPIRV_USE_SANITIZER}")
-      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${SPIRV_USE_SANITIZER}")
-    endif()
-  endif()
+option(SKIP_SPIRV_TOOLS_INSTALL "Skip installation" ${SKIP_SPIRV_TOOLS_INSTALL})
+if(NOT ${SKIP_SPIRV_TOOLS_INSTALL})
+  set(ENABLE_SPIRV_TOOLS_INSTALL ON)
 endif()
 
-if(UNIX)
-  option(SPIRV_COLOR_TERMINAL "Enable color terminal output" ON)
-  if(${SPIRV_COLOR_TERMINAL})
-    add_definitions(-DSPV_COLOR_TERMINAL)
-  endif()
+option(SPIRV_BUILD_COMPRESSION "Build SPIR-V compressing codec" OFF)
+
+option(SPIRV_WERROR "Enable error on warning" ON)
+if(("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
+  set(COMPILER_IS_LIKE_GNU TRUE)
 endif()
+if(${COMPILER_IS_LIKE_GNU})
+  set(SPIRV_WARNINGS -Wall -Wextra -Wnon-virtual-dtor -Wno-missing-field-initializers)
 
-if(UNIX)
-  set(SPIRV_WARNINGS "-Wall -Wextra -Wno-missing-field-initializers")
-  option(SPIRV_WARN_EVERYTHING "Enable -Weverything for SPIRV library" OFF)
+  option(SPIRV_WARN_EVERYTHING "Enable -Weverything" ${SPIRV_WARN_EVERYTHING})
   if(${SPIRV_WARN_EVERYTHING})
-    set(SPIRV_WARNINGS
-      "${SPIRV_WARNINGS} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded")
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+      set(SPIRV_WARNINGS ${SPIRV_WARNINGS}
+        -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded)
+    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+      set(SPIRV_WARNINGS ${SPIRV_WARNINGS} -Wpedantic -pedantic-errors)
+    else()
+      message(STATUS "Unknown compiler ${CMAKE_CXX_COMPILER_ID}, "
+                     "so SPIRV_WARN_EVERYTHING has no effect")
+    endif()
   endif()
-elseif(WIN32)
-  set(SPIRV_WARNINGS "-D_CRT_SECURE_NO_WARNINGS /wd4800")
-endif()
 
-if(UNIX)
-  option(SPIRV_WERROR "Enable error on warning" OFF)
   if(${SPIRV_WERROR})
-    set(SPIRV_WARNINGS "${SPIRV_WARNINGS} -Werror")
+    set(SPIRV_WARNINGS ${SPIRV_WARNINGS} -Werror)
+  endif()
+elseif(MSVC)
+  set(SPIRV_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS /wd4800)
+
+  if(${SPIRV_WERROR})
+    set(SPIRV_WARNINGS ${SPIRV_WARNINGS} /WX)
   endif()
 endif()
 
-include_directories(SYSTEM
-  ${CMAKE_CURRENT_SOURCE_DIR}/external/include)
-
-include_directories(
-  ${CMAKE_CURRENT_SOURCE_DIR}/include)
-
-set(SPIRV_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}/include/libspirv/libspirv.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/bitwisecast.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/binary.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/diagnostic.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/opcode.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/operand.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/print.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/text.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/text_handler.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/validate.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/binary.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/diagnostic.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/ext_inst.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/opcode.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/operand.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/print.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/text.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/text_handler.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/validate.cpp
-  ${CMAKE_CURRENT_SOURCE_DIR}/source/validate_id.cpp)
-
-add_library(SPIRV-TOOLS ${SPIRV_SOURCES})
-target_link_libraries(SPIRV-TOOLS ${SPIRV_LIBS})
-set_target_properties(SPIRV-TOOLS PROPERTIES COMPILE_FLAGS ${SPIRV_WARNINGS})
-
-option(SPIRV_SKIP_EXECUTABLES "Skip building the executables and tests along with the library" ${SPIRV_SKIP_EXECUTABLES})
-
-set(SPIRV_BUILT_TARGETS SPIRV-TOOLS)
-if (NOT ${SPIRV_SKIP_EXECUTABLES})
-  list(APPEND SPIRV_BUILT_TARGETS spirv-as spirv-dis spirv-val)
-  add_executable(spirv-as
-    ${CMAKE_CURRENT_SOURCE_DIR}/include/libspirv/libspirv.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/tools/as/as.cpp)
-  set_target_properties(spirv-as PROPERTIES COMPILE_FLAGS ${SPIRV_WARNINGS})
-  target_link_libraries(spirv-as SPIRV-TOOLS)
-
-  add_executable(spirv-dis
-    ${CMAKE_CURRENT_SOURCE_DIR}/include/libspirv/libspirv.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/tools/dis/dis.cpp)
-  set_target_properties(spirv-dis PROPERTIES COMPILE_FLAGS ${SPIRV_WARNINGS})
-  target_link_libraries(spirv-dis SPIRV-TOOLS)
-
-  add_executable(spirv-val
-    ${CMAKE_CURRENT_SOURCE_DIR}/include/libspirv/libspirv.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/tools/val/val.cpp)
-  set_target_properties(spirv-val PROPERTIES COMPILE_FLAGS ${SPIRV_WARNINGS})
-  target_link_libraries(spirv-val SPIRV-TOOLS)
-
-  set(GTEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/googletest)
-  if(EXISTS ${GTEST_DIR})
-    if(WIN32)
-      option(gtest_force_shared_crt
-        "Use shared (DLL) run-time lib even when Google Test is built as static lib."
-        ON)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source)
+
+option(SPIRV_COLOR_TERMINAL "Enable color terminal output" ON)
+if(${SPIRV_COLOR_TERMINAL})
+  add_definitions(-DSPIRV_COLOR_TERMINAL)
+endif()
+
+option(SPIRV_LOG_DEBUG "Enable excessive debug output" OFF)
+if(${SPIRV_LOG_DEBUG})
+  add_definitions(-DSPIRV_LOG_DEBUG)
+endif()
+
+if (DEFINED SPIRV_TOOLS_EXTRA_DEFINITIONS)
+  add_definitions(${SPIRV_TOOLS_EXTRA_DEFINITIONS})
+endif()
+
+function(spvtools_default_compile_options TARGET)
+  target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS})
+
+  if (${COMPILER_IS_LIKE_GNU})
+    target_compile_options(${TARGET} PRIVATE
+      -std=c++11 -fno-exceptions -fno-rtti)
+    target_compile_options(${TARGET} PRIVATE
+      -Wall -Wextra -Wno-long-long -Wshadow -Wundef -Wconversion
+      -Wno-sign-conversion)
+    # For good call stacks in profiles, keep the frame pointers.
+    if(NOT "${SPIRV_PERF}" STREQUAL "")
+      target_compile_options(${TARGET} PRIVATE -fno-omit-frame-pointer)
     endif()
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+      set(SPIRV_USE_SANITIZER "" CACHE STRING
+        "Use the clang sanitizer [address|memory|thread|...]")
+      if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "")
+        target_compile_options(${TARGET} PRIVATE
+          -fsanitize=${SPIRV_USE_SANITIZER})
+      endif()
+    else()
+      target_compile_options(${TARGET} PRIVATE
+         -Wno-missing-field-initializers)
+    endif()
+  endif()
 
-    add_subdirectory(${GTEST_DIR})
+  if (MSVC)
+    # Specify /EHs for exception handling. This makes using SPIRV-Tools as
+    # dependencies in other projects easier.
+    target_compile_options(${TARGET} PRIVATE /EHs)
   endif()
-  if (TARGET gmock)
-    message(STATUS "Found Google Mock, building tests.")
-
-    include_directories(SYSTEM
-      ${gmock_SOURCE_DIR}/include
-      ${gtest_SOURCE_DIR}/include)
-
-    add_executable(UnitSPIRV
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TestFixture.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/UnitSPIRV.h
-
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/AssemblyFormat.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryDestroy.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryEndianness.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryHeaderGet.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryToText.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/Comment.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/DiagnosticPrint.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/ExtInstGLSLstd450.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/FixWord.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/ImmediateInt.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/LibspirvMacros.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/NamedId.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OperandCapabilities.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OperandPattern.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeMake.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeRequiresCapabilities.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeSplit.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeTableGet.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/OperandTableGet.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextAdvance.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextDestroy.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextLiteral.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextStartsNewInst.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Annotation.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Barrier.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Constant.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.ControlFlow.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Debug.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.DeviceSideEnqueue.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Function.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Group.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Image.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Literal.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Memory.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.Miscellaneous.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.ModeSetting.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextToBinary.TypeDeclaration.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/TextWordGet.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/UnitSPIRV.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/Validate.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/ValidateID.cpp
-      ${CMAKE_CURRENT_SOURCE_DIR}/test/main.cpp)
-    target_link_libraries(UnitSPIRV SPIRV-TOOLS gmock)
-  else()
-    message(STATUS "Did not find googletest, tests will not be built."
-      "To enable tests place googletest in '<spirv-dir>/external/googletest'.")
+
+  # For MinGW cross compile, statically link to the C++ runtime.
+  # But it still depends on MSVCRT.dll.
+  if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+    if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
+      set_target_properties(${TARGET} PROPERTIES
+        LINK_FLAGS -static -static-libgcc -static-libstdc++)
+    endif()
   endif()
+endfunction()
+
+if(NOT COMMAND find_host_package)
+  macro(find_host_package)
+    find_package(${ARGN})
+  endmacro()
+endif()
+if(NOT COMMAND find_host_program)
+  macro(find_host_program)
+    find_program(${ARGN})
+  endmacro()
 endif()
 
-set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/install)
-install(TARGETS ${SPIRV_BUILT_TARGETS}
-  RUNTIME DESTINATION bin
-  LIBRARY DESTINATION lib
-  ARCHIVE DESTINATION lib)
+find_host_package(PythonInterp)
 
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/libspirv/libspirv.h
-  DESTINATION include/libspirv/)
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+  macro(spvtools_check_symbol_exports TARGET)
+    add_test(NAME spirv-tools-symbol-exports-${TARGET}
+             COMMAND ${PYTHON_EXECUTABLE}
+             ${spirv-tools_SOURCE_DIR}/utils/check_symbol_exports.py "$<TARGET_FILE:${TARGET}>")
+  endmacro()
+else()
+  macro(spvtools_check_symbol_exports TARGET)
+    message("Skipping symbol exports test for ${TARGET}")
+  endmacro()
+endif()
+
+# Defaults to OFF if the user didn't set it.
+option(SPIRV_SKIP_EXECUTABLES
+  "Skip building the executable and tests along with the library"
+  ${SPIRV_SKIP_EXECUTABLES})
+option(SPIRV_SKIP_TESTS
+  "Skip building tests along with the library" ${SPIRV_SKIP_TESTS})
+if ("${SPIRV_SKIP_EXECUTABLES}")
+  set(SPIRV_SKIP_TESTS ON)
+endif()
+
+# Defaults to ON.  The checks can be time consuming.
+# Turn off if they take too long.
+option(SPIRV_CHECK_CONTEXT "In a debug build, check if the IR context is in a valid state." ON)
+if (${SPIRV_CHECK_CONTEXT})
+  add_definitions(-DSPIRV_CHECK_CONTEXT)
+endif()
+
+add_subdirectory(external)
+
+if (TARGET effcee)
+  add_definitions(-DSPIRV_EFFCEE)
+endif()
+
+add_subdirectory(source)
+add_subdirectory(tools)
+
+add_subdirectory(test)
+add_subdirectory(examples)
+
+if(ENABLE_SPIRV_TOOLS_INSTALL)
+  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
+      ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/linker.hpp
+    DESTINATION
+      ${CMAKE_INSTALL_INCLUDEDIR}/spirv-tools/)
+endif(ENABLE_SPIRV_TOOLS_INSTALL)
+
+if (NOT "${SPIRV_SKIP_TESTS}")
+  add_test(NAME spirv-tools-copyrights
+           COMMAND ${PYTHON_EXECUTABLE} utils/check_copyright.py
+           WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+set(SPIRV_LIBRARIES "-lSPIRV-Tools -lSPIRV-Tools-link -lSPIRV-Tools-opt")
+set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
+if(SPIRV_BUILD_COMPRESSION)
+  set(SPIRV_LIBRARIES "${SPIRV_LIBRARIES} -lSPIRV-Tools-comp")
+endif(SPIRV_BUILD_COMPRESSION)
+
+# Build pkg-config file
+# Use a first-class target so it's regenerated when relevant files are updated.
+add_custom_target(spirv-tools-pkg-config ALL
+        COMMAND ${CMAKE_COMMAND}
+                      -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
+                      -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in
+                      -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
+                      -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
+                      -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
+                      -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
+                      -DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
+                      -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
+        DEPENDS "CHANGES" "cmake/SPIRV-Tools.pc.in" "cmake/write_pkg_config.cmake")
+add_custom_target(spirv-tools-shared-pkg-config ALL
+        COMMAND ${CMAKE_COMMAND}
+                      -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
+                      -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in
+                      -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
+                      -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
+                      -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
+                      -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
+                      -DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
+                      -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
+        DEPENDS "CHANGES" "cmake/SPIRV-Tools-shared.pc.in" "cmake/write_pkg_config.cmake")
+
+# Install pkg-config file
+if (ENABLE_SPIRV_TOOLS_INSTALL)
+  install(
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
+      ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
+    DESTINATION
+      ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+endif()