.so undefined reference to openssl
By Martin on Regards: C; linux;[…]so: undefined reference to
This blog post is more or less the story of how I encountered some
issues while building an application from source which is using the
openssl libary on an old linux machine. So when I was setting up the
application I ran into the error “ssl libary not available” when using
./configure --prefix=/opt/
[...]
checking for inflateEnd in -lz... yes
checking zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking for inflateEnd in -lz... (cached) yes
checking zlib in /usr/local... ok
checking whether to enable https support... yes
checking for EVP_get_digestbyname in -lcrypto... yes
checking for SSL_CTX_new in -lssl... no
configure: error: not available
From the error message it was clear that configure
was
unable to detect my openssl libary. I knew I had installed the openssl
libary, but to be sure that openssl is functionaly working I checked it
by calling the binary executable.
/usr/local/ssl/bin/openssl
OpenSSL> version
OpenSSL 1.0.2r 26 Feb 2019
OpenSSL> q
Next I needed to set the LDFLAGS enviroment variable to give gcc and the linker a hint where to look for the shared libraries. In this scenario the /usr/local/ssl/ path is important. You can find more about this here
Actual openssl and other shared libaries will display this information when you compile and install the software by yourself. They will print something like that:
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
In addition, I set the LIBS flag too, which apperantly was wrong. Instead of
LDFLAGS="-L/usr/local/ssl/ -L/usr/local/ -L/usr/local/bin/ -Wl,-rpath,/usr/local/ssl/,-rpath,/usr/local/lib/,--export-dynamic" LIBS="-ldl" CC=/opt/gcc-4.6.0/bin/gcc CXX=/opt/gcc-4.6.0/bin/g++ ./configure --prefix=/opt/
I later learnd, that I should have used
LDFLAGS="-L/usr/local/ssl/ -L/usr/local/ -L/usr/local/bin/ -Wl,-rpath,/usr/local/ssl/,-rpath,/usr/local/lib/,--export-dynamic" LIBS="-ldl -lm -lrt -lssl -lcrypto" CC=/opt/gcc-4.6.0/bin/gcc CXX=/opt/gcc-4.6.0/bin/g++ ./configure --prefix=/opt/
instead.
Calling the configure
script with the modified parameter
worked well, as the script was now able to detect that openssl is
installed. The next step was to compile the whole thing with
make
.
So the first sourcefiles could be compiled without any problems, but after a few minutes it stopped with the compiler error:
libtool: link: /opt/gcc-4.6.0/bin/gcc -fvisibility=hidden -g -O2 -Wl,-rpath -Wl,/usr/local/ssl/ -Wl,-rpath -Wl,/usr/local/lib/ -Wl,--export-dynamic -o .libs/httrack httrack.o -L/usr/local/ssl/ -L/usr/local/ -L/usr/local/bin/ -L/usr/local/lib -lpthread ./.libs/libhttrack.so -lz -ldl -Wl,-rpath -Wl,/opt/lib
./.libs/libhttrack.so: undefined reference to `EVP_enc_null'
./.libs/libhttrack.so: undefined reference to `EVP_CIPHER_CTX_init'
./.libs/libhttrack.so: undefined reference to `X509_NAME_dup'
./.libs/libhttrack.so: undefined reference to `COMP_compress_block'
./.libs/libhttrack.so: undefined reference to `EVP_rc2_cbc'
./.libs/libhttrack.so: undefined reference to `X509_STORE_get_by_subject'
./.libs/libhttrack.so: undefined reference to `EVP_VerifyFinal'
./.libs/libhttrack.so: undefined reference to `COMP_CTX_new'
./.libs/libhttrack.so: undefined reference to `X509_STORE_CTX_set_ex_data'
I googled the compiler error message and as it turns out, it is
related to ssl. So I suspected that the required ssl hints for the
compiler didn’t work out (The compiler error was caused by the
incomplete LIBS flag, which I mentioned above). So the first thing I
tried here, was to call the compiler command by hand. I changed the
directory to the src
folder and executed the printed
command from make
and I got the same error message. After
googling I figured out that in addition I need the ssl flags as
well.
/opt/gcc-4.6.0/bin/gcc -fvisibility=hidden -g -O2 -L/usr/local/ssl/ -L/usr/local/ -L/usr/local/bin/ -Wl,-rpath,/usr/local/ssl/,-rpath,/usr/local/lib/,--export-dynamic -L/usr/local/lib -o httrack httrack.o -lpthread libhttrack.la -lz -ldl -lm -lrt -lssl -lcrypto
Tada! it compiled succesfully! I expected that make
will
skip my compiled file, since I already complied it by hand. But
make
overwrote my file and ran into the same issue again
because it didn’t use the proper flags. What you can do about this is to
look for a file named Makefile
and adjust its content so
that the proper command will be generated.
The Makefile
defined some variables and one of it is
named LIBS
with LIBS = -lz -ldl
. So I added
the missing flags with
LIBS = -lz -ldl -lm -lrt -lssl -lcrypto
and ran
make
again. Now the command printed the additonal ssl falgs
and the compliation of the tool was succesful. Just one side node: the
Makefile
can occour in the source tree multiple times, so
you need to be sure to adjust the correct one, where the related source
file is located.
Conclusion: [ ] make sure that the compiler and linker can find the location of the shared libaries which you need for your compilation [ ] add the required flags for the libaries
Useful links:
- https://flameeyes.blog/2010/06/20/the-why-and-how-of-rpath/
- https://thoughtbot.com/blog/the-magic-behind-configure-make-make-install