[cmake] Add support for CMAKE_SYSTEM_NAME == "Fuchsia"

This patch modifies the CMakeLists.txt file and a few sources
in order to build the SwiftShader Vulkan ICD for Fuchsia with
CMake.

Note that building EGL/GLES_CM/GLESv2 and tests is not supported,
and should be explicitly disabled when configuring the build,
e.g.:

  mkdir build-fuchsia && build-fuchsia
  cmake .. \
    -DCMAKE_TOOLCHAIN_FILE=.../FuchsiaSdkToolchain.cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DSWIFTSHADER_BUILD_TESTS=0 \
    -DSWIFTSHADER_BUILD_EGL=0 \
    -DSWIFTSHADER_BUILD_GLES_CM=0 \
    -DSWIFTSHADER_BUILD_GLESv2=0 \
    <other-cmake-options>

  make  # or ninja

NOTE: This should not affect the build for other platforms!

This will make it easier to conditionally add Fuchsia-specific
sources to the build (see discussion on b/144687651 for details).

The BUILD.gn file will still be maintained in parallel for
Fuchsia-specific changes.

NOTE: As of now, the Fuchsia SDK doesn't provide a way for
      third-party code to access the framebuffer directly.

      Instead, client code should rely on Vulkan presentation
      surfaces or higher-level APIs provided by the compositor
      that are still in flux / unstable. Hence this will appear
      in a future CL.

Bug: b/143122483
Bug: b/144687651
Change-Id: Ica3b98f5a8eb1370287e2bb4ff22ef938aaa4b49
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38488
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: David Turner <digit@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7399105..8aed906 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,6 +39,10 @@
     set(CMAKE_CXX_FLAGS "-DANDROID_NDK_BUILD")
 elseif(WIN32)
 elseif(APPLE)
+elseif(FUCHSIA)
+    # NOTE: Building for Fuchsia requires a Fuchsia CMake-based SDK.
+    # See https://fuchsia-review.googlesource.com/c/fuchsia/+/379673
+    find_package(FuchsiaSdk)
 else()
     message(FATAL_ERROR "Platform is not supported")
 endif()
@@ -266,7 +270,7 @@
         if(NOT SWIFTSHADER_MSAN AND NOT SWIFTSHADER_ASAN AND NOT SWIFTSHADER_TSAN AND NOT SWIFTSHADER_UBSAN)
             set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-undefined,error")
         endif()
-    elseif(LINUX)
+    elseif(LINUX OR FUCHSIA)
         # The version script only exports the API functions and
         # hides all the others.
         set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${DIR}/${TARGET}.lds")
@@ -279,7 +283,7 @@
         if(ARCH STREQUAL "mipsel" OR ARCH STREQUAL "mips64el")
           # MIPS supports sysv hash-style only.
           set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=sysv")
-        else()
+        elseif(LINUX)
           # Both hash-style are needed, because we want both gold and
           # GNU ld to be able to read our libraries.
           set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=both")
@@ -737,6 +741,8 @@
     set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid)
 elseif(LINUX)
     set(OS_LIBS dl pthread)
+elseif(FUCHSIA)
+    set(OS_LIBS zircon)
 elseif(APPLE)
     find_library(COCOA_FRAMEWORK Cocoa)
     find_library(QUARTZ_FRAMEWORK Quartz)
@@ -824,14 +830,22 @@
     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")
+    endif()
     set_target_properties(vk_swiftshader PROPERTIES
         INCLUDE_DIRECTORIES "${VULKAN_INCLUDE_DIR}"
         FOLDER "Vulkan"
-        COMPILE_OPTIONS "${SWIFTSHADER_COMPILE_OPTIONS};${WARNINGS_AS_ERRORS}"
+        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
@@ -850,6 +864,14 @@
         set(VULKAN_API_LIBRARY_NAME "libvulkan.dylib")
         set_property(TARGET vk_swiftshader APPEND
                      PROPERTY COMPILE_DEFINITIONS "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++")
     else()
         message(FATAL_ERROR "Platform does not support Vulkan yet")
     endif()
diff --git a/third_party/llvm-10.0/CMakeLists.txt b/third_party/llvm-10.0/CMakeLists.txt
index 31fe70c..979f63b 100644
--- a/third_party/llvm-10.0/CMakeLists.txt
+++ b/third_party/llvm-10.0/CMakeLists.txt
@@ -1143,6 +1143,8 @@
 elseif(ANDROID)
     list(APPEND LLVM_INCLUDE_DIR ${LLVM_CONFIG_DIR}/android/include)
     list(APPEND LIBBACKTRACE_INCLUDE_DIR ${LIBBACKTRACE_CONFIG_DIR}/android/include)
+elseif(FUCHSIA)
+    list(APPEND LLVM_INCLUDE_DIR ${LLVM_CONFIG_DIR}/fuchsia/include)
 endif()
 
 list(APPEND LLVM_INCLUDE_DIR
@@ -1193,6 +1195,10 @@
         "/wd4805" # 'X': unsafe mix of type 'unsigned int' and type 'bool' in operation
         "/wd4996" # 'X': Call to 'Y' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct.
     )
+elseif(FUCHSIA)
+    list(APPEND LLVM_COMPILE_OPTIONS
+         "-Wno-error"   # The Fuchsia builds triggers several minor explicit #warning lines.
+    )
 endif()
 
 add_library(llvm STATIC EXCLUDE_FROM_ALL ${LLVM_LIST})
diff --git a/third_party/llvm-7.0/CMakeLists.txt b/third_party/llvm-7.0/CMakeLists.txt
index 7ad25ba..0b55d1c 100644
--- a/third_party/llvm-7.0/CMakeLists.txt
+++ b/third_party/llvm-7.0/CMakeLists.txt
@@ -918,6 +918,8 @@
 elseif(ANDROID)
     list(APPEND LLVM_INCLUDE_DIR ${LLVM_CONFIG_DIR}/android/include)
     list(APPEND LIBBACKTRACE_INCLUDE_DIR ${LIBBACKTRACE_CONFIG_DIR}/android/include)
+elseif(FUCHSIA)
+    list(APPEND LLVM_INCLUDE_DIR ${LLVM_CONFIG_DIR}/fuchsia/include)
 endif()
 
 list(APPEND LLVM_INCLUDE_DIR
@@ -968,6 +970,10 @@
         "/wd4805" # 'X': unsafe mix of type 'unsigned int' and type 'bool' in operation
         "/wd4996" # 'X': Call to 'Y' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct.
     )
+elseif(FUCHSIA)
+    list(APPEND LLVM_COMPILE_OPTIONS
+          "-Wno-error"   # The Fuchsia builds triggers several minor explicit #warning lines.
+    )
 endif()
 
 add_library(llvm STATIC EXCLUDE_FROM_ALL ${LLVM_LIST})