SDL_net: cmake: update cmake + VC build system

From a3e8f14e8493243c69c0c658234ba4cda9bc0fa6 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Tue, 26 Sep 2023 20:08:35 +0200
Subject: [PATCH] cmake: update cmake + VC build system

---
 .github/workflows/main.yml                    |   30 +-
 .wikiheaders-options                          |   16 +
 CMakeLists.txt                                |  275 ++-
 VisualC/SDL_net.sln                           |   66 +
 VisualC/SDL_net.vcxproj                       |  223 +++
 VisualC/SDL_net.vcxproj.filters               |   26 +
 VisualC/clean.sh                              |    3 +
 VisualC/examples/get-local-addrs.vcxproj      |  234 +++
 VisualC/examples/resolve-hostnames.vcxproj    |  234 +++
 VisualC/examples/simple-http-get.vcxproj      |  234 +++
 VisualC/examples/voipchat.vcxproj             |  234 +++
 .../cmake/sdl3_net-config-version.cmake       |   54 +
 .../pkg-support/cmake/sdl3_net-config.cmake   |   45 +
 build-scripts/test-versioning.sh              |  141 ++
 build-scripts/wikiheaders.pl                  | 1663 +++++++++++++++++
 cmake/PrivateSdlFunctions.cmake               |  288 +++
 cmake/SDL3_netConfig.cmake.in                 |   38 +
 cmake/sdl3-net.pc.in                          |   13 +
 cmake/sdlmanpages.cmake                       |   62 +
 cmake/test/CMakeLists.txt                     |   35 +
 cmake/test/main.c                             |   19 +
 examples/get-local-addrs.c                    |    3 +
 SDL_net.h => include/SDL3_net/SDL_net.h       |   11 +-
 SDL_net.c => src/SDL_net.c                    |    2 +-
 src/SDL_net.sym                               |   37 +
 src/version.rc                                |   38 +
 26 files changed, 3988 insertions(+), 36 deletions(-)
 create mode 100644 .wikiheaders-options
 create mode 100644 VisualC/SDL_net.sln
 create mode 100644 VisualC/SDL_net.vcxproj
 create mode 100644 VisualC/SDL_net.vcxproj.filters
 create mode 100755 VisualC/clean.sh
 create mode 100644 VisualC/examples/get-local-addrs.vcxproj
 create mode 100644 VisualC/examples/resolve-hostnames.vcxproj
 create mode 100644 VisualC/examples/simple-http-get.vcxproj
 create mode 100644 VisualC/examples/voipchat.vcxproj
 create mode 100644 VisualC/pkg-support/cmake/sdl3_net-config-version.cmake
 create mode 100644 VisualC/pkg-support/cmake/sdl3_net-config.cmake
 create mode 100755 build-scripts/test-versioning.sh
 create mode 100755 build-scripts/wikiheaders.pl
 create mode 100644 cmake/PrivateSdlFunctions.cmake
 create mode 100644 cmake/SDL3_netConfig.cmake.in
 create mode 100644 cmake/sdl3-net.pc.in
 create mode 100644 cmake/sdlmanpages.cmake
 create mode 100644 cmake/test/CMakeLists.txt
 create mode 100644 cmake/test/main.c
 rename SDL_net.h => include/SDL3_net/SDL_net.h (99%)
 rename SDL_net.c => src/SDL_net.c (99%)
 create mode 100644 src/SDL_net.sym
 create mode 100644 src/version.rc

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index b13f82e..fe0c8e1 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -13,7 +13,7 @@ jobs:
       matrix:
         platform:
           - { name: 'Linux',                    os: ubuntu-latest,  shell: sh }
-#          - { name: 'MacOS',                    os: macos-latest,   shell: sh }
+          - { name: 'MacOS',                    os: macos-latest,   shell: sh }
 #          - { name: 'Windows msys2 (mingw32)',  os: windows-latest, shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686 }
           - { name: 'Windows msys2 (mingw64)',  os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64 }
 #          - { name: 'Windows msys2 (clang32)',  os: windows-latest, shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686 }
@@ -56,7 +56,33 @@ jobs:
           add-to-environment: true
       - name: Configure (CMake)
         run: |
-          cmake -B build -GNinja
+          cmake -B build -GNinja \
+            -DCMAKE_BUILD_TYPE=Release \
+            -DCMAKE_INSTALL_PREFIX=prefix \
+            -DSDL3NET_WERROR=OFF \
+            -DCMAKE_INSTALL_PREFIX=prefix
+        # FIXME: enable SDL3NET_WERROR
+
       - name: Build (CMake)
         run: |
           cmake --build build/ --verbose
+      - name: Install (CMake)
+        if: ${{ matrix.platform.shell == 'sh' || contains(matrix.platform.shell, 'msys2') }}
+        run: |
+          set -eu
+          rm -fr DESTDIR-cmake
+          cmake --install build/ --config Release
+          echo "SDL3_net_ROOT=$(pwd)/prefix" >> $GITHUB_ENV
+          ( cd prefix; find . ) | LC_ALL=C sort -u
+      - name: Verify CMake configuration files
+        run: |
+          cmake -S cmake/test -B cmake_config_build \
+            -DCMAKE_BUILD_TYPE=Release \
+            -DTEST_SHARED=TRUE \
+            -DTEST_STATIC=FALSE
+          cmake --build cmake_config_build --verbose
+
+      - name: Check that versioning is consistent
+        # We only need to run this once: arbitrarily use the Linux build
+        if: ${{ runner.os == 'Linux' }}
+        run: ./build-scripts/test-versioning.sh
diff --git a/.wikiheaders-options b/.wikiheaders-options
new file mode 100644
index 0000000..9697ef2
--- /dev/null
+++ b/.wikiheaders-options
@@ -0,0 +1,16 @@
+projectfullname = SDL_net
+projectshortname = SDL_net
+incsubdir = include/SDL3_net
+wikisubdir = SDL_net
+apiprefixregex = SDLNet_
+mainincludefname = SDL3_net/SDL_net.h
+versionfname = include/SDL3_net/SDL_net.h
+versionmajorregex = \A\#define\s+SDL_NET_MAJOR_VERSION\s+(\d+)\Z
+versionminorregex = \A\#define\s+SDL_NET_MINOR_VERSION\s+(\d+)\Z
+versionpatchregex = \A\#define\s+SDL_NET_PATCHLEVEL\s+(\d+)\Z
+selectheaderregex = \ASDL_net\.h\Z
+projecturl = https://libsdl.org/projects/SDL_net
+wikiurl = https://wiki.libsdl.org/SDL_net
+bugreporturl = https://github.com/libsdl-org/sdlwiki/issues/new
+warn_about_missing = 0
+wikipreamble = (This function is part of SDL_net, a separate library from SDL.)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7267c6..895e739 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,37 +1,260 @@
 cmake_minimum_required(VERSION 3.16)
-project(SDL3_net VERSION 3.0.0)
 
-find_package(SDL3 REQUIRED COMPONENTS SDL3)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
 
-add_library(SDL3_net SHARED SDL_net.c)
-add_library(SDL3_net::SDL3_net ALIAS SDL3_net)
-target_include_directories(SDL3_net PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
-target_link_libraries(SDL3_net PRIVATE SDL3::SDL3)
+# See docs/release_checklist.md
+set(MAJOR_VERSION 3)
+set(MINOR_VERSION 0)
+set(MICRO_VERSION 0)
+set(SDL_REQUIRED_VERSION 3.0.0)
+
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+    message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL_net source code and call cmake from there")
+endif()
+
+project(SDL3_net
+    LANGUAGES C
+    VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}"
+)
+
+include(PrivateSdlFunctions)
+include(sdlmanpages)
+sdl_calculate_derived_version_variables(${MAJOR_VERSION} ${MINOR_VERSION} ${MICRO_VERSION})
+
+message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}")
+
+if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
+    set(SDL3NET_ROOTPROJECT ON)
+else()
+    set(SDL3NET_ROOTPROJECT OFF)
+endif()
+
+set(SDL3NET_SAMPLES_DEFAULT ${SDL3NET_ROOTPROJECT})
+if(ANDROID)
+    set(SDL3NET_SAMPLES_DEFAULT OFF)
+endif()
+
+set(sdl3net_install_enableable ON)
+if((TARGET SDL3-shared OR TARGET SDL3-static) AND SDL_DISABLE_INSTALL)
+    # Cannot install SDL3_net when SDL3 is built in same built, and is not installed.
+    set(sdl3net_install_enableable OFF)
+endif()
+
+if(NOT DEFINED CMAKE_FIND_PACKAGE_PREFER_CONFIG)
+    set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+endif()
+
+include(CMakeDependentOption)
+include(CMakePackageConfigHelpers)
+include(GNUInstallDirs)
+
+option(CMAKE_POSITION_INDEPENDENT_CODE "Build static libraries with -fPIC" ON)
+option(BUILD_SHARED_LIBS "Build the library as a shared library" ON)
+
+cmake_dependent_option(SDL3NET_INSTALL "Enable SDL3_net install target" ${SDL3NET_ROOTPROJECT} "${sdl3net_install_enableable}" OFF)
+cmake_dependent_option(SDL3NET_INSTALL_MAN "Install man pages for SDL3_net" ${SDL3NET_ROOTPROJECT} "SDL3NET_INSTALL" OFF)
+option(SDL3NET_WERROR "Treat warnings as errors" OFF)
+
+option(SDL3NET_SAMPLES "Build the SDL3_net sample program(s)" ${SDL3NET_SAMPLES_DEFAULT})
+cmake_dependent_option(SDL3NET_SAMPLES_INSTALL "Install the SDL3_net sample program(s)" OFF "SDL3NET_SAMPLES;SDL3NET_INSTALL" OFF)
+
+# Save BUILD_SHARED_LIBS variable
+set(SDL3NET_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
+
+set(sdl_required_components Headers)
+
+if(SDL3NET_BUILD_SHARED_LIBS)
+    set(sdl3_net_target_name SDL3_net-shared)
+    set(sdl3_target_name SDL3::SDL3-shared)
+
+    list(APPEND sdl_required_components SDL3-shared)
+else()
+    set(sdl3_net_target_name SDL3_net-static)
+    set(sdl3_target_name SDL3::SDL3)
+endif()
+
+if(NOT TARGET SDL3::Headers OR NOT TARGET ${sdl3_target_name})
+    find_package(SDL3 ${SDL_REQUIRED_VERSION} REQUIRED COMPONENTS ${sdl_required_components})
+endif()
+
+set(PC_LIBS)
+set(PC_REQUIRES)
+
+add_library(${sdl3_net_target_name} src/SDL_net.c)
+add_library(SDL3_net::${sdl3_net_target_name} ALIAS ${sdl3_net_target_name})
+set_property(TARGET ${sdl3_net_target_name} PROPERTY C_STANDARD 99)
+if(NOT TARGET SDL3_net::SDL3_net)
+    add_library(SDL3_net::SDL3_net ALIAS ${sdl3_net_target_name})
+endif()
+target_include_directories(${sdl3_net_target_name}
+    PUBLIC
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/SDL3_net>"
+        "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+        "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL3_net>"
+)
+target_compile_definitions(${sdl3_net_target_name} PRIVATE
+    BUILD_SDL
+    SDL_BUILD_MAJOR_VERSION=${MAJOR_VERSION}
+    SDL_BUILD_MINOR_VERSION=${MINOR_VERSION}
+    SDL_BUILD_MICRO_VERSION=${MICRO_VERSION}
+)
+target_link_libraries(${sdl3_net_target_name} PUBLIC SDL3::Headers)
+if(SDL3NET_BUILD_SHARED_LIBS)
+    target_link_libraries(${sdl3_net_target_name} PRIVATE SDL3::SDL3-shared)
+endif()
+sdl_add_warning_options(${sdl3_net_target_name} WARNING_AS_ERROR ${SDL3NET_WERROR})
 if(WIN32)
-    target_link_libraries(SDL3_net PRIVATE ws2_32 iphlpapi)
-    set_target_properties(SDL3_net PROPERTIES
-        OUTPUT_NAME "SDL3_net"
-        DEFINE_SYMBOL DLL_EXPORT
-        EXPORT_NAME SDL3_net
-        C_VISIBILITY_PRESET "hidden"
-    )
+    if(SDL3NET_BUILD_SHARED_LIBS)
+        target_sources(${sdl3_net_target_name} PRIVATE
+            src/version.rc
+        )
+    endif()
+    target_link_libraries(${sdl3_net_target_name} PRIVATE iphlpapi ws2_32)
+    list(APPEND PC_LIBS -liphlpapi -lws2_32)
 endif()
-if(UNIX AND NOT APPLE)
-    set_property(TARGET SDL3_net PROPERTY SOVERSION ${PROJECT_VERSION_MAJOR})
-    set_property(TARGET SDL3_net PROPERTY VERSION ${PROJECT_VERSION})
+set_target_properties(${sdl3_net_target_name} PROPERTIES
+    OUTPUT_NAME "SDL3_net"
+    DEFINE_SYMBOL DLL_EXPORT
+    EXPORT_NAME ${sdl3_net_target_name}
+    C_VISIBILITY_PRESET "hidden"
+)
+
+sdl_target_link_option_version_file(${sdl3_net_target_name} "${CMAKE_CURRENT_SOURCE_DIR}/src/SDL_net.sym")
+
+if(NOT ANDROID)
+    if(APPLE)
+        # the SOVERSION property corresponds to the compatibility version and VERSION corresponds to the current version
+        # https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html#mach-o-versions
+        set_target_properties(${sdl3_net_target_name} PROPERTIES
+            SOVERSION "${DYLIB_COMPAT_VERSION}"
+            VERSION "${DYLIB_CURRENT_VERSION}"
+        )
+        sdl_no_deprecated_errors(${sdl3_net_target_name})
+    else()
+        set_target_properties(${sdl3_net_target_name} PROPERTIES
+            SOVERSION "${SO_VERSION_MAJOR}"
+            VERSION "${SO_VERSION}"
+        )
+    endif()
 endif()
-if(NOT MSVC AND NOT APPLE)
-    target_link_options(SDL3_net PRIVATE -Wl,--no-undefined)
+if(SDL3NET_BUILD_SHARED_LIBS)
+    if(WIN32)
+        set_target_properties(${sdl3_net_target_name} PROPERTIES
+            PREFIX ""
+        )
+    endif()
+else()
+    if(MSVC)
+        set_target_properties(${sdl3_net_target_name} PROPERTIES
+            OUTPUT_NAME "SDL3_net-static"
+        )
+    endif()
 endif()
 
-add_executable(voipchat examples/voipchat.c)
-target_link_libraries(voipchat PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
+# Use `Compatible Interface Properties` to ensure a shared SDL3_net is built with a shared SDL3
+if(SDL3NET_BUILD_SHARED_LIBS)
+    set_property(TARGET ${sdl3_net_target_name} PROPERTY INTERFACE_SDL3_SHARED TRUE)
+    set_property(TARGET ${sdl3_net_target_name} APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL3_SHARED)
+endif()
 
-add_executable(simple-http-get examples/simple-http-get.c)
-target_link_libraries(simple-http-get PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
+if(SDL3NET_BUILD_SHARED_LIBS)
+    sdl_target_link_options_no_undefined(${sdl3_net_target_name})
+endif()
 
-add_executable(resolve-hostnames examples/resolve-hostnames.c)
-target_link_libraries(resolve-hostnames PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
+if(SDL3NET_INSTALL)
+    install(
+        TARGETS ${sdl3_net_target_name}
+        EXPORT SDL3NetExports
+        ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel
+        LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT library
+        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT library
+    )
+    install(
+        FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/SDL3_net/SDL_net.h"
+        DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL3_net" COMPONENT devel
+    )
+
+    if(WIN32 AND NOT MINGW)
+        set(SDL3NET_INSTALL_CMAKEDIR_ROOT_DEFAULT "cmake")
+    else()
+        set(SDL3NET_INSTALL_CMAKEDIR_ROOT_DEFAULT "${CMAKE_INSTALL_LIBDIR}/cmake")
+    endif()
+    set(SDL3NET_INSTALL_CMAKEDIR_ROOT "${SDL3NET_INSTALL_CMAKEDIR_ROOT_DEFAULT}" CACHE STRING "Root folder where to install SDL3_netConfig.cmake related files (SDL3_net subfolder for MSVC projects)")
+    set(SDLNET_PKGCONFIG_INSTALLDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
 
-add_executable(get-local-addrs examples/get-local-addrs.c)
-target_link_libraries(get-local-addrs PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
+    if(WIN32 AND NOT MINGW)
+        set(SDL3NET_INSTALL_CMAKEDIR "${SDL3NET_INSTALL_CMAKEDIR_ROOT}")
+        set(LICENSES_PREFIX "licenses/SDL3_net")
+    else()
+        set(SDL3NET_INSTALL_CMAKEDIR "${SDL3NET_INSTALL_CMAKEDIR_ROOT}/SDL3_net")
+        set(LICENSES_PREFIX "${CMAKE_INSTALL_DATAROOTDIR}/licenses/SDL3_net")
+    endif()
+
+    configure_package_config_file(cmake/SDL3_netConfig.cmake.in SDL3_netConfig.cmake
+        INSTALL_DESTINATION "${SDL3NET_INSTALL_CMAKEDIR}"
+    )
+    write_basic_package_version_file("${PROJECT_BINARY_DIR}/SDL3_netConfigVersion.cmake"
+        COMPATIBILITY AnyNewerVersion
+    )
+    install(
+        FILES
+            "${CMAKE_CURRENT_BINARY_DIR}/SDL3_netConfig.cmake"
+            "${CMAKE_CURRENT_BINARY_DIR}/SDL3_netConfigVersion.cmake"
+        DESTINATION "${SDL3NET_INSTALL_CMAKEDIR}"
+        COMPONENT devel
+    )
+    install(EXPORT SDL3NetExports
+        FILE ${sdl3_net_target_name}-targets.cmake
+        NAMESPACE SDL3_net::
+        DESTINATION "${SDL3NET_INSTALL_CMAKEDIR}"
+        COMPONENT devel
+    )
+
+    file(RELATIVE_PATH SDL_PATH_PREFIX_RELATIVE_TO_PKGCONFIG "${CMAKE_INSTALL_PREFIX}/${SDLNET_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}")
+
+    string(JOIN " " PC_REQUIRES ${PC_REQUIRES})
+    string(JOIN " " PC_LIBS ${PC_LIBS})
+    configure_file(cmake/sdl3-net.pc.in sdl3-net.pc @ONLY)
+
+    # Always install sdl3-net.pc file: libraries might be different between config modes
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdl3-net.pc"
+        DESTINATION "${SDLNET_PKGCONFIG_INSTALLDIR}" COMPONENT devel)
+
+    install(FILES "LICENSE.txt"
+        DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}"
+        COMPONENT library
+    )
+
+    if(SDL3NET_INSTALL_MAN)
+        SDL_generate_manpages(
+            HEADERS_DIR "${PROJECT_SOURCE_DIR}/include/SDL3_net"
+            SYMBOL "SDLNet_Init"
+            WIKIHEADERS_PL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build-scripts/wikiheaders.pl"
+        )
+    endif()
+endif()
+
+if(SDL3NET_SAMPLES)
+    add_executable(voipchat examples/voipchat.c)
+    add_executable(simple-http-get examples/simple-http-get.c)
+    add_executable(resolve-hostnames examples/resolve-hostnames.c)
+    add_executable(get-local-addrs examples/get-local-addrs.c)
+
+    set(examples voipchat simple-http-get resolve-hostnames get-local-addrs)
+    foreach(example IN LISTS examples)
+        target_link_libraries(${example} PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
+        set_property(TARGET ${example} PROPERTY C_STANDARD 99)
+        set_property(TARGET ${example} PROPERTY C_EXTENSIONS FALSE)
+        sdl_add_warning_options(${example} WARNING_AS_ERROR ${SDL3NET_WERROR})
+        if(SDL3NET_SAMPLES_INSTALL)
+            install(TARGETS ${example}
+                RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+            )
+        endif()
+    endforeach()
+    # Build at least one example in C90
+    set_property(TARGET get-local-addrs PROPERTY C_STANDARD 90)
+endif()
diff --git a/VisualC/SDL_net.sln b/VisualC/SDL_net.sln
new file mode 100644
index 0000000..9f5eed1
--- /dev/null
+++ b/VisualC/SDL_net.sln
@@ -0,0 +1,66 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL3_net", "SDL_net.vcxproj", "{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "get-local-addrs", "examples\get-local-addrs.vcxproj", "{7B1F60CD-2A09-4514-937C-D9DD044428FB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resolve-hostnames", "examples\resolve-hostnames.vcxproj", "{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple-http-get", "examples\simple-http-get.vcxproj", "{35F14669-ED09-4105-A035-7984B94FDFBC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "voipchat", "examples\voipchat.vcxproj", "{A01E2216-139A-480E-8458-03CB4E90FE61}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Debug|Win32.Build.0 = Debug|Win32
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Debug|x64.ActiveCfg = Debug|x64
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Debug|x64.Build.0 = Debug|x64
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Release|Win32.ActiveCfg = Release|Win32
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Release|Win32.Build.0 = Release|Win32
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Release|x64.ActiveCfg = Release|x64
+		{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}.Release|x64.Build.0 = Release|x64
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Debug|Win32.Build.0 = Debug|Win32
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Debug|x64.ActiveCfg = Debug|x64
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Debug|x64.Build.0 = Debug|x64
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Release|Win32.ActiveCfg = Release|Win32
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Release|Win32.Build.0 = Release|Win32
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Release|x64.ActiveCfg = Release|x64
+		{7B1F60CD-2A09-4514-937C-D9DD044428FB}.Release|x64.Build.0 = Release|x64
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Debug|Win32.Build.0 = Debug|Win32
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Debug|x64.ActiveCfg = Debug|x64
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Debug|x64.Build.0 = Debug|x64
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Release|Win32.ActiveCfg = Release|Win32
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Release|Win32.Build.0 = Release|Win32
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Release|x64.ActiveCfg = Release|x64
+		{8DAC2820-128D-4FAF-9416-A8AD4C6D7A9A}.Release|x64.Build.0 = Release|x64
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Debug|Win32.Build.0 = Debug|Win32
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Debug|x64.ActiveCfg = Debug|x64
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Debug|x64.Build.0 = Debug|x64
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Release|Win32.ActiveCfg = Release|Win32
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Release|Win32.Build.0 = Release|Win32
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Release|x64.ActiveCfg = Release|x64
+		{35F14669-ED09-4105-A035-7984B94FDFBC}.Release|x64.Build.0 = Release|x64
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Debug|Win32.Build.0 = Debug|Win32
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Debug|x64.ActiveCfg = Debug|x64
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Debug|x64.Build.0 = Debug|x64
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Release|Win32.ActiveCfg = Release|Win32
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Release|Win32.Build.0 = Release|Win32
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Release|x64.ActiveCfg = Release|x64
+		{A01E2216-139A-480E-8458-03CB4E90FE61}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/VisualC/SDL_net.vcxproj b/VisualC/SDL_net.vcxproj
new file mode 100644
index 0000000..69195e9
--- /dev/null
+++ b/VisualC/SDL_net.vcxproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>SDL3_net</ProjectName>
+    <ProjectGuid>{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}</ProjectGuid>
+    <RootNamespace>SDL_net</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IncludePath>$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IncludePath>$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IncludePath>$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IncludePath>$(ProjectDir)..\..\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(ProjectDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>.\Debug/SDL3_net.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>ws2_32.lib;iphlpapi.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Debug/SDL3_net.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>ws2_32.lib;iphlpapi.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</Generat

(Patch may be truncated, please check the link at the top of this post.)