get-the-solution

.so undefined reference to openssl

By
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: