From e13d7b7ac51fdde1c9dd5bb004cecb02385d5c32 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Fri, 11 Sep 2026 13:53:16 +0800 Subject: [PATCH] Fix bundled libuv Windows CPU-info output pointer type --- third_party/CMakeLists.txt | 1 + third_party/LibuvWindows.cmake | 23 +++++++++++++++++++++++ third_party/README.md | 4 ++++ 3 files changed, 28 insertions(+) create mode 100644 third_party/LibuvWindows.cmake diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 7e18a29f..921d1b64 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -66,6 +66,7 @@ endif() set(LIBUV_BUILD_SHARED OFF CACHE BOOL "" FORCE) set(LIBUV_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(LIBUV_BUILD_BENCH OFF CACHE BOOL "" FORCE) +include(LibuvWindows.cmake) add_subdirectory("${uv_SOURCE}" uv EXCLUDE_FROM_ALL) add_library(ss_uv ALIAS uv_a) include(${PROJECT_SOURCE_DIR}/cmake/EventLoop.cmake) diff --git a/third_party/LibuvWindows.cmake b/third_party/LibuvWindows.cmake new file mode 100644 index 00000000..e9cf9f02 --- /dev/null +++ b/third_party/LibuvWindows.cmake @@ -0,0 +1,23 @@ +# libuv 1.52.1 passes const char ** to a converter that writes char **. +# GCC 14+ rejects this. Keep the archive untouched and use a mutable temporary +# in the extracted source, assigning it to the const public field afterwards. +if(WIN32) + set(uv_util "${uv_SOURCE}/src/win/util.c") + file(READ "${uv_util}" uv_util_content) + set(uv_old [=[ uv__convert_utf16_to_utf8(cpu_brand, + cpu_brand_size / sizeof(WCHAR), + &(cpu_info->model));]=]) + set(uv_new [=[ char* model = NULL; + uv__convert_utf16_to_utf8(cpu_brand, + cpu_brand_size / sizeof(WCHAR), + &model); + cpu_info->model = model;]=]) + string(FIND "${uv_util_content}" "${uv_old}" uv_old_offset) + string(FIND "${uv_util_content}" "${uv_new}" uv_new_offset) + if(NOT uv_old_offset EQUAL -1) + string(REPLACE "${uv_old}" "${uv_new}" uv_util_content "${uv_util_content}") + file(WRITE "${uv_util}" "${uv_util_content}") + elseif(uv_new_offset EQUAL -1) + message(FATAL_ERROR "Bundled libuv changed; review the Windows CPU-info compatibility fix") + endif() +endif() diff --git a/third_party/README.md b/third_party/README.md index f844eaea..fc57c586 100644 --- a/third_party/README.md +++ b/third_party/README.md @@ -22,6 +22,10 @@ CMake adapter compiles the portable C backends listed in upstream Makefile.am; it is maintained by this project, not upstream. Upstream known-answer tests are built and run under the `vendor` CTest label. SIMD acceleration needs its own compiler probes and validation before enabling additional backends. +On Windows, `LibuvWindows.cmake` applies a checked, idempotent fix to extracted +libuv 1.52.1 CPU-info code: a mutable string temporary replaces an incompatible +`const char **` output argument rejected by GCC 14+. The archive is unchanged. + Libuv replaces libev. Its Windows socket polling uses AFD readiness requests completed through IOCP; macOS uses kqueue. The internal `ss_event` layer combines read/write watchers for each descriptor and owns libuv handle lifetime separately