1

I have a program that I am writing and that needs to calculate some hashes. I need SHA, MD, HMAC algorithms. That is why I chose openssl as solution.

My code is the following:

#include <openssl/md4.h>

void calc();

void calc(unsigned char* data, unsigned long len) {
  unsigned char* h = new unsigned char[128];
  MD4(data, len, h);
}

Compiler returns me the following:

myfile.cpp:(.text+0x3e): undefined reference to `MD4' collect2: ld returned 1 exit status

I compile simply using:

g++ myfile.cpp -o myapp.o

under Linux Fedora.

I downloaded openssl libraries from here and compiled them cby using ./configure and then make install in the downloaded untarpalled directory. I also copied in /usr/local/include directory the include directory in the one I downloaded so that headers can be found by compiler because /usr/local/include is in my $PATH env var.

However the problem is that the linker cannot find the function. I understand that the reason might be two:

  • The compiler can find headers but cannot find implementations.
  • There are problems because openssl is written in C not in C++.

How should I proceeed? Thankyou

Edit1

I actually changed something in my openssl installation.

I installed openssl again and I could see that it places everything under /usr/local/ssl where I can find /usr/local/ssl/include and /usr/local/ssl/lib directories. I change my compilation string in:

g++ -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto

In the directories that I mentioned before I can find, respectively, /usr/local/ssl/include/openssl directory with all headers there and /usr/local/ssl/lib/libssl.a and /usr/local/ssl/lib/libcrypto.a libraries.

Before I did this change when I used the old compilation command, the compiler was telling me: Cannot find -lssl. With these changes, now it can find libs and headers, but ld always fails in the same way:

myfile.cpp:(.text+0x3e): undefined reference to `MD4' collect2: ld returned 1 exit status

A little disappointed. What do you think?

Andry
  • 16,172
  • 27
  • 138
  • 246
  • You probably need to specify the name of the library in your compile command: `g++ myfile.cpp openssl-something -o myapp.o`, perhaps even include the path to the library. – Alexey Frunze Oct 13 '12 at 14:23

2 Answers2

2

Linking against openssl usually requires -lssl.

g++ -o myapp myfile.cpp -lssl 

By the way, it sounds like you may have done the installation a little incorrectly.

You shouldn't have to copy header files anywhere. And you may not have copied the shared libraries anyway.

The compilation should go something like this:

./configure --prefix=/usr/local/openssl
make
make install

And then you compile your program like:

g++ -c -o myapp1.o myfile1.cpp -I/usr/local/openssl/include
g++ -c -o myapp2.o myfile2.cpp -I/usr/local/openssl/include
g++ -o myapp myapp1.o myapp2.o -I/usr/local/openssl/include -L/usr/local/openssl/lib -lssl -lcrypto
Geoff Montee
  • 2,587
  • 13
  • 14
  • I do what you told me, after fixing the installation ad providing correct L and I options and l options adding crypto as well, it can find those headers and implementations because the compiler tells me no more that it cannot find `lssl`, but the same problem persists... – Andry Oct 13 '12 at 18:51
  • Hmm. Interesting. That is very strange. What happens if you run `/usr/local/ssl/bin/openssl version` on the command line? – Geoff Montee Oct 13 '12 at 19:00
  • It tells me `OpenSSL 1.0.1c 10 May 2012` – Andry Oct 13 '12 at 19:03
  • It corresponds to the version I installed from the link I posted in the question. – Andry Oct 13 '12 at 19:03
  • And if you do `/usr/local/ssl/bin/openssl list-message-digest-commands` it shows `md4`? – Geoff Montee Oct 13 '12 at 19:04
  • Is it something related to C functions that the linker cannot link because of differences between C and C++? You know those errors related to `extern "C"` stuff... but I do not know what to think about this... – Andry Oct 13 '12 at 19:04
  • 1
    You only have the static libraries installed. When linking statically, order of the libraries makes a huge difference. Try... `g++ myapp.o -o myapp -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto` – Geoff Montee Oct 13 '12 at 19:14
  • So make sure the `crypto` and `ssl` libraries are listed after your own object files. – Geoff Montee Oct 13 '12 at 19:14
  • Compile `.cpp` files first with the `-c` flag. I updated the example in my answer. Does that work for you? – Geoff Montee Oct 13 '12 at 19:28
  • Sorry Geoff, I did not mention it, but I have more files to compile... it tells me I cannot compile with -c option multiple files... – Andry Oct 13 '12 at 19:48
  • Yes. You have to compile each `.cpp` file individually with `-c`. – Geoff Montee Oct 13 '12 at 19:48
  • Updated the example to give you an idea of what I mean. – Geoff Montee Oct 13 '12 at 19:49
  • It compiled successfully... please could you explain what exactly you did please? Why is it working now? Which was the problem here? Thankyou btw... – Andry Oct 13 '12 at 19:57
  • 1
    When you are using static libraries, the GNU linker has to have them in order of their dependency, if lib A requires lib B, then it needs to see them as `-lA -lB`. Since your `myapp.o` required `-lssl -lcrypt`, it needed to see `myapp.o -lssl -lcrypt`. – Geoff Montee Oct 13 '12 at 20:00
  • I see Geoff, thak you very much for spending your time on my problem. Before I forgot to check your answer as correct, sorry for being late. Thanks again :) – Andry Oct 13 '12 at 20:03
1

The error is caused because you do not link the program to the openssl library during compilation.

Fix it with

g++ myfile.cpp -o myapp.o -lssl

See OpenSSL link options -lssl and -lcrypto in GCC

for how to link a program to openssl.

Community
  • 1
  • 1
Philipp
  • 535
  • 1
  • 6
  • 16