CMake: split out Vulkan sources into separate CMakeLists

Add CMakeLists.txt to the following folders under src that create the
following targets:

Device -> vk_device
Pipeline -> vk_pipeline
WSI -> vk_wsi
System -> vk_system
Vulkan -> vk_swiftshader

Dependencies (by folder):

System --> n/a
Pipeline --> System Device* Vulkan*
WSI --> System Pipeline Vulkan*
Device --> System Pipeline Vulkan*
Vulkan --> Device Pipeline WSI System

* = dependency by include directory only (should fix this in the future)

Also make system-unittests and system-benchmarks depend on vk_system
rather than build part of System source files.

Bug: b/145758253
Change-Id: I9cce59ca90d91601696f6195326b5fd7dde517d5
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43690
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8aed906..541570d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,16 +18,6 @@
 
 project(SwiftShader C CXX ASM)
 
-# On Windows we use custom solution and project files, except for certain third-
-# party projects which use CMake-generated ones. They are manually (re)generated
-# and made path relative using build/cmake.sh, so they can be checked into the
-# repository. Therefore they should not be auto-regenerated and left using
-# absolute paths by CMake's ZERO_CHECK.
-if(WIN32)
-    # Disable automatically regenerating project files on CMakeLists.txt changes.
-    set(CMAKE_SUPPRESS_REGENERATION true)
-endif()
-
 ###########################################################
 # Detect system
 ###########################################################
@@ -311,9 +301,6 @@
 ###########################################################
 
 set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
-set(OPENGL_DIR ${SOURCE_DIR}/OpenGL)
-set(OPENGL_COMPILER_DIR ${OPENGL_DIR}/compiler)
-set(VULKAN_DIR ${SOURCE_DIR}/Vulkan)
 set(THIRD_PARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party)
 set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
 set(HELLO2_DIR ${THIRD_PARTY_DIR}/PowerVR_SDK/Examples/Beginner/01_HelloAPI/OGLES2)
@@ -571,6 +558,7 @@
         list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-fno-exceptions")
     endif()
 endif()
+unset(USE_EXCEPTIONS)
 
 # Transform SWIFTSHADER_LINK_FLAGS from semicolon delimited to whitespace
 # delimited (what is expected by LINK_FLAGS)
@@ -634,110 +622,20 @@
 # Include Directories
 ###########################################################
 
-set(COMMON_INCLUDE_DIR
+set(VULKAN_INCLUDE_DIR
     ${SOURCE_DIR}
     ${CMAKE_CURRENT_SOURCE_DIR}/include
 )
-set(OPENGL_INCLUDE_DIR
-    ${OPENGL_DIR}
-    ${COMMON_INCLUDE_DIR}
-)
-
-set(VULKAN_INCLUDE_DIR
-    ${COMMON_INCLUDE_DIR}
-)
 
 ###########################################################
 # File Lists
 ###########################################################
 
-
-file(GLOB VULKAN_LIST
-    ${VULKAN_DIR}/*.cpp
-    ${VULKAN_DIR}/*.h
-    ${VULKAN_DIR}/*.hpp
-    ${SOURCE_DIR}/System/Build.cpp
-    ${SOURCE_DIR}/System/Build.hpp
-    ${SOURCE_DIR}/System/CPUID.cpp
-    ${SOURCE_DIR}/System/CPUID.hpp
-    ${SOURCE_DIR}/System/Configurator.cpp
-    ${SOURCE_DIR}/System/Configurator.hpp
-    ${SOURCE_DIR}/System/Debug.cpp
-    ${SOURCE_DIR}/System/Debug.hpp
-    ${SOURCE_DIR}/System/Half.cpp
-    ${SOURCE_DIR}/System/Half.hpp
-    ${SOURCE_DIR}/System/Math.cpp
-    ${SOURCE_DIR}/System/Math.hpp
-    ${SOURCE_DIR}/System/Memory.cpp
-    ${SOURCE_DIR}/System/Memory.hpp
-    ${SOURCE_DIR}/System/Socket.cpp
-    ${SOURCE_DIR}/System/Socket.hpp
-    ${SOURCE_DIR}/System/Synchronization.hpp
-    ${SOURCE_DIR}/System/Timer.cpp
-    ${SOURCE_DIR}/System/Timer.hpp
-    ${SOURCE_DIR}/Device/*.cpp
-    ${SOURCE_DIR}/Device/*.hpp
-    ${SOURCE_DIR}/Pipeline/*.cpp
-    ${SOURCE_DIR}/Pipeline/*.hpp
-    ${SOURCE_DIR}/WSI/VkSurfaceKHR.cpp
-    ${SOURCE_DIR}/WSI/VkSurfaceKHR.hpp
-    ${SOURCE_DIR}/WSI/VkSwapchainKHR.cpp
-    ${SOURCE_DIR}/WSI/VkSwapchainKHR.hpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan/*.h
-)
-
-if(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER)
-    file(GLOB_RECURSE VULKAN_DEBUG_LIST
-        ${VULKAN_DIR}/Debug/*.cpp
-        ${VULKAN_DIR}/Debug/*.h
-        ${VULKAN_DIR}/Debug/*.hpp
-    )
-    list(APPEND VULKAN_LIST ${VULKAN_DEBUG_LIST})
-    list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_VK_DEBUGGER")
-endif()
-
-if(LINUX OR ANDROID)
-    list(APPEND VULKAN_LIST
-        ${SOURCE_DIR}/System/Linux/MemFd.cpp
-        ${SOURCE_DIR}/System/Linux/MemFd.hpp
-    )
-endif()
-
 ###########################################################
 # Append OS specific files to lists
 ###########################################################
 
 if(WIN32)
-    list(APPEND VULKAN_LIST
-        ${VULKAN_DIR}/Vulkan.rc
-        ${SOURCE_DIR}/WSI/Win32SurfaceKHR.cpp
-        ${SOURCE_DIR}/WSI/Win32SurfaceKHR.hpp
-    )
-elseif(LINUX)
-    if(X11)
-        list(APPEND VULKAN_LIST
-            ${SOURCE_DIR}/WSI/XlibSurfaceKHR.cpp
-            ${SOURCE_DIR}/WSI/XlibSurfaceKHR.hpp
-            ${SOURCE_DIR}/WSI/libX11.cpp
-            ${SOURCE_DIR}/WSI/libX11.hpp
-        )
-    endif()
-
-    if(XCB)
-        list(APPEND VULKAN_LIST
-            ${SOURCE_DIR}/WSI/XcbSurfaceKHR.cpp
-            ${SOURCE_DIR}/WSI/XcbSurfaceKHR.hpp
-        )
-    endif()
-
-elseif(APPLE)
-    list(APPEND VULKAN_LIST
-        ${SOURCE_DIR}/WSI/MetalSurface.mm
-        ${SOURCE_DIR}/WSI/MetalSurface.h
-    )
-endif()
-
-if(WIN32)
     set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid)
 elseif(LINUX)
     set(OS_LIBS dl pthread)
@@ -796,119 +694,44 @@
 endif(SWIFTSHADER_BUILD_GLES_CM)
 
 if(SWIFTSHADER_BUILD_VULKAN)
-    add_library(vk_swiftshader SHARED ${VULKAN_LIST})
-
     if (NOT TARGET SPIRV-Tools)
         # This variable is also used by SPIRV-Tools to locate SPIRV-Headers
         set(SPIRV-Headers_SOURCE_DIR "${THIRD_PARTY_DIR}/SPIRV-Headers")
-        list(APPEND VULKAN_INCLUDE_DIR "${SPIRV-Headers_SOURCE_DIR}/include")
         set(SPIRV_SKIP_TESTS TRUE CACHE BOOL "" FORCE)
-        add_subdirectory(third_party/SPIRV-Tools)
-
-        set_target_properties(core_tables PROPERTIES FOLDER "SPIRV-Tools build")
-        set_target_properties(enum_string_mapping PROPERTIES FOLDER "SPIRV-Tools build")
-        set_target_properties(extinst_tables PROPERTIES FOLDER "SPIRV-Tools build")
-        set_target_properties(spirv-tools-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
-        set_target_properties(spirv-tools-shared-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
+        add_subdirectory(third_party/SPIRV-Tools) # Add SPIRV-Tools target
     endif()
 
-    # Copy the OpenCLDebugInfo100.h header that's generated by SPIRV-Tools
-    # out to a separate directory that can be added to the include path.
-    # Ideally, this header would just be pre-built and part of SPIRV-Headers.
-    # See: https://github.com/KhronosGroup/SPIRV-Headers/issues/137
-    set(SPIRV_TOOLS_EXT_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/spirv-tools-ext/include)
-    add_custom_command(
-        OUTPUT "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h"
-        DEPENDS spirv-tools-header-OpenCLDebugInfo100
-        COMMAND ${CMAKE_COMMAND} -E copy
-            "${spirv-tools_BINARY_DIR}/OpenCLDebugInfo100.h"
-            "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h"
-    )
-    add_custom_target(spirv_tools_ext_includes
-        DEPENDS "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h")
-    set_target_properties(spirv_tools_ext_includes PROPERTIES FOLDER "SPIRV-Tools build")
-    list(APPEND VULKAN_INCLUDE_DIR "${SPIRV_TOOLS_EXT_INC_DIR}")
-    add_dependencies(vk_swiftshader spirv_tools_ext_includes)
-
-    set(VULKAN_COMPILE_OPTIONS ${SWIFTSHADER_COMPILE_OPTIONS})
-    if(FUCHSIA)
-        # At the moment, the Fuchsia build uses unofficial VK_STRUCTURE_TYPE_XX
-        # constants that are defined as macros in <vulkan/fuchsia_extras.h>. When
-        # these appear in switch() cases, the compiler complains that the values
-        # are not part of the VkStructureType enum. Silence this warning, until
-        # the constants are upstreamed to the official Vulkan headers.
-        list(APPEND VULKAN_COMPILE_OPTIONS "-Wno-switch")
+    # Add a vk_base interface library for shared vulkan build options.
+    # TODO: Create src/Base and make this a lib target, and move stuff from
+    # src/Vulkan into it that is needed by vk_pipeline, vk_device, and vk_wsi.
+    add_library(vk_base INTERFACE)
+    
+    if(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER)
+        target_compile_definitions(vk_base INTERFACE "ENABLE_VK_DEBUGGER")
     endif()
-    set_target_properties(vk_swiftshader PROPERTIES
-        INCLUDE_DIRECTORIES "${VULKAN_INCLUDE_DIR}"
-        FOLDER "Vulkan"
-        COMPILE_OPTIONS "${VULKAN_COMPILE_OPTIONS};${WARNINGS_AS_ERRORS}"
-        COMPILE_DEFINITIONS "VK_EXPORT=;NO_SANITIZE_FUNCTION=;$<$<CONFIG:Debug>:DEBUGGER_WAIT_DIALOG>"
-        LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
-    )
+
     if(WIN32)
-        set(VULKAN_API_LIBRARY_NAME "vulkan-1.dll")
-        set_property(TARGET vk_swiftshader APPEND
-                     PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_WIN32_KHR")
+        target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_WIN32_KHR")
     elseif(LINUX)
-        set(VULKAN_API_LIBRARY_NAME "libvulkan.so.1")
         if(X11)
-            set_property(TARGET vk_swiftshader APPEND
-                        PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XLIB_KHR")
+            target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XLIB_KHR")
         endif()
         if(XCB)
-            set_property(TARGET vk_swiftshader APPEND
-                        PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XCB_KHR")
+            target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XCB_KHR")
         endif()
     elseif(APPLE)
-        set(VULKAN_API_LIBRARY_NAME "libvulkan.dylib")
-        set_property(TARGET vk_swiftshader APPEND
-                     PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_MACOS_MVK")
+        target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_MACOS_MVK")
     elseif(FUCHSIA)
-        set(VULKAN_API_LIBRARY_NAME "libvulkan.so")
-        set_property(TARGET vk_swiftshader APPEND
-                     PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_FUCHSIA")
-        # On Fuchsia, the Vulkan ICD is loaded into a process sandbox that doesn't
-        # have system libraries available, so ensure it does not depend on libc++.so.
-        set_property(TARGET vk_swiftshader APPEND
-                     PROPERTY LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS} -static-libstdc++")
+        target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_FUCHSIA")
     else()
         message(FATAL_ERROR "Platform does not support Vulkan yet")
     endif()
 
-    set_shared_library_export_map(vk_swiftshader ${SOURCE_DIR}/Vulkan)
-
-    set(VK_SWIFTSHADER_LIBS ${Reactor} marl ${OS_LIBS} SPIRV-Tools SPIRV-Tools-opt ${SWIFTSHADER_LIBS})
-    if(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER)
-        list(APPEND VK_SWIFTSHADER_LIBS cppdap)
-    endif()
-    if(SWIFTSHADER_ENABLE_ASTC)
-        list(APPEND VK_SWIFTSHADER_LIBS astc-encoder)
-    endif()
-    target_link_libraries(vk_swiftshader ${VK_SWIFTSHADER_LIBS})
-
-    add_custom_command(
-        TARGET vk_swiftshader
-        POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/
-        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vk_swiftshader> ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/
-        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vk_swiftshader> ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/${VULKAN_API_LIBRARY_NAME}
-    )
-
-    # The vk_swiftshader_icd.json manifest file will point to ICD_LIBRARY_PATH.
-    # Set ICD_LIBRARY_PATH to be a relative path similar to "./libvk_swiftshader.so", so both files can be moved.
-    # A relative path is relative to the manifest file.
-    set(ICD_LIBRARY_PATH "${CMAKE_SHARED_LIBRARY_PREFIX}vk_swiftshader${CMAKE_SHARED_LIBRARY_SUFFIX}")
-    if(WIN32)
-        # The path is output to a JSON file, which requires backslashes to be escaped.
-        set(ICD_LIBRARY_PATH ".\\\\${ICD_LIBRARY_PATH}")
-    else()
-        set(ICD_LIBRARY_PATH "./${ICD_LIBRARY_PATH}")
-    endif()
-    configure_file(
-        "${VULKAN_DIR}/vk_swiftshader_icd.json.tmpl"
-        "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/vk_swiftshader_icd.json"
-    )
+    add_subdirectory(src/System) # Add vk_system target
+    add_subdirectory(src/Pipeline) # Add vk_pipeline target
+    add_subdirectory(src/WSI) # Add vk_wsi target
+    add_subdirectory(src/Device) # Add vk_device target
+    add_subdirectory(src/Vulkan) # Add vk_swiftshader target
 
     if(SWIFTSHADER_EMIT_COVERAGE)
         add_executable(turbo-cov ${TESTS_DIR}/regres/cov/turbo-cov/main.cpp)
@@ -996,18 +819,6 @@
         ${TESTS_DIR}/SystemUnitTests/unittests.cpp
     )
 
-    # TODO: Replace with dep on System static target
-    list(APPEND SYSTEM_UNITTESTS_LIST
-        ${SOURCE_DIR}/System/Debug.cpp
-        ${SOURCE_DIR}/System/Memory.cpp
-    )
-    if(LINUX OR ANDROID)
-        list(APPEND SYSTEM_UNITTESTS_LIST
-            ${SOURCE_DIR}/System/Linux/MemFd.cpp
-            ${SOURCE_DIR}/System/Linux/MemFd.hpp
-        )
-    endif()
-
     set(SYSTEM_UNITTESTS_INCLUDE_DIR
         ${CMAKE_CURRENT_SOURCE_DIR}/src/
     )
@@ -1020,7 +831,7 @@
         LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
     )
 
-    target_link_libraries(system-unittests gtest gmock)
+    target_link_libraries(system-unittests vk_system gtest gmock)
     if(NOT WIN32)
         target_link_libraries(system-unittests pthread ${SWIFTSHADER_LIBS})
     endif()
@@ -1048,8 +859,6 @@
 
     # System benchmarks
     set(SYSTEM_BENCHMARKS_LIST
-        ${SOURCE_DIR}/System/Debug.cpp
-
         ${TESTS_DIR}/SystemBenchmarks/main.cpp
         ${TESTS_DIR}/SystemBenchmarks/LRUCacheBenchmarks.cpp
     )
@@ -1067,7 +876,7 @@
         FOLDER "Benchmarks"
     )
 
-    target_link_libraries(system-benchmarks gtest gmock)
+    target_link_libraries(system-benchmarks vk_system gtest gmock)
     if(NOT WIN32)
         target_link_libraries(system-benchmarks pthread ${SWIFTSHADER_LIBS})
     endif()
diff --git a/src/Device/CMakeLists.txt b/src/Device/CMakeLists.txt
new file mode 100644
index 0000000..fae3be4
--- /dev/null
+++ b/src/Device/CMakeLists.txt
@@ -0,0 +1,80 @@
+# Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+#
+# 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
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+set(ROOT_PROJECT_COMPILE_OPTIONS
+    ${SWIFTSHADER_COMPILE_OPTIONS}
+    ${WARNINGS_AS_ERRORS}
+)
+
+set(DEVICE_SRC_FILES
+    ASTC_Decoder.cpp
+    ASTC_Decoder.hpp
+    BC_Decoder.cpp
+    BC_Decoder.hpp
+    Blitter.cpp
+    Blitter.hpp
+    Clipper.cpp
+    Clipper.hpp
+    Config.hpp
+    Context.cpp
+    Context.hpp
+    ETC_Decoder.cpp
+    ETC_Decoder.hpp
+    LRUCache.hpp
+    Memset.hpp
+    PixelProcessor.cpp
+    PixelProcessor.hpp
+    Polygon.hpp
+    Primitive.hpp
+    QuadRasterizer.cpp
+    QuadRasterizer.hpp
+    Rasterizer.hpp
+    Renderer.cpp
+    Renderer.hpp
+    RoutineCache.hpp
+    Sampler.hpp
+    SetupProcessor.cpp
+    SetupProcessor.hpp
+    Stream.hpp
+    Triangle.hpp
+    Vertex.hpp
+    VertexProcessor.cpp
+    VertexProcessor.hpp
+)
+
+add_library(vk_device EXCLUDE_FROM_ALL
+    ${DEVICE_SRC_FILES}
+)
+
+set_target_properties(vk_device PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "SwiftShader VK"
+    LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
+)
+
+target_include_directories(vk_device
+    PUBLIC
+        ".."
+        "${CMAKE_SOURCE_DIR}/include"
+)
+
+target_compile_options(vk_device
+    PUBLIC
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+)
+
+target_link_libraries(vk_device
+    PUBLIC
+        vk_pipeline
+)
diff --git a/src/Pipeline/CMakeLists.txt b/src/Pipeline/CMakeLists.txt
new file mode 100644
index 0000000..992865d
--- /dev/null
+++ b/src/Pipeline/CMakeLists.txt
@@ -0,0 +1,113 @@
+# Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+#
+# 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
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+set(ROOT_PROJECT_COMPILE_OPTIONS
+    ${SWIFTSHADER_COMPILE_OPTIONS}
+    ${WARNINGS_AS_ERRORS}
+)
+
+set(PIPELINE_SRC_FILES
+    ComputeProgram.cpp
+    ComputeProgram.hpp
+    Constants.cpp
+    Constants.hpp
+    PixelProgram.cpp
+    PixelProgram.hpp
+    PixelRoutine.cpp
+    PixelRoutine.hpp
+    SamplerCore.cpp
+    SamplerCore.hpp
+    SetupRoutine.cpp
+    SetupRoutine.hpp
+    ShaderCore.cpp
+    ShaderCore.hpp
+    SpirvID.hpp
+    SpirvShader.cpp
+    SpirvShader.hpp
+    SpirvShaderArithmetic.cpp
+    SpirvShaderControlFlow.cpp
+    SpirvShaderDebugger.cpp
+    SpirvShaderEnumNames.cpp
+    SpirvShaderGLSLstd450.cpp
+    SpirvShaderGroup.cpp
+    SpirvShaderImage.cpp
+    SpirvShaderInstructions.cpp
+    SpirvShaderMemory.cpp
+    SpirvShaderSampling.cpp
+    SpirvShaderSpec.cpp
+    VertexProgram.cpp
+    VertexProgram.hpp
+    VertexRoutine.cpp
+    VertexRoutine.hpp
+)
+
+add_library(vk_pipeline EXCLUDE_FROM_ALL
+    ${PIPELINE_SRC_FILES}
+)
+
+# Add SPIRV-Tools dep
+if (NOT TARGET SPIRV-Tools)
+    message(FATAL_ERROR "Missing required target: SPIRV-Tools")
+endif()
+
+set_target_properties(core_tables PROPERTIES FOLDER "SPIRV-Tools build")
+set_target_properties(enum_string_mapping PROPERTIES FOLDER "SPIRV-Tools build")
+set_target_properties(extinst_tables PROPERTIES FOLDER "SPIRV-Tools build")
+set_target_properties(spirv-tools-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
+set_target_properties(spirv-tools-shared-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
+
+# Copy the OpenCLDebugInfo100.h header that's generated by SPIRV-Tools
+# out to a separate directory that can be added to the include path.
+# Ideally, this header would just be pre-built and part of SPIRV-Headers.
+# See: https://github.com/KhronosGroup/SPIRV-Headers/issues/137
+set(SPIRV_TOOLS_EXT_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/spirv-tools-ext/include)
+add_custom_command(
+    OUTPUT "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h"
+    DEPENDS spirv-tools-header-OpenCLDebugInfo100
+    COMMAND ${CMAKE_COMMAND} -E copy
+        "${spirv-tools_BINARY_DIR}/OpenCLDebugInfo100.h"
+        "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h"
+)
+add_custom_target(spirv_tools_ext_includes
+    DEPENDS "${SPIRV_TOOLS_EXT_INC_DIR}/spirv-tools/ext/OpenCLDebugInfo100.h")
+set_target_properties(spirv_tools_ext_includes PROPERTIES FOLDER "SPIRV-Tools build")
+add_dependencies(vk_pipeline spirv_tools_ext_includes)
+
+set_target_properties(vk_pipeline PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "SwiftShader VK"
+    LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
+)
+
+target_include_directories(vk_pipeline
+    PUBLIC
+        ".."
+        "${CMAKE_SOURCE_DIR}/include"
+        "${SPIRV-Headers_SOURCE_DIR}/include"
+        "${SPIRV_TOOLS_EXT_INC_DIR}"
+)
+
+target_compile_options(vk_pipeline
+    PUBLIC
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+)
+
+target_link_libraries(vk_pipeline
+    PUBLIC
+        vk_base
+        vk_system
+        marl
+        SPIRV-Tools
+        SPIRV-Tools-opt
+)
diff --git a/src/System/CMakeLists.txt b/src/System/CMakeLists.txt
new file mode 100644
index 0000000..d7d5f00
--- /dev/null
+++ b/src/System/CMakeLists.txt
@@ -0,0 +1,69 @@
+# Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+#
+# 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
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+set(ROOT_PROJECT_COMPILE_OPTIONS
+    ${SWIFTSHADER_COMPILE_OPTIONS}
+    ${WARNINGS_AS_ERRORS}
+)
+
+set(SYSTEM_SRC_FILES
+    Build.cpp
+    Build.hpp
+    Configurator.cpp
+    Configurator.hpp
+    CPUID.cpp
+    CPUID.hpp
+    Debug.cpp
+    Debug.hpp
+    Half.cpp
+    Half.hpp
+    Math.cpp
+    Math.hpp
+    Memory.cpp
+    Memory.hpp
+    SharedLibrary.hpp
+    Socket.cpp
+    Socket.hpp
+    Synchronization.hpp
+    Timer.cpp
+    Timer.hpp
+    Types.hpp
+)
+
+if(LINUX OR ANDROID)
+    list(APPEND SYSTEM_SRC_FILES
+        Linux/MemFd.cpp
+        Linux/MemFd.hpp
+    )
+endif()
+
+add_library(vk_system EXCLUDE_FROM_ALL
+    ${SYSTEM_SRC_FILES}
+)
+
+set_target_properties(vk_system PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "SwiftShader VK"
+    LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
+)
+
+target_include_directories(vk_system
+    PUBLIC
+        ".."
+)
+
+target_compile_options(vk_system
+    PUBLIC
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+)
diff --git a/src/Vulkan/CMakeLists.txt b/src/Vulkan/CMakeLists.txt
new file mode 100644
index 0000000..8faa997
--- /dev/null
+++ b/src/Vulkan/CMakeLists.txt
@@ -0,0 +1,220 @@
+# Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+#
+# 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
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+set(ROOT_PROJECT_COMPILE_OPTIONS
+    ${SWIFTSHADER_COMPILE_OPTIONS}
+    ${WARNINGS_AS_ERRORS}
+)
+
+set(VULKAN_SRC_FILES
+    libVulkan.cpp
+    main.cpp
+    resource.h
+    Version.h
+    VkBuffer.cpp
+    VkBuffer.hpp
+    VkBufferView.cpp
+    VkBufferView.hpp
+    VkCommandBuffer.cpp
+    VkCommandBuffer.hpp
+    VkCommandPool.cpp
+    VkCommandPool.hpp
+    VkConfig.h
+    VkDescriptorPool.cpp
+    VkDescriptorPool.hpp
+    VkDescriptorSet.hpp
+    VkDescriptorSetLayout.cpp
+    VkDescriptorSetLayout.hpp
+    VkDescriptorUpdateTemplate.cpp
+    VkDescriptorUpdateTemplate.hpp
+    VkDestroy.h
+    VkDevice.cpp
+    VkDevice.hpp
+    VkDeviceMemory.cpp
+    VkDeviceMemory.hpp
+    VkDeviceMemoryExternalAndroid.hpp
+    VkDeviceMemoryExternalLinux.hpp
+    VkEvent.hpp
+    VkFence.hpp
+    VkFormat.cpp
+    VkFormat.h
+    VkFramebuffer.cpp
+    VkFramebuffer.hpp
+    VkGetProcAddress.cpp
+    VkGetProcAddress.h
+    VkImage.cpp
+    VkImage.hpp
+    VkImageView.cpp
+    VkImageView.hpp
+    VkInstance.cpp
+    VkInstance.hpp
+    VkMemory.cpp
+    VkMemory.h
+    VkObject.hpp
+    VkPhysicalDevice.cpp
+    VkPhysicalDevice.hpp
+    VkPipeline.cpp
+    VkPipeline.hpp
+    VkPipelineCache.cpp
+    VkPipelineCache.hpp
+    VkPipelineLayout.cpp
+    VkPipelineLayout.hpp
+    VkPromotedExtensions.cpp
+    VkQueryPool.cpp
+    VkQueryPool.hpp
+    VkQueue.cpp
+    VkQueue.hpp
+    VkRenderPass.cpp
+    VkRenderPass.hpp
+    VkSampler.cpp
+    VkSampler.hpp
+    VkSemaphore.cpp
+    VkSemaphore.hpp
+    VkSemaphoreExternalFuchsia.hpp
+    VkSemaphoreExternalLinux.hpp
+    VkShaderModule.cpp
+    VkShaderModule.hpp
+    VkStringify.cpp
+    VkStringify.hpp
+    VulkanPlatform.h
+)
+
+if(WIN32)
+    list(APPEND VULKAN_SRC_FILES
+        Vulkan.rc
+    )
+endif()
+
+if(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER)
+    list(APPEND VULKAN_SRC_FILES
+        Context.cpp
+        Context.hpp
+        Debug.cpp
+        EventListener.hpp
+        File.cpp
+        File.hpp
+        ID.hpp
+        Location.hpp
+        Server.cpp
+        Server.hpp
+        Thread.cpp
+        Thread.hpp
+        Type.cpp
+        Type.hpp
+        Value.cpp
+        Value.hpp
+        Variable.hpp
+        WeakMap.hpp
+    )
+endif()
+
+set(VULKAN_COMPILE_OPTIONS "")
+if(FUCHSIA)
+    # At the moment, the Fuchsia build uses unofficial VK_STRUCTURE_TYPE_XX
+    # constants that are defined as macros in <vulkan/fuchsia_extras.h>. When
+    # these appear in switch() cases, the compiler complains that the values
+    # are not part of the VkStructureType enum. Silence this warning, until
+    # the constants are upstreamed to the official Vulkan headers.
+    list(APPEND VULKAN_COMPILE_OPTIONS "-Wno-switch")
+endif()
+
+set(VULKAN_LINKER_FLAGS "")
+if(FUCHSIA)
+    # On Fuchsia, the Vulkan ICD is loaded into a process sandbox that doesn't
+    # have system libraries available, so ensure it does not depend on libc++.so.
+    list(APPEND VULKAN_LINKER_FLAGS "-static-libstdc++")
+endif()
+# Convert list to space-delimited string for LINK_FLAGS
+string(REPLACE ";" " " VULKAN_LINKER_FLAGS "${VULKAN_LINKER_FLAGS}")
+
+add_library(vk_swiftshader SHARED
+    ${VULKAN_SRC_FILES}
+)
+
+set_target_properties(vk_swiftshader PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "SwiftShader VK"
+    LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS} ${VULKAN_LINKER_FLAGS}"
+    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+)
+
+target_include_directories(vk_swiftshader
+    PRIVATE
+        ".."
+        # "${CMAKE_SOURCE_DIR}/include"
+)
+
+target_compile_options(vk_swiftshader
+    PRIVATE
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+        ${VULKAN_COMPILE_OPTIONS}
+)
+
+target_compile_definitions(vk_swiftshader
+    PRIVATE
+        "VK_EXPORT="
+        $<$<CONFIG:Debug>:"DEBUGGER_WAIT_DIALOG">
+)
+
+target_link_libraries(vk_swiftshader
+    PRIVATE
+        vk_system
+        vk_pipeline
+        vk_device
+        vk_wsi
+        ${Reactor}
+        marl
+        ${OS_LIBS}
+        ${SWIFTSHADER_LIBS}
+        $<$<BOOL:${SWIFTSHADER_ENABLE_VULKAN_DEBUGGER}>:cppdap>
+        $<$<BOOL:${SWIFTSHADER_ENABLE_ASTC}>:astc-encoder>
+)
+
+set_shared_library_export_map(vk_swiftshader ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(WIN32)
+    set(VULKAN_API_LIBRARY_NAME "vulkan-1.dll")
+elseif(LINUX)
+    set(VULKAN_API_LIBRARY_NAME "libvulkan.so.1")
+elseif(APPLE)
+    set(VULKAN_API_LIBRARY_NAME "libvulkan.dylib")
+elseif(FUCHSIA)
+    set(VULKAN_API_LIBRARY_NAME "libvulkan.so")
+else()
+    message(FATAL_ERROR "Platform does not support Vulkan yet")
+endif()
+
+add_custom_command(
+    TARGET vk_swiftshader
+    POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/
+    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vk_swiftshader> ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/
+    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:vk_swiftshader> ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/${VULKAN_API_LIBRARY_NAME}
+)
+
+# The vk_swiftshader_icd.json manifest file will point to ICD_LIBRARY_PATH.
+# Set ICD_LIBRARY_PATH to be a relative path similar to "./libvk_swiftshader.so", so both files can be moved.
+# A relative path is relative to the manifest file.
+set(ICD_LIBRARY_PATH "${CMAKE_SHARED_LIBRARY_PREFIX}vk_swiftshader${CMAKE_SHARED_LIBRARY_SUFFIX}")
+if(WIN32)
+    # The path is output to a JSON file, which requires backslashes to be escaped.
+    set(ICD_LIBRARY_PATH ".\\\\${ICD_LIBRARY_PATH}")
+else()
+    set(ICD_LIBRARY_PATH "./${ICD_LIBRARY_PATH}")
+endif()
+configure_file(
+    "vk_swiftshader_icd.json.tmpl"
+    "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}/vk_swiftshader_icd.json"
+)
diff --git a/src/WSI/CMakeLists.txt b/src/WSI/CMakeLists.txt
new file mode 100644
index 0000000..509eb6a
--- /dev/null
+++ b/src/WSI/CMakeLists.txt
@@ -0,0 +1,80 @@
+# Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+#
+# 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
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+set(ROOT_PROJECT_COMPILE_OPTIONS
+    ${SWIFTSHADER_COMPILE_OPTIONS}
+    ${WARNINGS_AS_ERRORS}
+)
+
+set(WSI_SRC_FILES
+    VkSurfaceKHR.cpp
+    VkSurfaceKHR.hpp
+    VkSwapchainKHR.cpp
+    VkSwapchainKHR.hpp
+)
+
+if(WIN32)
+    list(APPEND WSI_SRC_FILES
+        Win32SurfaceKHR.cpp
+        Win32SurfaceKHR.hpp
+    )
+elseif(LINUX)
+    if(X11)
+        list(APPEND WSI_SRC_FILES
+            XlibSurfaceKHR.cpp
+            XlibSurfaceKHR.hpp
+            libX11.cpp
+            libX11.hpp
+        )
+    endif()
+
+    if(XCB)
+        list(APPEND WSI_SRC_FILES
+            XcbSurfaceKHR.cpp
+            XcbSurfaceKHR.hpp
+        )
+    endif()
+
+elseif(APPLE)
+    list(APPEND WSI_SRC_FILES
+        MetalSurface.mm
+        MetalSurface.h
+    )
+endif()
+
+add_library(vk_wsi EXCLUDE_FROM_ALL
+    ${WSI_SRC_FILES}
+)
+
+set_target_properties(vk_wsi PROPERTIES
+    POSITION_INDEPENDENT_CODE 1
+    FOLDER "SwiftShader VK"
+    LINK_FLAGS "${SWIFTSHADER_LINK_FLAGS}"
+)
+
+target_include_directories(vk_wsi
+    PUBLIC
+        ".."
+        "${CMAKE_SOURCE_DIR}/include"
+)
+
+target_compile_options(vk_wsi
+    PUBLIC
+        ${ROOT_PROJECT_COMPILE_OPTIONS}
+)
+
+target_link_libraries(vk_wsi
+    PUBLIC
+        vk_pipeline
+)