]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
windows: fix `if_nametoindex()` detection with autotools, improve with cmake
authorViktor Szakats <commit@vsz.me>
Sun, 20 Jul 2025 23:57:26 +0000 (01:57 +0200)
committerViktor Szakats <commit@vsz.me>
Mon, 21 Jul 2025 11:30:01 +0000 (13:30 +0200)
- 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 0d71b18153c8edb996738f8a362373fc72d0013b #17413

Closes #17982

.github/workflows/windows.yml
CMakeLists.txt
appveyor.yml
configure.ac

index 084eb3b273e61bba387abe7f6537e4e3f24a036a..ac42055dc65db2c3de10f1ea252657b949ac4b87 100644 (file)
@@ -203,7 +203,7 @@ jobs:
           - { build: 'cmake'    , sys: 'msys'      , env: 'x86_64'       , tflags: ''       , config: '-DENABLE_DEBUG=ON -DENABLE_THREADED_RESOLVER=OFF', install: 'openssl-devel libssh2-devel', name: 'default' }
           - { build: 'autotools', sys: 'msys'      , env: 'x86_64'       , tflags: ''       , config: '--with-openssl', install: 'openssl-devel libssh2-devel', name: 'default R' }
           # MinGW
-          - { build: 'autotools', sys: 'mingw64'   , env: 'x86_64'       , tflags: 'skiprun', config: '--enable-debug --with-openssl --disable-threaded-resolver --disable-curldebug --enable-static=no --without-zlib', install: 'mingw-w64-x86_64-openssl mingw-w64-x86_64-libssh2', name: 'default' }
+          - { build: 'autotools', sys: 'mingw64'   , env: 'x86_64'       , tflags: 'skiprun', config: '--enable-debug --with-openssl --disable-threaded-resolver --disable-curldebug --enable-static=no --without-zlib CPPFLAGS=-D_WIN32_WINNT=0x0501', install: 'mingw-w64-x86_64-openssl mingw-w64-x86_64-libssh2', name: 'default XP' }
           - { build: 'autotools', sys: 'mingw64'   , env: 'x86_64'       , tflags: ''       , config: '--enable-debug --with-openssl --enable-windows-unicode --enable-ares --with-openssl-quic --enable-shared=no', install: 'mingw-w64-x86_64-openssl mingw-w64-x86_64-nghttp3 mingw-w64-x86_64-libssh2', name: 'c-ares U' }
           - { build: 'cmake'    , sys: 'mingw64'   , env: 'x86_64'       , tflags: ''       , config: '-DENABLE_DEBUG=ON  -DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON -DENABLE_ARES=ON', install: 'mingw-w64-x86_64-libssh2', type: 'Debug', name: 'schannel c-ares U' }
           # WARNING: libssh uses hard-coded world-writable paths (/etc/..., ~/.ssh/) to
index 31f6f1b1e425de5a545308dc137d2fdb120a6ebc..6e046c8b3e6dd1fb188f9c8edfd31d6cc74898b3 100644 (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)
index fc8d49152e63dc92b0290cc52ce08a41161e6381..cbba5fec00707bf1ebeebecd736c0c4ed31a5522 100644 (file)
@@ -61,7 +61,7 @@ environment:
       SCHANNEL: 'ON'
       DEBUG: 'OFF'
       CURLDEBUG: 'ON'
-    - job_name: 'CMake, VS2010, Debug, x64, OpenSSL 1.0.2 + Schannel, Shared, Build-tests & examples'
+    - job_name: 'CMake, VS2010, Debug, x64, OpenSSL 1.0.2 + Schannel, Shared, Build-tests & examples, XP'
       APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2013'
       PRJ_GEN: 'Visual Studio 10 2010'
       TARGET: '-A x64'
index 1d4746c8c4106d85277a739c799039d1c61efd0a..6e335986036ff8d7d9287fd89e59f4ae90c5c5e6 100644 (file)
@@ -4224,7 +4224,6 @@ AC_CHECK_FUNCS([\
   getpwuid_r \
   getrlimit \
   gettimeofday \
-  if_nametoindex \
   mach_absolute_time \
   pipe \
   pipe2 \
@@ -4238,8 +4237,27 @@ AC_CHECK_FUNCS([\
   utimes \
 ])
 
-if test "$curl_cv_native_windows" != 'yes'; then
+if test "$curl_cv_native_windows" = 'yes'; then
+  AC_MSG_CHECKING([for if_nametoindex on Windows])
+  AC_LINK_IFELSE([
+    AC_LANG_PROGRAM([[
+      #ifndef WIN32_LEAN_AND_MEAN
+      #define WIN32_LEAN_AND_MEAN
+      #endif
+      #include <winsock2.h>
+      #include <iphlpapi.h>
+    ]],[[
+      if_nametoindex("");
+    ]])
+  ],[
+    AC_MSG_RESULT([yes])
+    AC_DEFINE(HAVE_IF_NAMETOINDEX, 1, [if you have the 'if_nametoindex' function])
+  ],[
+    AC_MSG_RESULT([no])
+  ])
+else
   AC_CHECK_FUNCS([\
+    if_nametoindex \
     realpath \
     sched_yield \
   ])