From 9e5d4710f12addd221e8e8ccbc976bf400e110dc Mon Sep 17 00:00:00 2001
From: Alexandre Bouvier <contact@amb.tf>
Date: Fri, 6 Sep 2024 03:05:00 +0200
Subject: [PATCH] cmake: try system libraries first

---
 .github/workflows/rpcsx.yml       |  2 +-
 3rdparty/CMakeLists.txt           | 55 +++++++++++++++++++++----------
 CMakeLists.txt                    | 13 ++++++--
 cmake/FindSPIRV-Cross.cmake       | 51 ++++++++++++++++++++++++++++
 cmake/Findlibunwind.cmake         | 23 +++++++++++++
 cmake/Findsox.cmake               | 12 +++++++
 hw/amdgpu/device/CMakeLists.txt   |  7 +---
 hw/amdgpu/device/src/device.cpp   |  2 +-
 hw/amdgpu/shader/CMakeLists.txt   |  2 +-
 hw/amdgpu/shader/src/Fragment.cpp |  2 +-
 orbis-kernel/CMakeLists.txt       |  4 ++-
 rpcsx-os/CMakeLists.txt           |  4 ++-
 tools/spv-gen/CMakeLists.txt      |  2 +-
 13 files changed, 146 insertions(+), 33 deletions(-)
 create mode 100644 cmake/FindSPIRV-Cross.cmake
 create mode 100644 cmake/Findlibunwind.cmake
 create mode 100644 cmake/Findsox.cmake

diff --git a/.github/workflows/rpcsx.yml b/.github/workflows/rpcsx.yml
index 1bc705c3..f0f90afa 100644
--- a/.github/workflows/rpcsx.yml
+++ b/.github/workflows/rpcsx.yml
@@ -26,7 +26,7 @@ jobs:
         sudo apt update
         sudo apt install -y cmake build-essential libunwind-dev \
         libglfw3-dev libvulkan-dev vulkan-validationlayers-dev \
-        spirv-tools glslang-tools libspirv-cross-c-shared-dev libsox-dev
+        libsox-dev
         VULKANVER=1.3.259
         curl -sSfLo Vulkan-Headers.tar.gz https://github.com/KhronosGroup/Vulkan-Headers/archive/v${VULKANVER}.tar.gz
         tar -xf Vulkan-Headers*.tar.gz
diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt
index bfd44961..a9cdf26e 100644
--- a/3rdparty/CMakeLists.txt
+++ b/3rdparty/CMakeLists.txt
@@ -1,21 +1,40 @@
 add_subdirectory(crypto)
-add_subdirectory(xbyak)
-add_subdirectory(SPIRV-Headers)
-add_subdirectory(SPIRV-Tools)
 
-set(SPIRV_CROSS_SHARED on)
-set(SPIRV_CROSS_STATIC on)
-set(SPIRV_CROSS_ENABLE_GLSL on)
-set(SPIRV_CROSS_ENABLE_HLSL off)
-set(SPIRV_CROSS_ENABLE_MSL off)
-set(SPIRV_CROSS_ENABLE_CPP off)
-set(SPIRV_CROSS_ENABLE_REFLECT off)
-set(SPIRV_CROSS_ENABLE_C_API off)
-set(SPIRV_CROSS_ENABLE_UTIL off)
-set(SPIRV_CROSS_CLI off)
-set(SPIRV_CROSS_ENABLE_TESTS off)
-set(SPIRV_CROSS_SKIP_INSTALL on)
-add_subdirectory(SPIRV-Cross)
+if(NOT xbyak_FOUND)
+    add_subdirectory(xbyak)
+endif()
 
-add_subdirectory(glslang)
-add_subdirectory(json)
+if(NOT SPIRV-Headers_FOUND)
+    add_subdirectory(SPIRV-Headers)
+endif()
+
+if(NOT SPIRV-Tools-opt_FOUND)
+    add_subdirectory(SPIRV-Tools)
+endif()
+
+if(NOT SPIRV-Cross_FOUND)
+    set(SPIRV_CROSS_SHARED on)
+    set(SPIRV_CROSS_STATIC on)
+    set(SPIRV_CROSS_ENABLE_GLSL on)
+    set(SPIRV_CROSS_ENABLE_HLSL off)
+    set(SPIRV_CROSS_ENABLE_MSL off)
+    set(SPIRV_CROSS_ENABLE_CPP off)
+    set(SPIRV_CROSS_ENABLE_REFLECT off)
+    set(SPIRV_CROSS_ENABLE_C_API off)
+    set(SPIRV_CROSS_ENABLE_UTIL off)
+    set(SPIRV_CROSS_CLI off)
+    set(SPIRV_CROSS_ENABLE_TESTS off)
+    set(SPIRV_CROSS_SKIP_INSTALL on)
+    add_subdirectory(SPIRV-Cross)
+endif()
+
+if(NOT glslang_FOUND)
+    add_subdirectory(glslang)
+    if(NOT TARGET glslang::glslang-standalone)
+        add_executable(glslang::glslang-standalone ALIAS glslang-standalone)
+    endif()
+endif()
+
+if(NOT nlohmann_json_FOUND)
+    add_subdirectory(json)
+endif()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 80d7bfd3..33b90c01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,15 @@ set(CMAKE_CXX_EXTENSIONS off)
 set(CMAKE_CXX_STANDARD 23)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+find_package(glslang CONFIG)
+find_package(nlohmann_json CONFIG)
+find_package(SPIRV-Cross 1.6 MODULE)
+find_package(SPIRV-Headers CONFIG)
+find_package(SPIRV-Tools-opt CONFIG)
+find_package(xbyak CONFIG)
+
 add_subdirectory(3rdparty EXCLUDE_FROM_ALL)
 
 function(add_precompiled_vulkan_spirv target)
@@ -29,8 +38,8 @@ function(add_precompiled_vulkan_spirv target)
 
         add_custom_command(
             OUTPUT ${outputpath}
-            COMMAND $<TARGET_FILE:glslang-standalone> -V --target-env vulkan1.3 --vn "${varname}" -o "${outputpath}" "${CMAKE_CURRENT_SOURCE_DIR}/${input}"
-            DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${input}" glslang-standalone
+            COMMAND $<TARGET_FILE:glslang::glslang-standalone> -V --target-env vulkan1.3 --vn "${varname}" -o "${outputpath}" "${CMAKE_CURRENT_SOURCE_DIR}/${input}"
+            DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${input}" glslang::glslang-standalone
             COMMENT "Generating ${outputname}..."
         )
 
diff --git a/cmake/FindSPIRV-Cross.cmake b/cmake/FindSPIRV-Cross.cmake
new file mode 100644
index 00000000..462699ae
--- /dev/null
+++ b/cmake/FindSPIRV-Cross.cmake
@@ -0,0 +1,51 @@
+find_library(SPIRV-Cross_core_LIBRARY NAMES spirv-cross-core)
+find_library(SPIRV-Cross_glsl_LIBRARY NAMES spirv-cross-glsl)
+
+find_path(SPIRV-Cross_INCLUDE_DIR NAMES spirv.hpp PATH_SUFFIXES spirv_cross)
+if(SPIRV-Cross_INCLUDE_DIR)
+    if(EXISTS "${SPIRV-Cross_INCLUDE_DIR}/spirv.hpp")
+        file(STRINGS "${SPIRV-Cross_INCLUDE_DIR}/spirv.hpp" _ver_line
+            REGEX "^[\t ]*#define[\t ]+SPV_VERSION[\t ]+0x[0-9]+"
+            LIMIT_COUNT 1
+        )
+        string(REGEX MATCH "0x[0-9]+" _ver "${_ver_line}")
+        math(EXPR SPIRV-Cross_MAJOR_VERSION "${_ver} >> 16")
+        math(EXPR SPIRV-Cross_MINOR_VERSION "${_ver} >> 8 & 0xFF")
+        set(SPIRV-Cross_VERSION
+            "${SPIRV-Cross_MAJOR_VERSION}.${SPIRV-Cross_MINOR_VERSION}"
+        )
+        unset(_ver_line)
+        unset(_ver)
+    endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SPIRV-Cross
+    REQUIRED_VARS
+        SPIRV-Cross_INCLUDE_DIR
+        SPIRV-Cross_core_LIBRARY
+        SPIRV-Cross_glsl_LIBRARY
+    VERSION_VAR SPIRV-Cross_VERSION
+)
+
+if(SPIRV-Cross_FOUND AND NOT TARGET spirv-cross-core)
+    add_library(spirv-cross-core UNKNOWN IMPORTED)
+    set_target_properties(spirv-cross-core PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${SPIRV-Cross_INCLUDE_DIR}"
+        IMPORTED_LOCATION "${SPIRV-Cross_core_LIBRARY}"
+    )
+endif()
+
+if(SPIRV-Cross_FOUND AND NOT TARGET spirv-cross-glsl)
+    add_library(spirv-cross-glsl UNKNOWN IMPORTED)
+    set_target_properties(spirv-cross-glsl PROPERTIES
+        IMPORTED_LOCATION "${SPIRV-Cross_glsl_LIBRARY}"
+    )
+    target_link_libraries(spirv-cross-glsl INTERFACE spirv-cross-core)
+endif()
+
+mark_as_advanced(
+    SPIRV-Cross_INCLUDE_DIR
+    SPIRV-Cross_core_LIBRARY
+    SPIRV-Cross_glsl_LIBRARY
+)
diff --git a/cmake/Findlibunwind.cmake b/cmake/Findlibunwind.cmake
new file mode 100644
index 00000000..7cdec8ac
--- /dev/null
+++ b/cmake/Findlibunwind.cmake
@@ -0,0 +1,23 @@
+find_package(PkgConfig QUIET)
+pkg_search_module(UNWIND QUIET IMPORTED_TARGET libunwind)
+
+find_library(libunwind_x86_64_LIBRARY
+    NAMES unwind-x86_64
+    HINTS "${UNWIND_LIBRARY_DIRS}"
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(libunwind
+    REQUIRED_VARS UNWIND_LINK_LIBRARIES libunwind_x86_64_LIBRARY
+    VERSION_VAR UNWIND_VERSION
+)
+
+if(libunwind_FOUND AND NOT TARGET libunwind::unwind-x86_64)
+    add_library(libunwind::unwind-x86_64 UNKNOWN IMPORTED)
+    set_target_properties(libunwind::unwind-x86_64 PROPERTIES
+        IMPORTED_LOCATION "${libunwind_x86_64_LIBRARY}"
+    )
+    target_link_libraries(libunwind::unwind-x86_64 INTERFACE PkgConfig::UNWIND)
+endif()
+
+mark_as_advanced(libunwind_x86_64_LIBRARY)
diff --git a/cmake/Findsox.cmake b/cmake/Findsox.cmake
new file mode 100644
index 00000000..5d0a8543
--- /dev/null
+++ b/cmake/Findsox.cmake
@@ -0,0 +1,12 @@
+find_package(PkgConfig QUIET)
+pkg_search_module(SOX QUIET IMPORTED_TARGET sox)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(sox
+    REQUIRED_VARS SOX_LINK_LIBRARIES
+    VERSION_VAR SOX_VERSION
+)
+
+if(sox_FOUND AND NOT TARGET sox::sox)
+    add_library(sox::sox ALIAS PkgConfig::SOX)
+endif()
diff --git a/hw/amdgpu/device/CMakeLists.txt b/hw/amdgpu/device/CMakeLists.txt
index be22227a..74e9b4f5 100644
--- a/hw/amdgpu/device/CMakeLists.txt
+++ b/hw/amdgpu/device/CMakeLists.txt
@@ -9,11 +9,6 @@ add_precompiled_vulkan_spirv(${PROJECT_NAME}-shaders
     src/rect_list.geom.glsl
 )
 
-find_package(SPIRV-Tools REQUIRED CONFIG)
-find_package(SPIRV-Tools-opt REQUIRED CONFIG)
-find_package(spirv_cross_core REQUIRED CONFIG)
-find_package(spirv_cross_glsl REQUIRED CONFIG)
-
 add_library(${PROJECT_NAME} STATIC ${INCLUDE} ${SRC})
 target_link_libraries(${PROJECT_NAME}
 PUBLIC
@@ -24,7 +19,7 @@ PUBLIC
     util
     SPIRV-Tools
     SPIRV-Tools-opt
-    spirv-cross-glsl
+    $<$<CONFIG:Debug>:spirv-cross-glsl>
 
 PRIVATE
     ${PROJECT_NAME}-shaders
diff --git a/hw/amdgpu/device/src/device.cpp b/hw/amdgpu/device/src/device.cpp
index 0f883403..356d3bdd 100644
--- a/hw/amdgpu/device/src/device.cpp
+++ b/hw/amdgpu/device/src/device.cpp
@@ -37,7 +37,7 @@
 #include <vulkan/vulkan_core.h>
 
 #ifndef NDEBUG
-#include <spirv_cross/spirv_glsl.hpp>
+#include <spirv_glsl.hpp>
 #endif
 
 using namespace amdgpu;
diff --git a/hw/amdgpu/shader/CMakeLists.txt b/hw/amdgpu/shader/CMakeLists.txt
index 90c2ad1d..9ff008e0 100644
--- a/hw/amdgpu/shader/CMakeLists.txt
+++ b/hw/amdgpu/shader/CMakeLists.txt
@@ -15,7 +15,7 @@ set(SRC
 )
 
 add_library(${PROJECT_NAME} STATIC ${INCLUDE} ${SRC})
-target_link_libraries(${PROJECT_NAME} PUBLIC spirv amdgpu::base)
+target_link_libraries(${PROJECT_NAME} PUBLIC spirv amdgpu::base spirv-cross-core)
 target_include_directories(${PROJECT_NAME} PUBLIC include PRIVATE include/${PROJECT_PATH})
 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
 add_library(amdgpu::shader ALIAS ${PROJECT_NAME})
diff --git a/hw/amdgpu/shader/src/Fragment.cpp b/hw/amdgpu/shader/src/Fragment.cpp
index fb1ff423..d0a5b8ac 100644
--- a/hw/amdgpu/shader/src/Fragment.cpp
+++ b/hw/amdgpu/shader/src/Fragment.cpp
@@ -6,7 +6,7 @@
 
 #include <spirv/GLSL.std.450.h>
 #include <spirv/spirv-instruction.hpp>
-#include <spirv_cross/spirv.hpp>
+#include <spirv.hpp>
 #include <util/unreachable.hpp>
 
 #include <bit>
diff --git a/orbis-kernel/CMakeLists.txt b/orbis-kernel/CMakeLists.txt
index 23af4565..076dff05 100644
--- a/orbis-kernel/CMakeLists.txt
+++ b/orbis-kernel/CMakeLists.txt
@@ -1,5 +1,7 @@
 set(CMAKE_POSITION_INDEPENDENT_CODE on)
 
+find_package(sox REQUIRED)
+
 add_library(obj.orbis-utils-ipc OBJECT
   src/utils/SharedMutex.cpp
   src/utils/SharedCV.cpp
@@ -71,7 +73,7 @@ add_library(obj.orbis-kernel OBJECT
   src/utils/Logs.cpp
 )
 
-target_link_libraries(obj.orbis-kernel PUBLIC orbis::kernel::config $<TARGET_OBJECTS:obj.orbis-utils-ipc> sox)
+target_link_libraries(obj.orbis-kernel PUBLIC orbis::kernel::config $<TARGET_OBJECTS:obj.orbis-utils-ipc> sox::sox)
 
 target_include_directories(obj.orbis-kernel
     PUBLIC
diff --git a/rpcsx-os/CMakeLists.txt b/rpcsx-os/CMakeLists.txt
index 47e382cd..532663d5 100644
--- a/rpcsx-os/CMakeLists.txt
+++ b/rpcsx-os/CMakeLists.txt
@@ -1,3 +1,5 @@
+find_package(libunwind REQUIRED)
+
 add_library(standalone-config INTERFACE)
 target_include_directories(standalone-config INTERFACE orbis-kernel-config)
 add_library(orbis::kernel::config ALIAS standalone-config)
@@ -62,7 +64,7 @@ add_executable(rpcsx-os
 )
 
 target_include_directories(rpcsx-os PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(rpcsx-os PUBLIC orbis::kernel amdgpu::bridge rx libcrypto unwind unwind-x86_64 xbyak)
+target_link_libraries(rpcsx-os PUBLIC orbis::kernel amdgpu::bridge rx libcrypto libunwind::unwind-x86_64 xbyak::xbyak)
 target_link_options(rpcsx-os PUBLIC "LINKER:-Ttext-segment,0x0000010000000000")
 target_compile_options(rpcsx-os PRIVATE "-march=native")
 
diff --git a/tools/spv-gen/CMakeLists.txt b/tools/spv-gen/CMakeLists.txt
index 92f9a6c6..e9f8f232 100644
--- a/tools/spv-gen/CMakeLists.txt
+++ b/tools/spv-gen/CMakeLists.txt
@@ -1,2 +1,2 @@
 add_executable(spv-gen spv-gen.cpp)
-target_link_libraries(spv-gen PUBLIC nlohmann_json)
+target_link_libraries(spv-gen PUBLIC nlohmann_json::nlohmann_json)