SDL: revise iconv detection: (42c83)

From 42c8366fdc58415c8045097a4f0a0f6f371709b8 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Thu, 23 Nov 2023 04:30:56 +0300
Subject: [PATCH] revise iconv detection:

- check libiconv with a linkage test with iconv.h included
- check libc iconv with a linkage test with iconv.h included
  and LIBICONV_PLUG defined (in case libiconv header is in
  include path)
- add new configuration option to prefer iconv from libiconv,
  if available, over the libc version: SDL_LIBICONV, defaults
  to disabled.
- remove FindIconv + pkg_check_modules for iconv, and use our
  manual iconv finding only
- change FreeBSD specific LIBICONV_PLUG define in SDL_iconv.c
  to configuration result.
---
 CMakeLists.txt                                | 44 +++++++++++--------
 include/build_config/SDL_build_config.h.cmake |  5 ++-
 src/stdlib/SDL_iconv.c                        |  2 +-
 3 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a04b2b39916..ba5451015020 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -295,6 +295,7 @@ dep_option(SDL_LASX                "Use LASX assembly routines" ON "SDL_ASSEMBLY
 
 set_option(SDL_LIBC                "Use the system C library" ${SDL_LIBC_DEFAULT})
 set_option(SDL_SYSTEM_ICONV        "Use iconv() from system-installed libraries" ${SDL_SYSTEM_ICONV_DEFAULT})
+set_option(SDL_LIBICONV            "Prefer iconv() from libiconv, if available, over libc version" OFF)
 set_option(SDL_GCC_ATOMICS         "Use gcc builtin atomics" ${SDL_GCC_ATOMICS_DEFAULT})
 dep_option(SDL_DBUS                "Enable D-Bus support" ON ${UNIX_SYS} OFF)
 set_option(SDL_DISKAUDIO           "Support the disk writer audio driver" ON)
@@ -1099,24 +1100,31 @@ if(SDL_LIBC)
     check_symbol_exists(poll "poll.h" HAVE_POLL)
 
     if(SDL_SYSTEM_ICONV)
-      check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
-      if(HAVE_LIBICONV)
-        find_package(Iconv)
-        if(Iconv_FOUND AND NOT Iconv_IS_BUILT_IN)
-          set(HAVE_ICONV 1)
-          set(HAVE_SYSTEM_ICONV TRUE)
-          pkg_check_modules(PC_ICONV iconv)
-          if(PC_ICONV_FOUND)
-            sdl_link_dependency(iconv LIBS Iconv::Iconv CMAKE_MODULE Iconv PKG_CONFIG_SPECS iconv)
-          else()
-            sdl_link_dependency(iconv LIBS Iconv::Iconv CMAKE_MODULE Iconv PKG_CONFIG_LIBS iconv)
-          endif()
-        endif()
-      else()
-        check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV)
-        if(HAVE_BUILTIN_ICONV)
-          set(HAVE_ICONV 1)
-          set(HAVE_SYSTEM_ICONV TRUE)
+      check_c_source_compiles("
+        #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */
+        #include <stddef.h>
+        #include <iconv.h>
+        int main(int argc, char **argv) {
+            return iconv_open(NULL,NULL);
+        }" ICONV_IN_LIBC)
+
+      cmake_push_check_state()
+      list(APPEND CMAKE_REQUIRED_LIBRARIES iconv)
+      check_c_source_compiles("
+        #include <stddef.h>
+        #include <iconv.h>
+        int main(int argc, char **argv) {
+            return iconv_open(NULL,NULL);
+        }" ICONV_IN_LIBICONV)
+      cmake_pop_check_state()
+
+      if(ICONV_IN_LIBC OR ICONV_IN_LIBICONV)
+        set(HAVE_ICONV 1)
+        set(HAVE_SYSTEM_ICONV TRUE)
+        if(ICONV_IN_LIBICONV AND (SDL_LIBICONV OR (NOT ICONV_IN_LIBC)))
+          sdl_link_dependency(iconv LIBS iconv)
+          set(SDL_USE_LIBICONV 1)
+          set(HAVE_LIBICONV TRUE)
         endif()
       endif()
     endif()
diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake
index 8b26e0dea929..4c5f9b31c0db 100644
--- a/include/build_config/SDL_build_config.h.cmake
+++ b/include/build_config/SDL_build_config.h.cmake
@@ -196,6 +196,7 @@
 #cmakedefine HAVE_CLOCK_GETTIME 1
 #cmakedefine HAVE_GETPAGESIZE 1
 #cmakedefine HAVE_ICONV 1
+#cmakedefine SDL_USE_LIBICONV 1
 #cmakedefine HAVE_PTHREAD_SETNAME_NP 1
 #cmakedefine HAVE_PTHREAD_SET_NAME_NP 1
 #cmakedefine HAVE_SEM_TIMEDWAIT 1
@@ -223,7 +224,7 @@
 
 #cmakedefine HAVE_LINUX_INPUT_H 1
 #cmakedefine HAVE_LIBUDEV_H 1
-#cmakedefine HAVE_LIBDECOR_H  1
+#cmakedefine HAVE_LIBDECOR_H 1
 
 #cmakedefine HAVE_D3D_H @HAVE_D3D_H@
 #cmakedefine HAVE_D3D11_H @HAVE_D3D11_H@
@@ -487,7 +488,7 @@
 #cmakedefine SDL_ARM_NEON_BLITTERS @SDL_ARM_NEON_BLITTERS@
 
 /* Whether SDL_DYNAMIC_API needs dlopen */
-#cmakedefine DYNAPI_NEEDS_DLOPEN  @DYNAPI_NEEDS_DLOPEN@
+#cmakedefine DYNAPI_NEEDS_DLOPEN @DYNAPI_NEEDS_DLOPEN@
 
 /* Enable ime support */
 #cmakedefine SDL_USE_IME @SDL_USE_IME@
diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c
index f1ea29e63e30..2c98b77286f0 100644
--- a/src/stdlib/SDL_iconv.c
+++ b/src/stdlib/SDL_iconv.c
@@ -23,7 +23,7 @@
 /* This file contains portable iconv functions for SDL */
 
 #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H)
-#ifdef __FreeBSD__
+#ifndef SDL_USE_LIBICONV
 /* Define LIBICONV_PLUG to use iconv from the base instead of ports and avoid linker errors. */
 #define LIBICONV_PLUG 1
 #endif