From a75110570a8427241c4128d3ac68a23d31ac0a71 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Mon, 21 Jul 2025 01:57:26 +0200 Subject: [PATCH] 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 0d71b18153c8edb996738f8a362373fc72d0013b #17413 Closes #17982 --- .github/workflows/windows.yml | 2 +- CMakeLists.txt | 23 ++++++++++++++--------- appveyor.yml | 2 +- configure.ac | 22 ++++++++++++++++++++-- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 084eb3b273..ac42055dc6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f6f1b1e4..6e046c8b3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/appveyor.yml b/appveyor.yml index fc8d49152e..cbba5fec00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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' diff --git a/configure.ac b/configure.ac index 1d4746c8c4..6e33598603 100644 --- a/configure.ac +++ b/configure.ac @@ -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 + #include + ]],[[ + 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 \ ]) -- 2.47.2