SDL_ttf: cmake: introduce SDLTTF_STRICT

From 80646aa73774458bb0961f9f6bd852030762abe6 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Tue, 28 Jan 2025 20:25:13 +0100
Subject: [PATCH] cmake: introduce SDLTTF_STRICT

---
 CMakeLists.txt    | 119 ++++++++++++++++++++++++++++++++++------------
 external/plutosvg |   2 +-
 2 files changed, 90 insertions(+), 31 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d8f4e2a..b8e3b3a3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -84,6 +84,14 @@ cmake_dependent_option(SDLTTF_RELOCATABLE "Create relocatable SDL_ttf package" "
 option(SDLTTF_VENDORED "Use vendored third-party libraries" ${vendored_default})
 option(SDLTTF_WERROR "Treat warnings as errors" OFF)
 
+option(SDLTTF_STRICT "Fail when a dependency could not be found" OFF)
+set(find_package_strict_arg "QUIET")
+set(fatal_error "STATUS")
+if(SDLTTF_STRICT)
+    set(find_package_strict_arg "REQUIRED")
+    set(fatal_error "FATAL_ERROR")
+endif()
+
 option(SDLTTF_SAMPLES "Build the SDL3_ttf sample program(s)" ${SDLTTF_ROOTPROJECT})
 cmake_dependent_option(SDLTTF_SAMPLES_INSTALL "Install the SDL3_ttf sample program(s)" OFF "SDLTTF_SAMPLES;SDLTTF_INSTALL" OFF)
 
@@ -224,35 +232,53 @@ set(PC_REQUIRES)
 # Build freetype and harfbuzz as a static library
 set(BUILD_SHARED_LIBS OFF)
 
+list(APPEND SDLTTF_BACKENDS PLUTOSVG)
+set(SDLTTF_PLUTOSVG_ENABLED FALSE)
 if(SDLTTF_PLUTOSVG)
+    set(plutosvg_include_directories)
+    set(plutosvg_link_libraries)
+    set(plutosvg_sources)
     if(SDLTTF_PLUTOSVG_VENDORED)
         message(STATUS "${PROJECT_NAME}: Using vendored plutosvg library")
-
+        set(BUILD_SHARED_LIBS OFF)
         set(PLUTOSVG_ENABLE_FREETYPE ON CACHE BOOL "plutosvg enable freetype" FORCE)
         set(PLUTOVG_BUILD_EXAMPLES OFF CACHE BOOL "plutosvg build examples" FORCE)
-        if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/plutosvg/CMakeLists.txt")
-            message(FATAL_ERROR "No plutosvg sources found. Install a plutosvg development package or run the download script in the external folder.")
-        endif()
+        sdl_check_project_in_subfolder(external/plutovg plutovg SDLTTF_VENDORED)
+        add_subdirectory(external/plutovg EXCLUDE_FROM_ALL)
+        sdl_check_project_in_subfolder(external/plutosvg plutosvg SDLTTF_VENDORED)
         add_subdirectory(external/plutosvg EXCLUDE_FROM_ALL)
-        if(NOT TARGET plutosvg::plutosvg)
-            add_library(plutosvg::plutosvg ALIAS plutosvg)
-        endif()
+        set(SDLTTF_PLUTOSVG_ENABLED TRUE)
         if(SDLTTF_BUILD_SHARED_LIBS)
-          target_link_libraries(${sdl3_ttf_target_name} PRIVATE plutosvg::plutosvg)
+            set(plutosvg_link_libraries plutosvg::plutosvg)
         else()
-          target_sources(${sdl3_ttf_target_name} PRIVATE $<TARGET_OBJECTS:plutosvg::plutosvg>)
-          target_include_directories(${sdl3_ttf_target_name} PRIVATE $<TARGET_PROPERTY:plutosvg::plutosvg,INTERFACE_INCLUDE_DIRECTORIES>)
+            set(plutosvg_include_directories $<TARGET_PROPERTY:plutosvg::plutosvg,INTERFACE_INCLUDE_DIRECTORIES>)
+            set(plutosvg_sources $<TARGET_OBJECTS:plutosvg> $<TARGET_OBJECTS:plutovg>)
         endif()
     else()
-        message(STATUS "${PROJECT_NAME}: Using system plutosvg library")
-        find_package(plutosvg REQUIRED)
-        list(APPEND PC_REQUIRES plutosvg)
-        target_link_libraries(${sdl3_ttf_target_name} PRIVATE plutosvg::plutosvg)
+        find_package(plutosvg ${find_package_strict_arg})
+        if(plutosvg_FOUND)
+            message(STATUS "${PROJECT_NAME}: Using system plutosvg library")
+            set(plutosvg_link_libraries plutosvg::plutosvg)
+            list(APPEND PC_REQUIRES plutosvg)
+            set(SDLTTF_PLUTOSVG_ENABLED TRUE)
+        else()
+            message(${fatal_error} "plutosvg NOT found")
+        endif()
+    endif()
+    if(SDLTTF_PLUTOSVG_ENABLED)
+        target_compile_definitions(${sdl3_ttf_target_name} PRIVATE TTF_USE_PLUTOSVG=1)
+        target_sources(${sdl3_ttf_target_name} PRIVATE ${plutosvg_sources})
+        target_include_directories(${sdl3_ttf_target_name} PRIVATE ${plutosvg_include_directories})
+        target_link_libraries(${sdl3_ttf_target_name} PRIVATE ${plutosvg_link_libraries})
     endif()
-    target_compile_definitions(${sdl3_ttf_target_name} PRIVATE TTF_USE_PLUTOSVG=1)
 endif()
 
+list(APPEND SDLTTF_BACKENDS HARFBUZZ)
+set(SDLTTF_HARFBUZZ_ENABLED FALSE)
 if(SDLTTF_HARFBUZZ)
+    set(harfbuzz_sources)
+    set(harfbuzz_link_libraries)
+    set(harfbuzz_include_directories)
     if(SDLTTF_HARFBUZZ_VENDORED)
         message(STATUS "${PROJECT_NAME}: Using vendored harfbuzz library")
         # HB_BUILD_UTILS variable is used by harfbuzz
@@ -261,34 +287,45 @@ if(SDLTTF_HARFBUZZ)
         set(SKIP_INSTALL_LIBRARIES ON CACHE BOOL "harfbuzz install option" FORCE)
         # HB_HAVE_FREETYPE variable is used by harfbuzz
         set(HB_HAVE_FREETYPE ${SDLTTF_FREETYPE} CACHE BOOL "harfbuzz freetype helpers" FORCE)
-        if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/harfbuzz/CMakeLists.txt")
-            message(FATAL_ERROR "No harfbuzz sources found. Install a harfbuzz development package or run the download script in the external folder.")
-        endif()
+        sdl_check_project_in_subfolder(external/harfbuzz harfbuzz SDLTTF_VENDORED)
         add_subdirectory(external/harfbuzz EXCLUDE_FROM_ALL)
         # harfbuzz is a c++ project, enable c++ here to ensure linking to the c++ standard library
         enable_language(CXX)
         if(NOT TARGET harfbuzz::harfbuzz)
             add_library(harfbuzz::harfbuzz ALIAS harfbuzz)
         endif()
+        set(SDLTTF_HARFBUZZ_ENABLED TRUE)
         if(SDLTTF_BUILD_SHARED_LIBS)
-          target_link_libraries(${sdl3_ttf_target_name} PRIVATE harfbuzz::harfbuzz)
+            set(harfbuzz_link_libraries harfbuzz::harfbuzz)
         else()
-          target_sources(${sdl3_ttf_target_name} PRIVATE $<TARGET_OBJECTS:harfbuzz::harfbuzz>)
-          target_include_directories(${sdl3_ttf_target_name} PRIVATE $<TARGET_PROPERTY:harfbuzz::harfbuzz,INTERFACE_INCLUDE_DIRECTORIES>)
-          if(NOT MSVC)
-            find_package(Threads)
-            target_link_libraries(${sdl3_ttf_target_name} PRIVATE Threads::Threads)
-          endif()
+            set(harfbuzz_sources $<TARGET_OBJECTS:harfbuzz::harfbuzz>)
+            set(harfbuzz_include_directories $<TARGET_PROPERTY:harfbuzz::harfbuzz,INTERFACE_INCLUDE_DIRECTORIES>)
+            if(NOT MSVC)
+                find_package(Threads)
+                set(harfbuzz_link_librarise Threads::Threads)
+            endif()
         endif()
     else()
-        message(STATUS "${PROJECT_NAME}: Using system harfbuzz library")
-        find_package(harfbuzz REQUIRED)
-        list(APPEND PC_REQUIRES harfbuzz)
-        target_link_libraries(${sdl3_ttf_target_name} PRIVATE harfbuzz::harfbuzz)
+        find_package(harfbuzz ${find_package_strict_arg})
+        if(harfbuzz_FOUND)
+            message(STATUS "${PROJECT_NAME}: Using system harfbuzz library")
+            list(APPEND PC_REQUIRES harfbuzz)
+            set(SDLTTF_HARFBUZZ_ENABLED TRUE)
+            set(harfbuzz_link_libraries harfbuzz::harfbuzz)
+        else()
+            message(${fatal_error} "harfbuzz NOT found")
+        endif()
+    endif()
+    if(SDLTTF_HARFBUZZ_ENABLED)
+        target_compile_definitions(${sdl3_ttf_target_name} PRIVATE TTF_USE_HARFBUZZ=1)
+        target_sources(${sdl3_ttf_target_name} PRIVATE ${harfbuzz_sources})
+        target_include_directories(${sdl3_ttf_target_name} PRIVATE ${harfbuzz_include_directories})
+        target_link_libraries(${sdl3_ttf_target_name} PRIVATE ${harfbuzz_link_libraries})
     endif()
-    target_compile_definitions(${sdl3_ttf_target_name} PRIVATE TTF_USE_HARFBUZZ=1)
 endif()
 
+list(APPEND SDLTTF_BACKENDS FREETYPE)
+set(SDLTTF_FREETYPE_ENABLED FALSE)
 if(SDLTTF_FREETYPE)
     if(SDLTTF_FREETYPE_VENDORED)
         message(STATUS "${PROJECT_NAME}: Using vendored freetype library")
@@ -330,6 +367,7 @@ if(SDLTTF_FREETYPE)
         list(APPEND PC_REQUIRES freetype2)
         target_link_libraries(${sdl3_ttf_target_name} PRIVATE Freetype::Freetype)
     endif()
+    set(SDLTTF_FREETYPE_ENABLED TRUE)
 endif()
 
 # Restore BUILD_SHARED_LIBS variable
@@ -470,3 +508,24 @@ if(SDLTTF_SAMPLES)
         endif()
     endforeach()
 endif()
+
+set(available_deps)
+set(unavailable_deps)
+foreach(dep IN LISTS SDLTTF_BACKENDS)
+  set(var SDLTTF_${dep}_ENABLED)
+  if(NOT DEFINED ${var})
+    message(AUTHOR_WARNING "${var} not defined")
+  endif()
+  if(${var})
+    list(APPEND available_deps ${dep})
+  else()
+    list(APPEND unavailable_deps ${dep})
+  endif()
+endforeach()
+string(JOIN " " avail_str ${available_deps})
+string(TOLOWER "${avail_str}" avail_str)
+string(JOIN " " unavail_str ${unavailable_deps})
+string(TOLOWER "${unavail_str}" unavail_str)
+message(STATUS "SDL3_ttf backends:")
+message(STATUS "- enabled:  ${avail_str}")
+message(STATUS "- disabled: ${unavail_str}")
diff --git a/external/plutosvg b/external/plutosvg
index e0a1ce53..978dfe7e 160000
--- a/external/plutosvg
+++ b/external/plutosvg
@@ -1 +1 @@
-Subproject commit e0a1ce53c7fb8ae3831b39285d98c407a32b56cf
+Subproject commit 978dfe7ef30ccab1360703e87320cb3913d6ce2c