I am running OSX Yosemite 10.10.5 with clang-700.0.72 and a brew installed 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.
I use cmake, and I do link with openssl, using find_package(OpenSSL REQUIRED)
and I do have openssl 1.0.2g
.
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
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);
I have no compilation errors, the application is linked against libssl/libcrypto, and I have not tested it under Linux (only OSX).
I've seen an SO question with the same topic but no answer here.
Actual link flags:
/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
EDIT
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 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.
SOLUTION
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.
The default library was OSX's openssl, whereas I was linking explicitly with ${OPENSSL_LIBRARIES}
.
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()
And then do a target_link_libraries(... ${OPENSSL_LIBRARIES})
Boost Asio does use
SSLv2_client_method()
andSSLv2_server_method()
inboost/asio/ssl/impl/context.ipp
, conditional on the absence of the preprocessor symbolOPENSSL_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.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.