Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake configuration is wrong on iOS #451

Closed
lagner opened this issue Dec 17, 2021 · 5 comments
Closed

CMake configuration is wrong on iOS #451

lagner opened this issue Dec 17, 2021 · 5 comments

Comments

@lagner
Copy link

lagner commented Dec 17, 2021

DNS resolving on iOS does not work without libresolv. But identifying dependency with Autotools and CMake are different.

Autotools checks that the function exists in resolv library

dnl resolv lib for Apple (MacOS and iOS)
AS_IF([test "x$host_vendor" = "xapple"], [
  AC_SEARCH_LIBS([res_servicename], [resolv], [
    AC_DEFINE([CARES_USE_LIBRESOLV], [1], [Use resolver library to configure cares])
  ], [
    AC_MSG_ERROR([Unable to find libresolv which is required for iPhone targets])
  ])
])

CMake, if I understand correctly, checks if the function exists in the system scope and if so, it rejects the library.

CARES_FUNCTION_IN_LIBRARY (res_servicename resolv HAVE_RES_SERVICENAME_IN_LIBRESOLV)
IF (HAVE_RES_SERVICENAME_IN_LIBRESOLV)
	SET (HAVE_LIBRESOLV 1)
ENDIF ()

Therefore we have

-- Looking for res_servicename
-- Looking for res_servicename - found

But HAVE_LIBRESOLV is undefined

How to reproduce
Get the iOS toolchain file here and run

cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS64
@bradh352
Copy link
Member

Can you explain the error you are receiving? Both set CARES_USE_LIBRESOLV within ares_config.h.

And for cmake, it generates the c-ares-config.cmake file containing all the build instructions for any external project linking which should include the libresolv dep. Likewise, for autotools, it generates a package config file that does the same purpose.

MacOS actually uses the exact same logic as iOS, I haven't tried the ios toolchain file.

We used to autobuild for ios when travis was working, but since they stopped supporting open source, it wasn't re-added for cirrus-ci, its still on the todo list so we may not have visibility into any issues there.

That said, in my day job, we use c-ares and build ios apps and I don't recall any issues...

@lagner
Copy link
Author

lagner commented Dec 20, 2021

First of all, there are no errors during the build. But name resolving does not work on iOS devices. We use C-Ares with Curl and get the following error in runtime

Couldn't resolve host name

Let me show step by step.
I've done the tiny commit to highlighting CMake logic here. Then I run the build

✓ ~/Projects/c-ares % mkdir build && cd build
✓ ~/Projects/c-ares/build % curl https://raw.githubusercontent.com/leetal/ios-cmake/master/ios.toolchain.cmake -o ios.toolchain.cmake -s 
✓ ~/Projects/c-ares/build % cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=ios.toolchain.cmake -DPLATFORM=OS64

I see the following log in console

-- Looking for res_servicename
-- Looking for res_servicename - found
-- HAVE_LIBRESOLV is undefined

CARES_USE_LIBRESOLV is undefined as well

✓ ~/Projects/c-ares/build % cat ares_config.h | grep CARES_USE_LIBRESOLV
/* #undef CARES_USE_LIBRESOLV */

Why does it happen?
To check if we need libresolv we call CARES_FUNCTION_IN_LIBRARY.

CARES_FUNCTION_IN_LIBRARY (res_servicename resolv HAVE_RES_SERVICENAME_IN_LIBRESOLV)
IF (HAVE_RES_SERVICENAME_IN_LIBRESOLV)
	SET (HAVE_LIBRESOLV 1)

let's look closer to the CARES_FUNCTION_IN_LIBRARY macro

MACRO (CARES_FUNCTION_IN_LIBRARY func lib var)
	CHECK_FUNCTION_EXISTS ("${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}")
	IF ("${_CARES_FUNC_IN_LIB_GLOBAL_${func}}")
→               # in case of iOS we come here!# it because libresolv is a system library on iOS I guess. # as a result, nobody defines HAVE_LIBRESOLV
→		SET (${var} FALSE)
	ELSE ()
		CHECK_LIBRARY_EXISTS ("${lib}" "${func}" "" ${var})
	ENDIF ()
ENDMACRO ()

PS: there is a piece of magic that I can't explain. The library without libresolv does work on iOS Simulator. But it doesn't on iOS devices

@bradh352
Copy link
Member

My guess is something on your system is causing CMAKE_REQUIRED_LIBRARIES to include libresolv already. I haven't looked at that toolchain to see what it does, but I've never used it. In theory libresolv should NOT be in CMAKE_REQUIRED_LIBRARIES ... I'm attempting to add the build to cirrus-ci autobuilds to see what it does there, but I'm not using that toolchain file.

@bradh352
Copy link
Member

bradh352 commented Dec 20, 2021

https://cirrus-ci.com/task/5130141339746304

-- Looking for res_servicename
-- Looking for res_servicename - not found
-- Looking for res_servicename in resolv
-- Looking for res_servicename in resolv - found
-- Performing Test IOS
-- Performing Test IOS - Success
-- Performing Test IOS_V10
-- Performing Test IOS_V10 - Success
-- Performing Test MACOS_V1012
-- Performing Test MACOS_V1012 - Failed

This is different behavior than what you described. Looks proper to me.

@Zliu404
Copy link

Zliu404 commented Nov 3, 2023

1、set ENABLE_STRICT_TRY_COMPILE_INT=ON for leetal‘s ios.toolchain.cmake to make sure CMAKE_TRY_COMPILE_TARGET_TYPE is not changed to STATIC_LIBRARY.
2、use newer cmake version (eg. 3.22.1) to disable xcode code signing when try_coplile called by CHECK_xxx_EXISTS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants