我正在运行OSX Yosemite 10.10.5和clang-700.0.72以及brew装机提升1.56。boost :: asio :: ssl :: context :: context(boost :: asio :: ssl :: context_base :: method)undefined符号
我使用boost :: asio for non-ssl和tls套接字。 在我的项目中,违规行是而不是,但似乎起源于boost 1.56本身。
我用cmake,而且我用openssl连接,使用find_package(OpenSSL REQUIRED)
,我确实有openssl 1.0.2g
。
该项目采用C++ 11,和有问题的线条似乎是:
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:
class asio_socket_https
{
public:
asio_socket_https(const std::string token)
: ctx_(boost::asio::ssl::context::tlsv12_client), token_(token)
{}
后来,intialising插座和上下文的时候,我做的:
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)下测试它。
我看过同一个主题的SO问题,但没有回答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
编辑
我今天测试相同的代码的Ubuntu 14.04之下,检测的OpenSSL 1.0.1f当它建立了良好的(与完全没有问题)。 这开始看起来像一个OSX特定的问题。
@rhashimoto看起来是正确的,而链接器正在使用/usr/local/Cellar/openssl/
中的openssl的Cellar版本,所使用的头文件在/usr/local/openssl
之下,我不认为它是由brew管理的。
SOLUTION
的问题是在我的CMakeLists.txt
我曾以为,find_package(OpenSSL REQUIRED)
就足够了,可惜的是这是什么做的是打破库的进口库头连接的版本。
默认库是OSX的openssl,而我明确链接到${OPENSSL_LIBRARIES}
。
只需添加以下固定的问题(现在它使用从冲泡安装了OpenSSL):
find_package(OpenSSL REQUIRED)
if (OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
然后做一个target_link_libraries(... ${OPENSSL_LIBRARIES})
检查链接参数的顺序(库去_after_自己的对象) – sehe
@sehe谢谢,顺序是正确的,我已经添加了链接标志(cmake详细)的编辑。看来我错过了特定的openssl函数 - 因为openssl的其余部分链接正确。我认为这是本地化的OSX,但我没有访问Linux的ATM。 –
我将验证您正在编译的OpenSSL头文件是否与您要链接的OpenSSL库文件头文件相对应。你可以尝试在你的编译器选项中注入一个'-H'标志来查找。 – rhashimoto