Xcode 11的ld错误:“您的二进制文件不是/usr/lib/libcrypto.dylib的允许客户端”。

14

我的项目使用CMake进行构建,但在Mac上构建时会使用本地macOS版本的clang和ld。

在升级到macOS 10.15 Catalina的Xcode 11后,我无法链接,出现以下错误:ld: cannot link directly with dylib/framework, your binary is not an allowed client of /usr/lib/libcrypto.dylib for architecture x86_64

这是否与新的应用程序验签有关?是否有一种修复方法,不需要将项目放在 Xcode 中(我在 macOS 上使用 CLion 进行开发)或不需要链接自己构建的 OpenSSL?

非常感谢任何帮助。


看起来 Twitter 上的提及表明这是“正常的”。基本上,包含的版本已经过时,所以现在他们只是防止你链接到它。有人可以半官方地确认或否认吗?https://twitter.com/steipete/status/1168926846962020352 - Didier Malenfant
今天早上我遇到了这个问题,经过一番搜索,我发现了这篇苹果论坛的帖子,其中提到苹果公司打算仅在内部使用这些类型的库。建议是自己构建第三方库并将其包含在应用程序中。https://forums.developer.apple.com/thread/124782 - Casey
1
@casey 我认为那是正确的答案,就像我在发现推特帖子时怀疑的那样。你想把这个作为答案发布,我会批准它吗? - Didier Malenfant
对于CMake,在Mac OSX上选择外部OpenSSL(比如通过VSCode),我们需要在TARGET_LINK_LIBRARIES段中同时包含OpenSSL::SSL和OpenSSL::Crypto。仅列出OpenSSL:SSL会从VSCode构建中选择ssl部分,但会再次尝试使用系统提供的libcrypto.dylib。 - Neelabh Mam
4个回答

13

由于FindOpenSSL.cmake代码查找库,然后将结果存储在CMake缓存中,因此您可以在尝试查找 OpenSSL 之前强制设置路径。 FindOpenSSL.cmake代码不会替换您的路径。

if (APPLE)
    # This is a bug in CMake that causes it to prefer the system version over
    # the one in the specified ROOT folder.
    set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} /usr/local/Cellar/openssl@1.1/1.1.1g/)
    set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_ROOT_DIR}/lib/libcrypto.dylib CACHE FILEPATH "" FORCE)
    set(OPENSSL_SSL_LIBRARY ${OPENSSL_ROOT_DIR}/lib/libssl.dylib CACHE FILEPATH "" FORCE)
endif()
find_package(OpenSSL REQUIRED)

请确保清除CMake缓存,因为一旦库被找到使用了错误的路径,即使您在项目上重新运行CMake,此方法也无法修复它。


5
我已经使用brew安装了OpenSSL,find_package似乎检测到了brew版本,但它试图链接系统中安装的LibreSSL,我尝试强制find_package设置库的确切路径,但它没有任何作用:
if(APPLE)
    set(OPENSSL_ROOT_DIR /usr/local/Cellar/openssl@1.1/1.1.1d/)
endif()

所以我最终手动设置了依赖项,虽然不太理想,但在开发期间可以使用。

# OpenSSL
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
    if(APPLE)
        include_directories(/usr/local/Cellar/openssl@1.1/1.1.1d/include)
        list(APPEND LIB_LIST /usr/local/Cellar/openssl@1.1/1.1.1d/lib/libssl.dylib)
        list(APPEND LIB_LIST /usr/local/Cellar/openssl@1.1/1.1.1d/lib/libcrypto.dylib)
        message(STATUS "OpenSSL Version: ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIR} ${OPENSSL_LIBRARIES}")
    else()
        include_directories(${OPENSSL_INCLUDE_DIR})
        list(APPEND LIB_LIST ${OPENSSL_LIBRARIES})
        message(STATUS "OpenSSL Version: ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIR} ${OPENSSL_LIBRARIES}")
    endif()
endif()

Cmake输出了这个信息,它检测到了来自brew的OpenSSL库,但链接却使用系统库。不知道为什么。
-- OpenSSL Version: 1.1.1d /usr/local/Cellar/openssl@1.1/1.1.1d/include /usr/lib/libssl.dylib;/usr/lib/libcrypto.dylib

希望这能帮到您!

1
嗨,我不知道需要编辑哪个文件来进行这些更改。非常感谢! - mikejw

1
今早我遇到了这个问题,经过调查,我发现这 苹果论坛消息 表明苹果打算仅在内部使用这些类型的库。建议是自己构建第三方库并将其与应用程序一起包含。

0
我以前遇到过这个问题。 解决方案: 进入构建文件夹:
$ rm -rf *
$ cmake -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl@1.1" ..
$ cmake -DOPENSSL_LIBRARIES="/usr/local/opt/openssl@1.1/lib" ..
$ make

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接