cmake: work around ios.toolchain.cmake breaking feature-detections

Fix builds with CMake configured to falsely return successful detection
when using `check_function_exists()` (and `check_library_exists()`, and
anything based on `try_compile()` that's relying on the linker). After
such mis-detection the build fails when trying to use the feature that
doesn't in fact exist.

The mis-detection is caused by this CMake setting:
```
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
```
It is set by default (or on conditions) when using 3rd-party toolchain:
https://github.com/leetal/ios-cmake/blob/master/ios.toolchain.cmake

After this patch the curl build overrides this setting for the duration
of feature tests, and logs a message about it.

Also preset and skip feature tests for known mis-detections:
- `connect()` in `libsocket`
- `getpass_r()`
- `eventfd()` (did not cause an issue due to a separate bug)
- `sendmmsg()` (did not cause an issue because it's Linux-only)

If mis-detections are still seen, the workaround is to force-set the
specific feature by passing `-DHAVE_*=OFF` to cmake.
Also consider passing `-DENABLE_STRICT_TRY_COMPILE=ON` for
`ios.toolchain.cmake` to fix the root cause.

Interestingly curl itself uses this setting to speed up compile-only
detections: be17f298ff #3744

Also:
- OtherTests.cmake: restore original value of
  `CMAKE_TRY_COMPILE_TARGET_TYPE`. Before this patch it reset it
  to empty.
- OtherTests.cmake: unset a local variable after use, quote a string.

Follow-up to 8e34505776 #15164
Follow-up to 8b76a8aeb2 #15525
Ref: https://github.com/leetal/ios-cmake/issues/47
Ref: https://gitlab.kitware.com/cmake/cmake/-/issues/18121
Ref: https://cmake.org/cmake/help/latest/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.html
Reported-by: Dan Rosser
Fixes #15557
Closes #15559
This commit is contained in:
Viktor Szakats 2024-11-12 15:22:50 +01:00
parent e3aa2a07f9
commit 93e6e4b823
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
2 changed files with 28 additions and 3 deletions

View File

@ -32,7 +32,8 @@ macro(add_header_include _check _header)
endif() endif()
endmacro() endmacro()
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) set(_cmake_try_compile_target_type_save ${CMAKE_TRY_COMPILE_TARGET_TYPE})
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE) if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE)
cmake_push_check_state() cmake_push_check_state()
@ -74,7 +75,8 @@ check_c_source_compiles("${_source_epilogue}
return 0; return 0;
}" HAVE_STRUCT_TIMEVAL) }" HAVE_STRUCT_TIMEVAL)
unset(CMAKE_TRY_COMPILE_TARGET_TYPE) set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_cmake_try_compile_target_type_save})
unset(_cmake_try_compile_target_type_save)
# Detect HAVE_GETADDRINFO_THREADSAFE # Detect HAVE_GETADDRINFO_THREADSAFE
@ -150,3 +152,5 @@ if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
return 0; return 0;
}" HAVE_CLOCK_GETTIME_MONOTONIC_RAW) }" HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
endif() endif()
unset(_source_epilogue)

View File

@ -129,6 +129,17 @@ if(NOT DEFINED CMAKE_UNITY_BUILD_BATCH_SIZE)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 0) set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
endif() endif()
# Having CMAKE_TRY_COMPILE_TARGET_TYPE set to STATIC_LIBRARY breaks certain
# 'check_function_exists()' detections (possibly more), by detecting
# non-existing features. This happens by default when using 'ios.toolchain.cmake'.
# Work it around by setting this value to `EXECUTABLE`.
if(CMAKE_TRY_COMPILE_TARGET_TYPE STREQUAL "STATIC_LIBRARY")
message(STATUS "CMAKE_TRY_COMPILE_TARGET_TYPE was found set to STATIC_LIBRARY. "
"Overriding with EXECUTABLE for feature detections to work.")
set(_cmake_try_compile_target_type_save ${CMAKE_TRY_COMPILE_TARGET_TYPE})
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
endif()
option(CURL_WERROR "Turn compiler warnings into errors" OFF) option(CURL_WERROR "Turn compiler warnings into errors" OFF)
option(PICKY_COMPILER "Enable picky compiler options" ON) option(PICKY_COMPILER "Enable picky compiler options" ON)
option(BUILD_CURL_EXE "Build curl executable" ON) option(BUILD_CURL_EXE "Build curl executable" ON)
@ -456,6 +467,11 @@ include(CheckCSourceCompiles)
# Preload settings on Windows # Preload settings on Windows
if(WIN32) if(WIN32)
include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake")
elseif(APPLE)
# Fast-track predicable feature detections
set(HAVE_EVENTFD 0)
set(HAVE_GETPASS_R 0)
set(HAVE_SENDMMSG 0)
endif() endif()
if(ENABLE_THREADED_RESOLVER) if(ENABLE_THREADED_RESOLVER)
@ -470,7 +486,7 @@ if(ENABLE_THREADED_RESOLVER)
endif() endif()
# Check for all needed libraries # Check for all needed libraries
if(NOT WIN32) if(NOT WIN32 AND NOT APPLE)
check_library_exists("socket" "connect" "" HAVE_LIBSOCKET) check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
if(HAVE_LIBSOCKET) if(HAVE_LIBSOCKET)
set(CURL_LIBS "socket;${CURL_LIBS}") set(CURL_LIBS "socket;${CURL_LIBS}")
@ -1751,6 +1767,11 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
endif() endif()
endif() endif()
if(_cmake_try_compile_target_type_save)
set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_cmake_try_compile_target_type_save})
unset(_cmake_try_compile_target_type_save)
endif()
include(CMake/OtherTests.cmake) include(CMake/OtherTests.cmake)
add_definitions("-DHAVE_CONFIG_H") add_definitions("-DHAVE_CONFIG_H")