From 62e7df2544abd30005d8eefb5a62d2edede0fe41 Mon Sep 17 00:00:00 2001
From: Evan Hemsley <[EMAIL REDACTED]>
Date: Sun, 27 Oct 2024 10:09:12 -0700
Subject: [PATCH] CMake structure and CLI (#27)
---------
Co-authored-by: Anonymous Maarten <anonymous.maarten@gmail.com>
---
.github/actions/setup-ninja/action.yml | 62 ++
.github/workflows/main.yml | 84 +++
.gitignore | 1 +
CMakeLists.txt | 289 ++++++++
README.txt | 16 +
build-scripts/test-versioning.sh | 81 +++
cmake/CPackProjectConfig.cmake.in | 37 +
cmake/PrivateSdlFunctions.cmake | 355 ++++++++++
cmake/SDL3_gpu_shadercrossConfig.cmake.in | 45 ++
cmake/sdl3-gpu-shadercross.pc.in | 13 +
cmake/sdlcpu.cmake | 156 +++++
cmake/sdlplatform.cmake | 106 +++
.../SDL_gpu_shadercross.h | 273 ++++++++
.../SDL_gpu_shadercross.c | 651 ++++++++++++------
src/SDL_gpu_shadercross.sym | 19 +
src/cli.c | 432 ++++++++++++
spirv.h => src/spirv.h | 0
spirv_cross_c.h => src/spirv_cross_c.h | 0
src/version.rc | 38 +
test.c | 3 -
20 files changed, 2430 insertions(+), 231 deletions(-)
create mode 100644 .github/actions/setup-ninja/action.yml
create mode 100644 .github/workflows/main.yml
create mode 100644 .gitignore
create mode 100644 CMakeLists.txt
create mode 100644 README.txt
create mode 100755 build-scripts/test-versioning.sh
create mode 100644 cmake/CPackProjectConfig.cmake.in
create mode 100644 cmake/PrivateSdlFunctions.cmake
create mode 100644 cmake/SDL3_gpu_shadercrossConfig.cmake.in
create mode 100644 cmake/sdl3-gpu-shadercross.pc.in
create mode 100644 cmake/sdlcpu.cmake
create mode 100644 cmake/sdlplatform.cmake
create mode 100644 include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
rename SDL_gpu_shadercross.h => src/SDL_gpu_shadercross.c (69%)
create mode 100644 src/SDL_gpu_shadercross.sym
create mode 100644 src/cli.c
rename spirv.h => src/spirv.h (100%)
rename spirv_cross_c.h => src/spirv_cross_c.h (100%)
create mode 100644 src/version.rc
delete mode 100644 test.c
diff --git a/.github/actions/setup-ninja/action.yml b/.github/actions/setup-ninja/action.yml
new file mode 100644
index 0000000..b5d5fad
--- /dev/null
+++ b/.github/actions/setup-ninja/action.yml
@@ -0,0 +1,62 @@
+name: 'Setup ninja'
+description: 'Download ninja and add it to the PATH environment variable'
+inputs:
+ version:
+ description: 'Ninja version'
+ default: '1.12.1'
+runs:
+ using: 'composite'
+ steps:
+ - name: 'Calculate variables'
+ id: calc
+ shell: sh
+ run: |
+ case "${{ runner.os }}-${{ runner.arch }}" in
+ "Linux-X86" | "Linux-X64")
+ archive="ninja-linux.zip"
+ ;;
+ "Linux-ARM64")
+ archive="ninja-linux-aarch64.zip"
+ ;;
+ "macOS-X86" | "macOS-X64" | "macOS-ARM64")
+ archive="ninja-mac.zip"
+ ;;
+ "Windows-X86" | "Windows-X64")
+ archive="ninja-win.zip"
+ ;;
+ "Windows-ARM64")
+ archive="ninja-winarm64.zip"
+ ;;
+ *)
+ echo "Unsupported ${{ runner.os }}-${{ runner.arch }}"
+ exit 1;
+ ;;
+ esac
+ echo "archive=${archive}" >> ${GITHUB_OUTPUT}
+ echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT}
+ - name: 'Restore cached ${{ steps.calc.outputs.archive }}'
+ id: cache-restore
+ uses: actions/cache/restore@v4
+ with:
+ path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}'
+ key: ${{ steps.calc.outputs.cache-key }}
+ - name: 'Download ninja ${{ inputs.version }} for ${{ runner.os }} (${{ runner.arch }})'
+ if: ${{ (!steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false') }}
+ shell: pwsh
+ run: |
+ Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v${{ inputs.version }}/${{ steps.calc.outputs.archive }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}"
+ - name: 'Cache ${{ steps.calc.outputs.archive }}'
+ if: ${{ (!steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false') }}
+ uses: actions/cache/save@v4
+ with:
+ path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}'
+ key: ${{ steps.calc.outputs.cache-key }}
+ - name: 'Extract ninja'
+ shell: pwsh
+ run: |
+ 7z "-o${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" x "${{ runner.temp }}/${{ steps.calc.outputs.archive }}"
+ - name: 'Set output variables'
+ id: final
+ shell: pwsh
+ run: |
+ echo "${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" >> $env:GITHUB_PATH
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..348f857
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,84 @@
+name: Build
+
+on: [push, pull_request]
+
+jobs:
+ Build:
+ name: ${{ matrix.platform.name }}
+ runs-on: ${{ matrix.platform.os }}
+
+ defaults:
+ run:
+ shell: ${{ matrix.platform.shell }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ platform:
+ - { name: Windows (MSVC), os: windows-2019, shell: sh, msvc: true, artifact: 'SDL3_gpu_shadercross-VC-x64' }
+ - { name: Windows (mingw64), os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64, artifact: 'SDL3_gpu_shadercross-mingw64' }
+ - { name: Linux, os: ubuntu-20.04, shell: sh, artifact: 'SDL3_gpu_shadercross-linux-x64' }
+ - { name: Macos, os: macos-latest, shell: sh, artifact: 'SDL3_gpu_shadercross-macos-x64' }
+
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ - name: Set up Ninja
+ uses: ./.github/actions/setup-ninja
+ if: ${{ !contains(matrix.platform.shell, 'msys2') }}
+ - uses: ilammy/msvc-dev-cmd@v1
+ if: ${{ matrix.platform.msvc }}
+ with:
+ arch: x64
+ - name: Set up MSYS2
+ if: ${{ matrix.platform.shell == 'msys2 {0}' }}
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: ${{ matrix.platform.msystem }}
+ install: >-
+ ${{ matrix.platform.msys-env }}-cmake
+ ${{ matrix.platform.msys-env }}-gcc
+ ${{ matrix.platform.msys-env }}-ninja
+ - name: Set up SDL
+ id: sdl
+ uses: libsdl-org/setup-sdl@main
+ with:
+ cmake-generator: Ninja
+ version: 3-head
+ sdl-test: true
+ shell: ${{ matrix.platform.shell }}
+
+ - name: Configure (CMake)
+ run: |
+ cmake -S . -B build -GNinja \
+ -DBUILD_STATIC=ON \
+ -DBUILD_CLI=ON \
+ -DENABLE_WERROR=ON \
+ -DENABLE_INSTALL=ON \
+ -DENABLE_DEPS=ON \
+ -DENABLE_INSTALL_CPACK=ON \
+ -DCMAKE_INSTALL_PREFIX=prefix
+
+ - name: Build (CMake)
+ id: build
+ run: |
+ cmake --build build --config Release --parallel --verbose
+
+ - name: Install (CMake)
+ if: ${{ always() && steps.build.outcome == 'success' }}
+ run: |
+ cmake --install build/ --config Release
+ - name: Package (CPack)
+ id: package
+ if: ${{ always() && steps.build.outcome == 'success' }}
+ run: |
+ cmake --build build/ --target package
+
+ - uses: actions/upload-artifact@v4
+ if: ${{ always() && steps.package.outcome == 'success' }}
+ with:
+ if-no-files-found: error
+ name: ${{ matrix.platform.artifact }}
+ path: build/dist/SDL*
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..08676cc
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,289 @@
+# CMake Project for SDL3_gpu_shadercross - Simple DirectMedia Layer Shader Cross Compiler
+# Written by @thatcosmonaut
+cmake_minimum_required(VERSION 3.22)
+
+# Version
+set(MAJOR_VERSION 3)
+set(MINOR_VERSION 0)
+set(MICRO_VERSION 0)
+set(SDL_REQUIRED_VERSION "3.1.3")
+
+project(SDL3_gpu_shadercross LANGUAGES C VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}")
+
+include(CMakeDependentOption)
+include("${CMAKE_CURRENT_LIST_DIR}/cmake/PrivateSdlFunctions.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/cmake/sdlcpu.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/cmake/sdlplatform.cmake")
+
+find_package(SDL3 REQUIRED COMPONENTS SDL3-shared)
+
+# Options
+option(BUILD_STATIC "Build static library" ON)
+option(BUILD_CLI "Build command line executable" ON)
+cmake_dependent_option(BUILD_CLI_STATIC "Link CLI with static libraries" OFF "BUILD_CLI;BUILD_STATIC;TARGET SDL3::SDL3-static" OFF)
+option(ENABLE_WERROR "Enable Werror" OFF)
+option(ENABLE_INSTALL "Enable installation" OFF)
+cmake_dependent_option(ENABLE_INSTALL_CPACK "Enable CPack installation" OFF "ENABLE_INSTALL" OFF)
+cmake_dependent_option(ENABLE_DEPS "Download, build and install dependencies" OFF "ENABLE_INSTALL" OFF)
+
+sdl_calculate_derived_version_variables(${MAJOR_VERSION} ${MINOR_VERSION} ${MICRO_VERSION})
+SDL_DetectTargetCPUArchitectures(SDL_CPU_NAMES)
+SDL_DetectCMakePlatform()
+
+# Platform Flags
+if(APPLE)
+ set(CMAKE_MACOSX_RPATH ON)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
+endif()
+
+if(NOT MSVC)
+ add_compile_options(-pedantic) # -Wno-strict-aliasing
+endif()
+
+# Source lists
+set(SOURCE_FILES
+ # Public Headers
+ include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
+ # Source Files
+ src/SDL_gpu_shadercross.c
+ src/spirv_cross_c.h
+ src/spirv.h
+)
+
+add_library(SDL3_gpu_shadercross-shared SHARED ${SOURCE_FILES})
+add_library(SDL3_gpu_shadercross::SDL3_gpu_shadercross ALIAS SDL3_gpu_shadercross-shared)
+
+set_property(TARGET SDL3_gpu_shadercross-shared PROPERTY DEFINE_SYMBOL DLL_EXPORT)
+sdl_add_warning_options(SDL3_gpu_shadercross-shared WARNING_AS_ERROR ${ENABLE_WERROR})
+sdl_target_link_option_version_file(SDL3_gpu_shadercross-shared "${CMAKE_CURRENT_SOURCE_DIR}/src/SDL_gpu_shadercross.sym")
+
+# Build flags
+if(WIN32)
+ target_sources(SDL3_gpu_shadercross-shared PRIVATE "src/version.rc")
+ set_property(TARGET SDL3_gpu_shadercross-shared PROPERTY PREFIX "")
+endif()
+target_compile_features(SDL3_gpu_shadercross-shared PRIVATE c_std_99)
+
+# SDL3_gpu_shadercross folders as includes, for other targets to consume
+target_include_directories(SDL3_gpu_shadercross-shared PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
+target_include_directories(SDL3_gpu_shadercross-shared PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
+
+# MinGW builds should statically link libgcc
+if(MINGW)
+ target_link_options(SDL3_gpu_shadercross-shared PRIVATE "-static-libgcc")
+endif()
+
+# Soname
+set_target_properties(SDL3_gpu_shadercross-shared PROPERTIES
+ OUTPUT_NAME "SDL3_gpu_shadercross"
+ SOVERSION "${SO_VERSION_MAJOR}"
+ VERSION "${SO_VERSION}"
+)
+
+target_link_libraries(SDL3_gpu_shadercross-shared PRIVATE
+ SDL3::SDL3-shared
+)
+
+if(BUILD_STATIC)
+ find_package(SDL3 REQUIRED COMPONENTS Headers)
+
+ add_library(SDL3_gpu_shadercross-static STATIC ${SOURCE_FILES})
+ add_library(SDL3_gpu_shadercross::SDL3_gpu_shadercross-static ALIAS SDL3_gpu_shadercross-static)
+ sdl_add_warning_options(SDL3_gpu_shadercross-static WARNING_AS_ERROR ${ENABLE_WERROR})
+ target_compile_features(SDL3_gpu_shadercross-static PRIVATE c_std_99)
+
+ if(NOT MSVC)
+ set_property(TARGET SDL3_gpu_shadercross-static PROPERTY OUTPUT_NAME "SDL3_gpu_shadercross")
+ endif()
+
+ # SDL3_gpu_shadercross folders as includes, for other targets to consume
+ target_include_directories(SDL3_gpu_shadercross-static PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
+ target_include_directories(SDL3_gpu_shadercross-static PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
+
+ target_link_libraries(SDL3_gpu_shadercross-static PUBLIC
+ SDL3::Headers
+ )
+endif()
+
+if(NOT TARGET SDL3_gpu_shadercross::SDL3_gpu_shadercross)
+ if(TARGET SDL3_gpu_shadercross-shared)
+ add_library(SDL3_gpu_shadercross::SDL3_gpu_shadercross ALIAS SDL3_gpu_shadercross-shared)
+ else()
+ add_library(SDL3_gpu_shadercross::SDL3_gpu_shadercross ALIAS SDL3_gpu_shadercross-static)
+ endif()
+endif()
+
+if(BUILD_CLI)
+ add_executable(shadercross src/cli.c)
+
+ if(BUILD_CLI_STATIC)
+ target_link_libraries(shadercross PRIVATE SDL3_gpu_shadercross::SDL3_gpu_shadercross-static)
+ target_link_libraries(shadercross PRIVATE SDL3::SDL3-static)
+ else()
+ target_link_libraries(shadercross PRIVATE SDL3_gpu_shadercross::SDL3_gpu_shadercross)
+ target_link_libraries(shadercross PRIVATE SDL3::SDL3)
+ endif()
+endif()
+
+if(ENABLE_INSTALL)
+ include(GNUInstallDirs)
+ if(WIN32 AND NOT MINGW)
+ set(INSTALL_CMAKEDIR_ROOT_DEFAULT "cmake")
+ else()
+ set(INSTALL_CMAKEDIR_ROOT_DEFAULT "${CMAKE_INSTALL_LIBDIR}/cmake")
+ endif()
+ set(SDLGPUSHADERCROSS_INSTALL_CMAKEDIR_ROOT "${INSTALL_CMAKEDIR_ROOT_DEFAULT}" CACHE STRING "Root folder where to install SDL3_gpu_shadercross cmake related files (SDL3_gpu_shadercross subfolder for MSVC projects)")
+ set(SDLGPUSHADERCROSS_PKGCONFIG_INSTALLDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+
+ if(WIN32 AND NOT MINGW)
+ set(SDLGPUSHADERCROSS_INSTALL_CMAKEDIR "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR_ROOT}")
+ else()
+ set(SDLGPUSHADERCROSS_INSTALL_CMAKEDIR "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR_ROOT}/SDL3_gpu_shadercross")
+ endif()
+
+ if(TARGET SDL3_gpu_shadercross-shared)
+ install(TARGETS SDL3_gpu_shadercross-shared EXPORT SDL3_gpu_shadercross-shared-export
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT library
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT library
+ )
+ install(EXPORT SDL3_gpu_shadercross-shared-export
+ FILE SDL3_gpu_shadercross-shared-targets.cmake
+ NAMESPACE SDL3_gpu_shadercross::
+ DESTINATION "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR}"
+ COMPONENT devel
+ )
+ endif()
+ if(TARGET SDL3_gpu_shadercross-static)
+ install(TARGETS SDL3_gpu_shadercross-static EXPORT SDL3_gpu_shadercross-static-export
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT library
+ )
+ install(EXPORT SDL3_gpu_shadercross-static-export
+ FILE SDL3_gpu_shadercross-static-targets.cmake
+ NAMESPACE SDL3_gpu_shadercross::
+ DESTINATION "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR}"
+ COMPONENT devel
+ )
+ endif()
+ install(
+ FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL3_gpu_shadercross" COMPONENT DEVEL
+ )
+ if(BUILD_CLI)
+ install(TARGETS shadercross RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+ endif()
+
+ include(CMakePackageConfigHelpers)
+ configure_package_config_file(cmake/SDL3_gpu_shadercrossConfig.cmake.in SDL3_gpu_shadercrossConfig.cmake
+ NO_SET_AND_CHECK_MACRO
+ INSTALL_DESTINATION "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR}"
+ )
+ write_basic_package_version_file("${PROJECT_BINARY_DIR}/SDL3_gpu_shadercrossConfigVersion.cmake"
+ COMPATIBILITY AnyNewerVersion
+ )
+ install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/SDL3_gpu_shadercrossConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/SDL3_gpu_shadercrossConfigVersion.cmake"
+ DESTINATION "${SDLGPUSHADERCROSS_INSTALL_CMAKEDIR}"
+ COMPONENT devel
+ )
+
+ file(RELATIVE_PATH SDL_PATH_PREFIX_RELATIVE_TO_PKGCONFIG "${CMAKE_INSTALL_PREFIX}/${SDLGPUSHADERCROSS_PKGCONFIG_INSTALLDIR}" "${CMAKE_INSTALL_PREFIX}")
+ string(REGEX REPLACE "[/]+$" "" SDL_PATH_PREFIX_RELATIVE_TO_PKGCONFIG "${SDL_PATH_PREFIX_RELATIVE_TO_PKGCONFIG}")
+ set(SDL_PKGCONFIG_PREFIX "\${pcfiledir}/${SDL_PATH_PREFIX_RELATIVE_TO_PKGCONFIG}")
+ set(PC_REQUIRED "")
+ set(PC_LIBS "")
+ configure_file(cmake/sdl3-gpu-shadercross.pc.in sdl3-gpu-shadercross.pc @ONLY)
+
+ # Always install sdl3-gpu-shadercross.pc file: libraries might be different between config modes
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdl3-gpu-shadercross.pc"
+ DESTINATION "${SDLGPUSHADERCROSS_PKGCONFIG_INSTALLDIR}" COMPONENT devel)
+
+ install(FILES "LICENSE.txt"
+ DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}"
+ COMPONENT library
+ )
+ if(ENABLE_INSTALL_CPACK)
+ if(MSVC)
+ set(CPACK_GENERATOR "ZIP")
+ else()
+ set(CPACK_GENERATOR "TGZ")
+ endif()
+ configure_file(cmake/CPackProjectConfig.cmake.in CPackProjectConfig.cmake @ONLY)
+ set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CPackProjectConfig.cmake")
+ # CPACK_SOURCE_PACKAGE_FILE_NAME must end with "-src" (so we can block creating a source archive)
+ set(CPACK_SOURCE_PACKAGE_FILE_NAME "SDL3_gpu_shadercross-${PROJECT_VERSION}-src")
+ set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/dist")
+ include(CPack)
+ endif()
+endif()
+
+set(DXC_LINUX_X64_URL "https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.8.2407/linux_dxc_2024_07_31.x86_64.tar.gz")
+set(DXC_LINUX_X64_HASH "SHA256=b58725ac191df0686994fb9d54d27ee8dd3f180b023d562733112a499ea1195c")
+set(DXC_WINDOWS_X86_X64_ARM64_URL "https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.8.2407/dxc_2024_07_31.zip")
+set(DXC_WINDOWS_X86_X64_ARM64_HASH "SHA256=e2627f004f0f9424d8c71ea1314d04f38c5a5096884ae9217f1f18bd320267b5")
+
+if(ENABLE_DEPS)
+ set(chmod_0755 OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+ # Install SDL3
+ if(BUILD_CLI AND NOT BUILD_CLI_STATIC)
+ if(WIN32)
+ install(FILES $<TARGET_FILE:SDL3::SDL3-shared> DESTINATION "${CMAKE_INSTALL_BINDIR}" PERMISSIONS ${chmod_0755})
+ else()
+ install(FILES $<TARGET_FILE:SDL3::SDL3-shared> $<TARGET_SONAME_FILE:SDL3::SDL3-shared> DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${chmod_0755})
+ endif()
+ endif()
+
+ # Download and install prebuilt dxil and dxcompiler shared libraries
+ include(ExternalProject)
+ if(LINUX AND SDL_CPU_X64)
+ ExternalProject_Add(dxc
+ URL "${DXC_LINUX_X64_URL}"
+ URL_HASH "${DXC_LINUX_X64_HASH}"
+ DOWNLOAD_EXTRACT_TIMESTAMP "1"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+ ExternalProject_Get_property(dxc SOURCE_DIR)
+ install(FILES "${SOURCE_DIR}/lib/libdxcompiler.so" "${SOURCE_DIR}/lib/libdxil.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${chmod_0755})
+ install(FILES "${SOURCE_DIR}/LICENSE-LLVM.txt" "${SOURCE_DIR}/LICENSE-MS.txt" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/dxc")
+ elseif(WINDOWS AND (SDL_CPU_ARM64 OR SDL_CPU_X86 OR SDL_CPU_X64))
+ ExternalProject_Add(dxc
+ URL "${DXC_WINDOWS_X86_X64_ARM64_URL}"
+ URL_HASH "${DXC_WINDOWS_X86_X64_ARM64_HASH}"
+ DOWNLOAD_EXTRACT_TIMESTAMP "1"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+ if(SDL_CPU_ARM64)
+ set(arch_dir "arm64")
+ elseif(SDL_CPU_X86)
+ set(arch_dir "x86")
+ elseif(SDL_CPU_X64)
+ set(arch_dir "x64")
+ endif()
+ ExternalProject_Get_property(dxc SOURCE_DIR)
+ install(FILES "${SOURCE_DIR}/bin/${arch_dir}/dxcompiler.dll" "${SOURCE_DIR}/bin/${arch_dir}/dxil.dll" DESTINATION "${CMAKE_INSTALL_BINDIR}" PERMISSIONS ${chmod_0755})
+ install(FILES "${SOURCE_DIR}/LICENSE-LLVM.txt" "${SOURCE_DIR}/LICENSE-MS.txt" "${SOURCE_DIR}/LICENSE-MIT.txt" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/dxc")
+ endif()
+
+ # Download, configure, build and install spirv-cross
+ ExternalProject_Add(spirv_cross
+ GIT_REPOSITORY "https://github.com/KhronosGroup/SPIRV-Cross.git"
+ GIT_TAG "main"
+ CMAKE_ARGS "-DCMAKE_BUILD_TYPE=Release" "-DSPIRV_CROSS_SHARED=ON" "-DSPIRV_CROSS_STATIC=OFF" "-DSPIRV_CROSS_CLI=OFF" "-DSPIRV_CROSS_ENABLE_TESTS=OFF" "-DCMAKE_INSTALL_LIBDIR=lib" "-DCMAKE_INSTALL_BINDIR=bin" "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>" "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
+ BUILD_COMMAND "${CMAKE_COMMAND}" "--build" "<BINARY_DIR>" --config "Release"
+ INSTALL_COMMAND "${CMAKE_COMMAND}" "--install" "<BINARY_DIR>" --config "Release"
+ )
+ ExternalProject_Get_property(spirv_cross INSTALL_DIR)
+ ExternalProject_Get_property(spirv_cross SOURCE_DIR)
+ install(FILES "${SOURCE_DIR}/LICENSE" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/spirv-cross")
+ install(DIRECTORY "${INSTALL_DIR}/lib/" DESTINATION "${CMAKE_INSTALL_LIBDIR}" FILES_MATCHING PATTERN "*.so*" PERMISSIONS ${chmod_0755})
+ install(DIRECTORY "${INSTALL_DIR}/lib/" DESTINATION "${CMAKE_INSTALL_LIBDIR}" FILES_MATCHING PATTERN "*.dylib*" PERMISSIONS ${chmod_0755})
+ install(DIRECTORY "${INSTALL_DIR}/bin/" DESTINATION "${CMAKE_INSTALL_BINDIR}" FILES_MATCHING PATTERN "*.dll" PERMISSIONS ${chmod_0755})
+endif()
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..6ace9f1
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,16 @@
+SDL_gpu_shadercross
+
+This is a library for translating shaders to different formats, intended for use with SDL's GPU API.
+It takes SPIRV or HLSL as the source and outputs DXBC, DXIL, SPIRV, MSL, or HLSL.
+
+This library can perform runtime translation and conveniently returns compiled SDL GPU shader objects from HLSL or SPIRV source.
+This library also provides a command line interface for offline translation of shaders.
+
+For SPIRV translation, this library depends on SPIRV-Cross: https://github.com/KhronosGroup/SPIRV-Cross
+spirv-cross-c-shared.dll (or your platform's equivalent) can be obtained in the Vulkan SDK: https://vulkan.lunarg.com/
+For compiling to DXIL, dxcompiler.dll and dxil.dll (or your platform's equivalent) are required.
+DXIL dependencies can be obtained here: https://github.com/microsoft/DirectXShaderCompiler/releases
+It is strongly recommended that you ship SPIRV-Cross and DXIL dependencies along with your application.
+For compiling to DXBC, d3dcompiler_47 is shipped with Windows. Other platforms require vkd3d-utils.
+
+This library is under the zlib license, see LICENSE.txt for details.
diff --git a/build-scripts/test-versioning.sh b/build-scripts/test-versioning.sh
new file mode 100755
index 0000000..560a020
--- /dev/null
+++ b/build-scripts/test-versioning.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+# Copyright 2022 Collabora Ltd.
+# SPDX-License-Identifier: Zlib
+
+set -eu
+
+cd `dirname $0`/..
+
+# Needed so sed doesn't report illegal byte sequences on macOS
+export LC_CTYPE=C
+
+header=include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
+ref_major=$(sed -ne 's/^#define SDL_GPU_SHADERCROSS_MAJOR_VERSION *//p' $header)
+ref_minor=$(sed -ne 's/^#define SDL_GPU_SHADERCROSS_MINOR_VERSION *//p' $header)
+ref_micro=$(sed -ne 's/^#define SDL_GPU_SHADERCROSS_MICRO_VERSION *//p' $header)
+ref_version="${ref_major}.${ref_minor}.${ref_micro}"
+
+tests=0
+failed=0
+
+ok () {
+ tests=$(( tests + 1 ))
+ echo "ok - $*"
+}
+
+not_ok () {
+ tests=$(( tests + 1 ))
+ echo "not ok - $*"
+ failed=1
+}
+
+major=$(sed -ne 's/^set(MAJOR_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt)
+minor=$(sed -ne 's/^set(MINOR_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt)
+micro=$(sed -ne 's/^set(MICRO_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt)
+ref_sdl_req=$(sed -ne 's/^set(SDL_REQUIRED_VERSION \([0-9.]*\))$/\1/p' CMakeLists.txt)
+version="${major}.${minor}.${micro}"
+
+if [ "$ref_version" = "$version" ]; then
+ ok "CMakeLists.txt $version"
+else
+ not_ok "CMakeLists.txt $version disagrees with SDL_gpu_shadercross.h $ref_version"
+fi
+
+for rcfile in src/version.rc; do
+ tuple=$(sed -ne 's/^ *FILEVERSION *//p' "$rcfile" | tr -d '\r')
+ ref_tuple="${ref_major},${ref_minor},${ref_micro},0"
+
+ if [ "$ref_tuple" = "$tuple" ]; then
+ ok "$rcfile FILEVERSION $tuple"
+ else
+ not_ok "$rcfile FILEVERSION $tuple disagrees with SDL_gpu_shadercross.h $ref_tuple"
+ fi
+
+ tuple=$(sed -ne 's/^ *PRODUCTVERSION *//p' "$rcfile" | tr -d '\r')
+
+ if [ "$ref_tuple" = "$tuple" ]; then
+ ok "$rcfile PRODUCTVERSION $tuple"
+ else
+ not_ok "$rcfile PRODUCTVERSION $tuple disagrees with SDL_gpu_shadercross.h $ref_tuple"
+ fi
+
+ tuple=$(sed -Ene 's/^ *VALUE "FileVersion", "([0-9, ]*)\\0"\r?$/\1/p' "$rcfile" | tr -d '\r')
+ ref_tuple="${ref_major}, ${ref_minor}, ${ref_micro}, 0"
+
+ if [ "$ref_tuple" = "$tuple" ]; then
+ ok "$rcfile FileVersion $tuple"
+ else
+ not_ok "$rcfile FileVersion $tuple disagrees with SDL_gpu_shadercross.h $ref_tuple"
+ fi
+
+ tuple=$(sed -Ene 's/^ *VALUE "ProductVersion", "([0-9, ]*)\\0"\r?$/\1/p' "$rcfile" | tr -d '\r')
+
+ if [ "$ref_tuple" = "$tuple" ]; then
+ ok "$rcfile ProductVersion $tuple"
+ else
+ not_ok "$rcfile ProductVersion $tuple disagrees with SDL_gpu_shadercross.h $ref_tuple"
+ fi
+done
+
+echo "1..$tests"
+exit "$failed"
diff --git a/cmake/CPackProjectConfig.cmake.in b/cmake/CPackProjectConfig.cmake.in
new file mode 100644
index 0000000..4c7ce7d
--- /dev/null
+++ b/cmake/CPackProjectConfig.cmake.in
@@ -0,0 +1,37 @@
+if(CPACK_PACKAGE_FILE_NAME MATCHES ".*-src$")
+ message(FATAL_ERROR "Creating source archives is not supported.")
+endif()
+
+set(PROJECT_NAME "@PROJECT_NAME@")
+set(PROJECT_VERSION "@PROJECT_VERSION@")
+set(PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@")
+set(SDL_CMAKE_PLATFORM "@SDL_CMAKE_PLATFORM@")
+set(SDL_CPU_NAMES "@SDL_CPU_NAMES@")
+list(SORT SDL_CPU_NAMES)
+
+string(TOLOWER "${SDL_CMAKE_PLATFORM}" SDL_CMAKE_PLATFORM)
+string(TOLOWER "${SDL_CPU_NAMES}" SDL_CPU_NAMES)
+if(lower_sdl_cmake_platform STREQUAL lower_sdl_cpu_names)
+ set(SDL_CPU_NAMES_WITH_DASHES)
+endif()
+
+string(REPLACE ";" "-" SDL_CPU_NAMES_WITH_DASHES "${SDL_CPU_NAMES}")
+if(SDL_CPU_NAMES_WITH_DASHES)
+ set(SDL_CPU_NAMES_WITH_DASHES "-${SDL_CPU_NAMES_WITH_DASHES}")
+endif()
+
+set(MSVC @MSVC@)
+set(MINGW @MINGW@)
+if(MSVC)
+ set(SDL_CMAKE_PLATFORM "${SDL_CMAKE_PLATFORM}-VC")
+elseif(MINGW)
+ set(SDL_CMAKE_PLATFORM "${SDL_CMAKE_PLATFORM}-mingw")
+endif()
+
+set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${SDL_CMAKE_PLATFORM}${SDL_CPU_NAMES_WITH_DASHES}")
+
+if(CPACK_GENERATOR STREQUAL "DragNDrop")
+ set(CPACK_DMG_VOLUME_NAME "@PROJECT_NAME@ @PROJECT_VERSION@")
+ # FIXME: use pre-built/create .DS_Store through AppleScript (CPACK_DMG_DS_STORE/CPACK_DMG_DS_STORE_SETUP_SCRIPT)
+ set(CPACK_DMG_DS_STORE "${PROJECT_SOURCE_DIR}/Xcode/SDL/pkg-support/resources/SDL_DS_Store")
+endif()
diff --git a/cmake/PrivateSdlFunctions.cmake b/cmake/PrivateSdlFunctions.cmake
new file mode 100644
index 0000000..0bd77bb
--- /dev/null
+++ b/cmake/PrivateSdlFunctions.cmake
@@ -0,0 +1,355 @@
+# This file is shared amongst SDL_image/SDL_mixer/SDL_ttf
+
+include(CheckCCompilerFlag)
+include(CheckCSourceCompiles)
+include(CMakePushCheckState)
+
+macro(sdl_calculate_derived_version_variables MAJOR MINOR MICRO)
+ set(SO_VERSION_MAJOR "0")
+ set(SO_VERSION_MINOR "${MINOR_VERSION}")
+ set(SO_VERSION_MICRO "${MICRO_VERSION}")
+ set(SO_VERSION "${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}.${SO_VERSION_MICRO}")
+
+ if(MINOR MATCHES "[02468]$")
+ math(EXPR DYLIB_COMPAT_VERSION_MAJOR "100 * ${MINOR} + 1")
+ set(DYLIB_COMPAT_VERSION_MINOR "0")
+ math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${DYLIB_COMPAT_VERSION_MAJOR}")
+ set(DYLIB_CURRENT_VERSION_MINOR "${MICRO}")
+ else()
+ math(EXPR DYLIB_COMPAT_VERSION_MAJOR "100 * ${MINOR} + ${MICRO} + 1")
+ set(DYLIB_COMPAT_VERSION_MINOR "0")
+ math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${DYLIB_COMPAT_VERSION_MAJOR}")
+ set(DYLIB_CURRENT_VERSION_MINOR "0")
+ endif()
+ set(DYLIB_COMPAT_VERSION_MICRO "0")
+ set(DYLIB_CURRENT_VERSION_MICRO "0")
+
+ set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.${DYLIB_CURRENT_VERSION_MICRO}")
+ set(DYLIB_COMPAT_VERSION "${DYLIB_COMPAT_VERSION_MAJOR}.${DYLIB_COMPAT_VERSION_MINOR}.${DYLIB_COMPAT_VERSION_MICRO}")
+endmacro()
+
+function(read_absolute_symlink DEST PATH)
+ file(READ_SYMLINK "${PATH}" p)
+ if(NOT IS_ABSOLUTE "${p}")
+ get_filename_component(pdir "${PATH}" DIRECTORY)
+ set(p "${pdir}/${p}")
+ endif()
+ get_filename_component(p "${p}" ABSOLUTE)
+ set("${DEST}" "${p}" PARENT_SCOPE)
+endfunction()
+
+function(win32_implib_identify_dll DEST IMPLIB)
+ cmake_parse_arguments(ARGS "NOTFATAL" "" "" ${ARGN})
+ if(CMAKE_DLLTOOL)
+ execute_process(
+ COMMAND "${CMAKE_DLLTOOL}" --identify "${IMPLIB}"
+ RESULT_VARIABLE retcode
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr)
+ if(NOT retcode EQUAL 0)
+ if(NOT ARGS_NOTFATAL)
+ message(FATAL_ERROR "${CMAKE_DLLTOOL} failed.")
+ else()
+ set("${DEST}" "${DEST}-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ string(STRIP "${stdout}" result)
+ set(${DEST} "${result}" PARENT_SCOPE)
+ elseif(MSVC)
+ get_filename_component(CMAKE_C_COMPILER_DIRECTORY "${CMAKE_C_COMPILER}" DIRECTORY CACHE)
+ find_program(CMAKE_DUMPBIN NAMES dumpbin PATHS "${CMAKE_C_COMPILER_DIRECTORY}")
+ if(CMAKE_DUMPBIN)
+ execute_process(
+ COMMAND "${CMAKE_DUMPBIN}" "-headers" "${IMPLIB}"
+ RESULT_VARIABLE retcode
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr)
+ if(NOT retcode EQUAL 0)
+ if(NOT ARGS_NOTFATAL)
+ message(FATAL_ERROR "dumpbin failed.")
+ else()
+ set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ string(REGEX MATCH "DLL name[ ]+:[ ]+([^\n]+)\n" match "${stdout}")
+ if(NOT match)
+ if(NOT ARGS_NOTFATAL)
+ message(FATAL_ERROR "dumpbin did not find any associated dll for ${IMPLIB}.")
+ else()
+ set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ set(result "${CMAKE_MATCH_1}")
+ set(${DEST} "${result}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Cannot find dumpbin, please set CMAKE_DUMPBIN cmake variable")
+ endif()
+ else()
+ if(NOT ARGS_NOTFATAL)
+ message(FATAL_ERROR "Don't know how to identify dll from import library. Set CMAKE_DLLTOOL (for mingw) or CMAKE_DUMPBIN (for MSVC)")
+ else()
+ set(${DEST} "${DEST}-NOTFOUND")
+ endif()
+ endif()
+endfunction()
+
+function(get_actual_target)
+ set(dst "${ARGV0}")
+ set(target "${${dst}}")
+ set(input "${target}")
+ get_target_property(alias "${target}" ALIASED_TARGET)
+ while(alias)
+ set(target "${alias}")
+ get_target_property(alias "${target}" ALIASED_TARGET)
+ endwhile()
+ message(DEBUG "get_actual_target(\"${input}\") -> \"${target}\"")
+ set("${dst}" "${target}" PARENT_SCOPE)
+endfunction()
+
+function(target_get_dynamic_library DEST TARGET)
+ set(result)
+ get_actual_target(TARGET)
+
(Patch may be truncated, please check the link at the top of this post.)