boost :: asio :: ssl :: context :: context(boost :: asio :: ssl :: context_base :: method)未定义符号 [英] boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) undefined Symbols

查看:703
本文介绍了boost :: asio :: ssl :: context :: context(boost :: asio :: ssl :: context_base :: method)未定义符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行带有clang-700.0.72的OSX Yosemite 10.10.5和一个安装了brew的boost 1.56.

I am running OSX Yosemite 10.10.5 with clang-700.0.72 and a brew installed boost 1.56.

我正在将boost :: asio用于非ssl和tls套接字. 令人反感的行在我的项目中,但似乎源自boost 1.56本身.

I am using boost::asio for non-ssl and tls sockets. The offending lines are not in my project, but appear to originate from boost 1.56 itself.

我使用cmake,并使用find_package(OpenSSL REQUIRED)与openssl链接,并且确实具有openssl 1.0.2g.

I use cmake, and I do link with openssl, using find_package(OpenSSL REQUIRED) and I do have openssl 1.0.2g.

该项目使用C ++ 11,并且令人反感的行似乎是:

The project uses C++11, and the offending lines appear to be:

Undefined symbols for architecture x86_64: "_SSLv2_client_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o "_SSLv2_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o "_SSLv2_server_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o ld: symbol(s) not found for architecture x86_64

Undefined symbols for architecture x86_64: "_SSLv2_client_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o "_SSLv2_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o "_SSLv2_server_method", referenced from: boost::asio::ssl::context::context(boost::asio::ssl::context_base::method) in asio_tls.cpp.o ld: symbol(s) not found for architecture x86_64

我根本不使用 SSLv2,实际上,该代码专注于仅使用TLS v2:

I do NOT use SSLv2 at all, in fact the code focuses on using only TLS v2:

class asio_socket_https
{
public:
    asio_socket_https(const std::string token)
    : ctx_(boost::asio::ssl::context::tlsv12_client), token_(token)
    {}

稍后,当我初始化套接字和上下文时,我会这样做:

Later on, when intialising the socket and context, I do:

ctx_.set_options(boost::asio::ssl::context::default_workarounds
                |boost::asio::ssl::context::no_sslv2
                |boost::asio::ssl::context::no_sslv3
                |boost::asio::ssl::context::no_tlsv1
                |boost::asio::ssl::context::single_dh_use);

我没有编译错误,该应用程序是针对libssl/libcrypto链接的,并且我还没有在Linux(仅OSX)上对其进行过测试.

I have no compilation errors, the application is linked against libssl/libcrypto, and I have not tested it under Linux (only OSX).

我看到了一个具有相同主题但没有答案的SO问题此处.

I've seen an SO question with the same topic but no answer here.

实际链接标志:

/usr/bin/g++ -std=c++11 -Wall -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/asio_tls.dir/examples/asio_tls.cpp.o -o asio_tls librapp.0.2.dylib /usr/local/lib/libboost_system-mt.dylib /usr/local/lib/libboost_thread-mt.dylib /usr/local/lib/libboost_random-mt.dylib /usr/local/lib/libboost_unit_test_framework-mt.dylib /usr/local/lib/libboost_program_options-mt.dylib /usr/local/Cellar/openssl/1.0.2g/lib/libssl.dylib /usr/local/Cellar/openssl/1.0.2g/lib/libcrypto.dylib

/usr/bin/g++ -std=c++11 -Wall -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/asio_tls.dir/examples/asio_tls.cpp.o -o asio_tls librapp.0.2.dylib /usr/local/lib/libboost_system-mt.dylib /usr/local/lib/libboost_thread-mt.dylib /usr/local/lib/libboost_random-mt.dylib /usr/local/lib/libboost_unit_test_framework-mt.dylib /usr/local/lib/libboost_program_options-mt.dylib /usr/local/Cellar/openssl/1.0.2g/lib/libssl.dylib /usr/local/Cellar/openssl/1.0.2g/lib/libcrypto.dylib

我今天在Ubuntu 14.04下测试了相同的代码,并且在检测openssl 1.0.1f时它运行良好(没有任何问题). 这似乎开始是OSX特有的问题.

I tested the same code today under Ubuntu 14.04 and it built fine (with no issues at all) when detecting openssl 1.0.1f. This is starting to seem like an OSX-specific issue.

@rhashimoto似乎是正确的,而链接器在/usr/local/Cellar/openssl/中使用的是opensl的​​Cellar版本,所使用的标头在/usr/local/openssl下,我认为与brew管理的标题不同.

@rhashimoto appears to be right, whereas the linker is using the Cellar version of openssl in /usr/local/Cellar/openssl/ the headers used are under /usr/local/openssl which I don't think is the same managed by brew.

问题出在我的CMakeLists.txt中,我以为find_package(OpenSSL REQUIRED)就足够了,不幸的是,这样做是破坏了与导入的库头链接的库链接的版本.

The problem was in my CMakeLists.txt I had assumed that find_package(OpenSSL REQUIRED) would be enough, unfortunatelly what this did was break the version of library linking with the library headers imported.

默认库是OSX的openssl,而我却明确地链接了${OPENSSL_LIBRARIES}.

The default library was OSX's openssl, whereas I was linking explicitly with ${OPENSSL_LIBRARIES}.

只需添加以下内容即可解决此问题(现在它使用从 brew 安装的openssl):

Simply adding the following fixed the issue (now it uses openssl installed from brew):

find_package(OpenSSL REQUIRED)
if (OPENSSL_FOUND)
    include_directories(${OPENSSL_INCLUDE_DIR})
endif()

然后执行target_link_libraries(... ${OPENSSL_LIBRARIES})

推荐答案

Boost Asio确实在

Boost Asio does use SSLv2_client_method() and SSLv2_server_method() in boost/asio/ssl/impl/context.ipp, conditional on the absence of the preprocessor symbol OPENSSL_NO_SSL2:

#if defined(OPENSSL_NO_SSL2)
  case context::sslv2:
  case context::sslv2_client:
  case context::sslv2_server:
    boost::asio::detail::throw_error(
        boost::asio::error::invalid_argument, "context");
    break;
#else // defined(OPENSSL_NO_SSL2)
  case context::sslv2:
    handle_ = ::SSL_CTX_new(::SSLv2_method());
    break;
  case context::sslv2_client:
    handle_ = ::SSL_CTX_new(::SSLv2_client_method());
    break;
  case context::sslv2_server:
    handle_ = ::SSL_CTX_new(::SSLv2_server_method());
    break;
#endif // defined(OPENSSL_NO_SSL2)

如果

OPENSSL_NO_SSL2不包含对SSLv2的支持,则应在您的OpenSSL库头中定义

OPENSSL_NO_SSL2,但是显然您的构建没有选择它.

OPENSSL_NO_SSL2 should be defined in your OpenSSL library headers if it does not include support for SSLv2, but apparently your build is not picking it up.

对此行为的一种常见解释是,您使用仍支持SSLv2的一个OpenSSL库中的标头进行编译,并使用不支持SSLv2的另一个OpenSSL库中的二进制文件进行链接.将-H标志插入编译器选项可能会有所帮助,该选项将在处理标头路径时记录这些标头路径,从而可以验证正在使用的标头.

One common explanation for this kind of behavior is that you are compiling with headers from one OpenSSL library that still supports SSLv2 and linking with binaries from another OpenSSL library that does not support SSLv2. It may be helpful to insert the -H flag into your compiler options, which will log the headers paths as they are processed, as you can then verify which headers are being used.

这篇关于boost :: asio :: ssl :: context :: context(boost :: asio :: ssl :: context_base :: method)未定义符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆