diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dafe03..eae4ce1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -478,10 +478,32 @@ if(APPLE) ) endif() if(USE_LIBIDN2 AND NOT WIN32) - # The prebuild makes libidn2 self-contained with its included libunistring. + # The prebuild makes libidn2 self-contained with its included libunistring, + # except for iconv: libunistring's striconveh.c calls the plain POSIX + # iconv()/iconv_open()/iconv_close() symbols, which are not part of + # a static archive's own link requirements, so they must be supplied again + # here when libidn2.a gets linked into curl. On Apple platforms iconv is + # not part of libSystem's implicit re-exports (unlike on glibc) and always + # needs to be linked explicitly; pinning the absolute path to Apple's + # /usr/lib/libiconv.dylib (rather than a bare -liconv) guarantees this + # resolves to the system copy even when a package manager's own libiconv + # is reachable on the linker search path. + # + # LIBIDN2_LIBRARY must carry both paths as one CMake list value (curl's + # FindLibidn2.cmake forwards it verbatim into an INTERFACE_LINK_LIBRARIES + # property). This ExternalProject_Add(curl ...) call's CONFIGURE_COMMAND + # is a plain command list, so a literal ";" here would already be split + # into separate command-line words by CMake's own configure-time list + # handling before it ever reaches the nested cmake invocation - use the + # same LIST_SEPARATOR token ("|", declared below) already used for + # CMAKE_IGNORE_PREFIX_PATH/CMAKE_IGNORE_PATH above for the same reason. + set(_libidn2_link_libs "${DEPS_INSTALL_DIR}/lib/libidn2.a") + if(APPLE) + string(APPEND _libidn2_link_libs "|@ICONV_PREFIX@/lib/libiconv.dylib") + endif() list(APPEND _curl_staged_dependency_args "-DLIBIDN2_INCLUDE_DIR=${DEPS_INSTALL_DIR}/include" - "-DLIBIDN2_LIBRARY=${DEPS_INSTALL_DIR}/lib/libidn2.a" + "-DLIBIDN2_LIBRARY=${_libidn2_link_libs}" ) endif()