SDL_gpu_shadercross: Implement build system and CLI support

From f2b7786104e15eef218e41bb80c7bea4a1f36b80 Mon Sep 17 00:00:00 2001
From: cosmonaut <[EMAIL REDACTED]>
Date: Thu, 24 Oct 2024 11:13:01 -0700
Subject: [PATCH] Implement build system and CLI support

---
 CMakeLists.txt                | 50 ++++++++++++++++++++++++-----------
 include/SDL_gpu_shadercross.h | 26 +++++++++++-------
 src/SDL_gpu_shadercross.c     |  2 ++
 src/cli.c                     | 23 ++++++++++++++--
 4 files changed, 74 insertions(+), 27 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1338f2a..53cfae2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,8 +5,8 @@ project(SDL_gpu_shadercross C)
 find_package(SDL3 REQUIRED)
 
 # Options
+option(BUILD_STATIC "Build static library" ON)
 option(BUILD_CLI "Build command line executable" ON)
-option(BUILD_SHARED_LIBS "Build shared library" ON)
 
 # Version
 SET(LIB_MAJOR_VERSION "1")
@@ -49,11 +49,7 @@ file(GLOB SOURCE_FILES
     src/spirv.h
 )
 
-if(BUILD_SHARED_LIBS)
-    add_library(SDL_gpu_shadercross SHARED ${SOURCE_FILES})
-else()
-    add_library(SDL_gpu_shadercross STATIC ${SOURCE_FILES})
-endif()
+add_library(SDL_gpu_shadercross SHARED ${SOURCE_FILES})
 
 # Build flags
 if(NOT MSVC)
@@ -61,10 +57,7 @@ if(NOT MSVC)
 endif()
 
 # SDL_gpu_shadercross folders as includes, for other targets to consume
-target_include_directories(SDL_gpu_shadercross PUBLIC
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
-)
+target_include_directories(SDL_gpu_shadercross PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
 
 # MinGW builds should statically link libgcc
 if(MINGW)
@@ -82,16 +75,41 @@ target_link_libraries(SDL_gpu_shadercross PRIVATE
     SDL3::Headers
 )
 
+if(BUILD_STATIC)
+    add_library(SDL_gpu_shadercross-static STATIC ${SOURCE_FILES})
+
+    # Build flags
+    if(NOT MSVC)
+        set_property(TARGET SDL_gpu_shadercross-static PROPERTY COMPILE_FLAGS "-std=gnu99 -Wall -Wno-strict-aliasing -pedantic")
+    endif()
+
+    # SDL_gpu_shadercross folders as includes, for other targets to consume
+    target_include_directories(SDL_gpu_shadercross-static PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+
+    # MinGW builds should statically link libgcc
+    if(MINGW)
+        target_link_libraries(SDL_gpu_shadercross-static PRIVATE -static-libgcc)
+    endif()
+
+    # Soname
+    set_target_properties(SDL_gpu_shadercross-static PROPERTIES OUTPUT_NAME "SDL_gpu_shadercross-static"
+        VERSION ${LIB_VERSION}
+        SOVERSION ${LIB_MAJOR_VERSION}
+    )
+
+    target_link_libraries(SDL_gpu_shadercross-static PRIVATE
+        SDL3::SDL3-static
+        SDL3::Headers
+    )
+endif()
+
 if(BUILD_CLI)
     file(GLOB CLI_SOURCES
         src/cli.c
     )
 
-    add_executable(SDL_gpu_shadercross_cli ${CLI_SOURCES})
+    add_executable(shadercross ${CLI_SOURCES})
 
-    if(BUILD_SHARED_LIBS)
-        target_link_libraries(SDL_gpu_shadercross_cli PUBLIC SDL_gpu_shadercross)
-    else()
-        target_link_libraries(SDL_gpu_shadercross_cli PRIVATE SDL_gpu_shadercross)
-    endif()
+    target_link_libraries(shadercross PRIVATE SDL3::SDL3-static SDL3::Headers)
+    target_link_libraries(shadercross PRIVATE SDL_gpu_shadercross-static)
 endif()
diff --git a/include/SDL_gpu_shadercross.h b/include/SDL_gpu_shadercross.h
index cae3475..58fed06 100644
--- a/include/SDL_gpu_shadercross.h
+++ b/include/SDL_gpu_shadercross.h
@@ -22,7 +22,15 @@
 #ifndef SDL_GPU_SHADERCROSS_H
 #define SDL_GPU_SHADERCROSS_H
 
-#include <SDL3/SDL.h>
+#ifdef _WIN32
+#define SHADERCROSSAPI __declspec(dllexport)
+#define SHADERCROSSCALL __cdecl
+#else
+#define CRAMAPI
+#define CRAMCALL
+#endif
+
+#include <SDL3/SDL_gpu.h>
 
 #ifndef SDL_GPU_SHADERCROSS_SPIRVCROSS
 #define SDL_GPU_SHADERCROSS_SPIRVCROSS 1
@@ -41,13 +49,13 @@
  *
  * \threadsafety This should only be called once, from a single thread.
  */
-extern bool SDL_ShaderCross_Init(void);
+extern SHADERCROSSAPI bool SDL_ShaderCross_Init(void);
 /**
  * De-initializes SDL_gpu_shadercross
  *
  * \threadsafety This should only be called once, from a single thread.
  */
-extern void SDL_ShaderCross_Quit(void);
+extern SHADERCROSSAPI void SDL_ShaderCross_Quit(void);
 
 #if SDL_GPU_SHADERCROSS_SPIRVCROSS
 /**
@@ -55,7 +63,7 @@ extern void SDL_ShaderCross_Quit(void);
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUShaderFormat SDL_ShaderCross_GetSPIRVShaderFormats(void);
+extern SHADERCROSSAPI SDL_GPUShaderFormat SDL_ShaderCross_GetSPIRVShaderFormats(void);
 
 /**
  * Compile an SDL GPU shader from SPIRV code.
@@ -66,7 +74,7 @@ extern SDL_GPUShaderFormat SDL_ShaderCross_GetSPIRVShaderFormats(void);
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromSPIRV(SDL_GPUDevice *device,
+extern SHADERCROSSAPI SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromSPIRV(SDL_GPUDevice *device,
                                               const SDL_GPUShaderCreateInfo *createInfo);
 
 /**
@@ -78,7 +86,7 @@ extern SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromSPIRV(SDL_GPUDevi
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromSPIRV(SDL_GPUDevice *device,
+extern SHADERCROSSAPI SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromSPIRV(SDL_GPUDevice *device,
                                               const SDL_GPUComputePipelineCreateInfo *createInfo);
 #endif /* SDL_GPU_SHADERCROSS_SPIRVCROSS */
 
@@ -88,7 +96,7 @@ extern SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromSPIRV(S
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUShaderFormat SDL_ShaderCross_GetHLSLShaderFormats(void);
+extern SHADERCROSSAPI SDL_GPUShaderFormat SDL_ShaderCross_GetHLSLShaderFormats(void);
 
 /**
  * Compile an SDL GPU shader from HLSL code.
@@ -101,7 +109,7 @@ extern SDL_GPUShaderFormat SDL_ShaderCross_GetHLSLShaderFormats(void);
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromHLSL(SDL_GPUDevice *device,
+extern SHADERCROSSAPI SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromHLSL(SDL_GPUDevice *device,
                                              const SDL_GPUShaderCreateInfo *createInfo,
                                              const char *hlslSource,
                                              const char *shaderProfile);
@@ -117,7 +125,7 @@ extern SDL_GPUShader *SDL_ShaderCross_CompileGraphicsShaderFromHLSL(SDL_GPUDevic
  *
  * \threadsafety It is safe to call this function from any thread.
  */
-extern SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromHLSL(SDL_GPUDevice *device,
+extern SHADERCROSSAPI SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromHLSL(SDL_GPUDevice *device,
                                              const SDL_GPUComputePipelineCreateInfo *createInfo,
                                              const char *hlslSource,
                                              const char *shaderProfile);
diff --git a/src/SDL_gpu_shadercross.c b/src/SDL_gpu_shadercross.c
index e8a77d6..d2a8774 100644
--- a/src/SDL_gpu_shadercross.c
+++ b/src/SDL_gpu_shadercross.c
@@ -20,6 +20,8 @@
 */
 
 #include "SDL_gpu_shadercross.h"
+#include <SDL3/SDL_loadso.h>
+#include <SDL3/SDL_log.h>
 
 #if SDL_GPU_SHADERCROSS_HLSL
 
diff --git a/src/cli.c b/src/cli.c
index 7c54460..98cd94b 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -19,9 +19,28 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-#define SDL_GPU_SHADERCROSS_IMPLEMENTATION
+#include "SDL_gpu_shadercross.h"
+#include "stdio.h"
+
+void print_help()
+{
+   fprintf(stdout, "%s", "Usage: shadercross input_file [options]\n");
+}
 
 int main(int argc, char *argv[])
 {
-    return 0;
+   if (argc < 2)
+   {
+      print_help();
+      return 1;
+   }
+
+   if (!SDL_ShaderCross_Init())
+   {
+      fprintf(stderr, "%s", "Failed to initialize shadercross!");
+      return 1;
+   }
+
+   SDL_ShaderCross_Quit();
+   return 0;
 }