SDL: On x86, pass -nodefaultlib to linker when wanting to avoid the C library

From c3b13346e0a2200f1521cf064b9a602c8196e6a6 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Fri, 21 Oct 2022 18:32:53 +0200
Subject: [PATCH] On x86, pass -nodefaultlib to linker when wanting to avoid
 the C library

---
 CMakeLists.txt                   |  8 +++++++
 cmake/CheckCPUArchitecture.cmake | 40 ++++++++++++++++++++++++++++++++
 src/stdlib/SDL_mslibc.c          |  6 +++++
 3 files changed, 54 insertions(+)
 create mode 100644 cmake/CheckCPUArchitecture.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf8667549029..c1c9e91e45f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,6 +72,7 @@ include(GNUInstallDirs)
 list(APPEND CMAKE_MODULE_PATH "${SDL2_SOURCE_DIR}/cmake")
 include(${SDL2_SOURCE_DIR}/cmake/macros.cmake)
 include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake)
+include(${SDL2_SOURCE_DIR}/cmake/CheckCPUArchitecture.cmake)
 
 # Enable large file support on 32-bit glibc, so that we can access files
 # with large inode numbers
@@ -3229,6 +3230,13 @@ if(SDL_SHARED)
   # alias target for in-tree builds
   add_library(SDL2::SDL2 ALIAS SDL2)
   set_target_properties(SDL2 PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
+  if(NOT SDL_LIBC)
+    check_cpu_architecture(x86 HAS_X86)
+    if(HAS_X86)
+      # FIXME: should be added for all architectures (missing symbols for ARM)
+      target_link_libraries(SDL2 PRIVATE "-nodefaultlib:MSVCRT")
+    endif()
+  endif()
   if(APPLE)
     # FIXME: Remove SOVERSION in SDL3
     set_target_properties(SDL2 PROPERTIES
diff --git a/cmake/CheckCPUArchitecture.cmake b/cmake/CheckCPUArchitecture.cmake
new file mode 100644
index 000000000000..79639f1c2bc4
--- /dev/null
+++ b/cmake/CheckCPUArchitecture.cmake
@@ -0,0 +1,40 @@
+include(CheckCSourceCompiles)
+include(CMakePushCheckState)
+
+function(_internal_check_cpu_architecture macro_check NAME VARIABLE)
+  cmake_push_check_state(RESET)
+  string(TOUPPER "${NAME}" UPPER_NAME)
+  set(CACHE_VARIABLE "CHECK_CPU_ARCHITECTURE_${UPPER_NAME}")
+  set(test_src "
+int main(int argc, char *argv[]) {
+#if ${macro_check}
+  return 0;
+#else
+  choke
+#endif
+}
+")
+  check_c_source_compiles("${test_src}" "${CACHE_VARIABLE}")
+  cmake_pop_check_state()
+  if(${CACHE_VARIABLE})
+    set(${VARIABLE} "TRUE" PARENT_SCOPE)
+  else()
+    set(${VARIABLE} "FALSE" PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(check_cpu_architecture ARCH VARIABLE)
+  if(ARCH STREQUAL "x86")
+    _internal_check_cpu_architecture("defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)" x86 ${VARIABLE})
+  elseif(ARCH STREQUAL "x64")
+    _internal_check_cpu_architecture("defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)" x64 ${VARIABLE})
+  elseif(ARCH STREQUAL "arm32")
+    _internal_check_cpu_architecture("defined(__arm__) || defined(_M_ARM)" arm32 ${VARIABLE})
+  elseif(ARCH STREQUAL "arm64")
+    _internal_check_cpu_architecture("defined(__aarch64__) || defined(_M_ARM64)" arm64 ${VARIABLE})
+  else()
+    message(WARNING "Unknown CPU architectures (${ARCH}).")
+    set(${VARIABLE} FALSE)
+  endif()
+  set("${VARIABLE}" "${${VARIABLE}}" PARENT_SCOPE)
+endfunction()
diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c
index 02eeb0f1ddc9..8f92463b1304 100644
--- a/src/stdlib/SDL_mslibc.c
+++ b/src/stdlib/SDL_mslibc.c
@@ -126,6 +126,12 @@ _ftol2_sse()
     _ftol();
 }
 
+void
+_ftol2()
+{
+    _ftol();
+}
+
 /* 64-bit math operators for 32-bit systems */
 void
 __declspec(naked)