Search code examples
c++openssllinker-errorsrestbed

Why are loads of symbols missing from OpenSSL libs, such as BIO_ctrl?


I'm mystified by why a large subset of symbols is apparently missing from OpenSSL libs I built on Mac.

In a CMake-based project, I'm compiling a lib (Restbed) that links statically with OpenSSL (both libssl and libcrypto). The Restbed lib appears to build fine, but if I try to link an application with it, it fails with lots of errors like:

Undefined symbols for architecture arm64:
"_BIO_ctrl", referenced from:
       asio::ssl::detail::engine::map_error_code(std::__1::error_code&) const
in librestbed.a(service_impl.cpp.o)
       asio::ssl::detail::engine::map_error_code(std::__1::error_code&) const
in librestbed.a(socket_impl.cpp.o)
"_BIO_ctrl_pending", referenced from:
       asio::ssl::detail::engine::perform(int (asio::ssl::detail::engine::*)(void*, unsigned long), void*, unsigned long, std::__1::error_code&, unsigned long*) in
librestbed.a(service_impl.cpp.o)

The architecture isn't the problem; everything is built on M1 Mac.

To sum up, step 1 was build the static Restbed lib:

  librestbed.a
    libssl.a
    libcrypto.a

All the output from that is here.

Then I tried to compile an app, linking statically with Restbed:

app
  librestbed.a

Here's the build command for the app, which triggers the errors:

/usr/bin/clang++ -g -arch arm64 -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/Series2Server.dir/main.cpp.o -o Series2Server -L/Users/me/data/series2server/restbed/library  -Wl,-rpath,/Users/me/data/series2server/restbed/library -lrestbed -pthread

libssl and libcrypto are built from source using the configure tool provided in the OpenSSL source tree.

So I examined both libssl and libcrypto with nm -u, to see if the complained-about symbols were in there. Well, they aren't. Such symbols as BIO_ctrl are listed as undefined in both libssl and libcrypto.

I don't know what this means. How are symbols known about by nm, and yet "undefined" in the file under inspection? More importantly, how do I fix this problem so the application will build?


Solution

  • When you build a static lib, it does not involving linking at all -- you just run a tool (ar or libtool or some such) that collects the compiled object files into a static library and does not link any of them.

    This means that when you link with a static library, you also need to link with any other libraries (static or dynamic) that it depends on.