windows: fix if_nametoindex() detection with autotools, improve with cmake

- autotools: fix auto-detection on the Windows platform.
  It was mis-detected when targeting Windows XP/2003 64-bit.
  It was permanently undetected when building for Windows 32-bit.
  ```
  lib/url.c: In function 'zonefrom_url':
  lib/url.c:1802:18: error: implicit declaration of function 'if_nametoindex' [-Wimplicit-function-declaration]
   1802 |       scopeidx = if_nametoindex(zoneid);
        |                  ^~~~~~~~~~~~~~
  lib/url.c:1802:18: error: nested extern declaration of 'if_nametoindex' [-Werror=nested-externs]
  ```
  Ref: https://github.com/curl/curl/actions/runs/16405598782/job/46351023138?pr=17982#step:10:29

  Reported-by: LoRd_MuldeR
  Fixes #17979

  Without this patch the workaround for the 8.15.0 release is:
  `export ac_cv_func_if_nametoindex=0` for Windows XP/2003 64-bit.

  Background: Checking for the `if_nametoindex()` function via
  `AC_CHECK_FUNCS()` (autotools) or `check_function_exists()` (cmake) do
  not work on Windows, for two reasons:
  - the function may be disabled at compile-time in Windows headers
    when targeting old Windows versions (XP or WS2003 in curl context)
    via `_WIN32_WINNT`. But it's always present in the system implib
    `iphlpapi` where these checks are looking.
  - for 32-bit Windows the function signature in the implib requires
    a 4-byte argument, while these checks always use no arguments,
    making them always fail.

- cmake: call `if_nametoindex` dynamically with mingw-w64 v1.0.
  This mingw-w64 version lacks prototype and implib entry for it.

- cmake: add auto-detection for Windows and use as a fallback for
  non-pre-fill cases.

- cmake: disable pre-fill with `_CURL_PREFILL=OFF`. (for testing)

- cmake: disable pre-fill for untested compilers. (i.e. non-MSVC,
  non-mingw64)

- GHA/windows: make an autotools job build for Windows XP.

Follow-up to 0d71b18153 #17413

Closes #17982
This commit is contained in:
Viktor Szakats 2025-07-21 01:57:26 +02:00
parent 3d302250ec
commit a75110570a
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
4 changed files with 36 additions and 13 deletions

View file

@ -1609,14 +1609,17 @@ if(WIN32)
endif()
# Pre-fill detection results based on target OS version
if(HAVE_WIN32_WINNT AND HAVE_WIN32_WINNT GREATER_EQUAL 0x0600 AND # Windows Vista or newer
(MINGW OR MSVC) AND
NOT WINCE AND NOT WINDOWS_STORE)
set(HAVE_IF_NAMETOINDEX 1)
else()
set(HAVE_IF_NAMETOINDEX 0)
if(_CURL_PREFILL)
if(NOT HAVE_WIN32_WINNT OR HAVE_WIN32_WINNT LESS 0x0600 OR # older than Windows Vista
(MINGW AND MINGW64_VERSION VERSION_LESS 2.0) OR
WINCE OR WINDOWS_STORE)
set(HAVE_IF_NAMETOINDEX 0)
unset(HAVE_IF_NAMETOINDEX CACHE)
elseif(MSVC OR MINGW)
set(HAVE_IF_NAMETOINDEX 1)
unset(HAVE_IF_NAMETOINDEX CACHE)
endif()
endif()
unset(HAVE_IF_NAMETOINDEX CACHE)
endif()
if(NOT WIN32)
@ -1772,12 +1775,14 @@ check_function_exists("eventfd" HAVE_EVENTFD)
check_symbol_exists("ftruncate" "unistd.h" HAVE_FTRUNCATE)
check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) # winsock2.h unistd.h proto/bsdsocket.h
check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME) # winsock2.h unistd.h proto/bsdsocket.h
check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # iphlpapi.h (Windows Vista+ non-UWP), net/if.h
check_function_exists("getrlimit" HAVE_GETRLIMIT)
check_function_exists("setlocale" HAVE_SETLOCALE)
check_function_exists("setrlimit" HAVE_SETRLIMIT)
if(NOT WIN32)
if(WIN32)
check_symbol_exists("if_nametoindex" "winsock2.h;iphlpapi.h" HAVE_IF_NAMETOINDEX) # Windows Vista+ non-UWP
else()
check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # net/if.h
check_function_exists("realpath" HAVE_REALPATH)
check_function_exists("sched_yield" HAVE_SCHED_YIELD)
check_symbol_exists("strcasecmp" "string.h" HAVE_STRCASECMP)