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?
CodePudding user response:
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.