24

When i am trying to compile a C code which uses openssl 'crypto' library functions with comand line -lcrypto with gcc 4.4.3 it gives an error

`@ubu:$ gcc -ggdb aes_m.c -Werror -Wall -I /usr/local/ssl/include/ -lcrypto -o aes
 /usr/bin/ld: cannot find -lcrypto
 collect2: ld returned 1 exit status`

what can be the reason for this??

I have already gone through this discussion ld cannot find an existing library but that does not help.

locate command results in

$ locate libcrypto
/home/abhi/Downloads/openssl-1.0.1b/libcrypto.a
/home/abhi/Downloads/openssl-1.0.1b/libcrypto.pc
/lib/libcrypto.so.0.9.8
/lib/i486/libcrypto.so.0.9.8
/lib/i586/libcrypto.so.0.9.8
/lib/i686/cmov/libcrypto.so.0.9.8
/usr/lib/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/local/ssl/lib/libcrypto.a
/usr/local/ssl/lib/pkgconfig/libcrypto.pc

Can someone please help on this or point out any mistake i am doing

@ Daniel Roethlisberger tried using the -L flag but that resulted in these errors

gcc -ggdb aes_m.c -Werror -Wall -I /usr/local/ssl/include/ -L /usr/local/ssl/lib -lcrypto -o aes
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
dso_dlfcn.c:(.text+0x2d): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x43): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x4d): undefined reference to `dlclose'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
dso_dlfcn.c:(.text+0x8f): undefined reference to `dladdr'
dso_dlfcn.c:(.text+0xe9): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
dso_dlfcn.c:(.text+0x4b1): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x590): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
dso_dlfcn.c:(.text+0x611): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x6f0): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
dso_dlfcn.c:(.text+0x755): undefined reference to `dlclose'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
dso_dlfcn.c:(.text+0x837): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x8ae): undefined reference to `dlclose'
dso_dlfcn.c:(.text+0x8f5): undefined reference to `dlerror'
collect2: ld returned 1 exit status

Many thanks

Community
  • 1
  • 1
abhi
  • 3,476
  • 5
  • 41
  • 58
  • 2
    I think you need a symlink without the version number. [This whitepaper](http://www.ibm.com/developerworks/linux/library/l-shlibs/index.html) might help. – jedwards Apr 29 '12 at 00:22
  • @jedwards ok but where actually i should create that symlink ..i mean the folder as this library appears in many location(see above leaving the vmware* and in the Download folder) thanks – abhi Apr 29 '12 at 00:26
  • Bad idea, building against 1.0.1b headers and linking against 0.9.8 shared object, that will lead to problems (if it builds at all). – Daniel Roethlisberger Apr 29 '12 at 00:29
  • 1
    Of course, you should link to (in gcc) the same version you are building against. Unless you're building against a version other than 0.9.8, symlinking `/usr/lib/libcrypto.so` to `/usr/lib/libcrypto.so.0.9.8` would work fine – jedwards Apr 29 '12 at 00:32
  • @DanielRoethlisberger i had previously 0.9.8 version on my ubuntu machine and then i downloaded and installed 1.0.1 , i thought that will take care of the previous version(i mean uninstall that) but it did not..any idea how to clear the 0.9.8 version now from the machine . – abhi Apr 29 '12 at 00:39
  • I suggest you use `apt-get` or Synaptic or whatever is the package manager UI these days on Ubuntu to install the latest openssl-dev package. If you previously installed 0.9.8 from source into `/` and/or `/usr`, just remove all files belonging to it manually (can be tricky, watch out; DON'T do this if you installed OpenSSL using apt-get). – Daniel Roethlisberger Apr 29 '12 at 00:42
  • @DanielRoethlisberger i tried that before installing this way but using apt-get openssl-dev gave error that the package not found – abhi Apr 29 '12 at 00:43
  • libcrypto is part of `libssl-dev` on Ubuntu, apparently. Try `apt-get install libssl-dev` – Daniel Roethlisberger Apr 29 '12 at 00:45
  • 1
    You need to add `-ldl` when performing the final link. – jww Apr 15 '16 at 21:28

2 Answers2

33

Add -L /usr/local/ssl/lib/ into the GCC command line, before the -lcrypto. Since you are building against the OpenSSL headers under /usr/local/ssl, you also need to link against the actual library under the same prefix (even though you only appear to have a static one installed there, that may or may not be your intention; you may need to properly reinstall your OpenSSL built from source).

(edit) To fix the dlopen() and friends not being found by the linker, add -ldl into the GCC command line. -ldl tells the linker to also link against libdl.so, which is the shared library containing dlopen(), dlsym(), dlclose() etc.; these functions are used by OpenSSL internally and thus, -ldl is an indirect dependency when using -lcrypto (on Linux). Because you are linking to a static version of libcrypto, you need to explicitly link against all indirect dependencies.

If you are not familiar with linking to the proper libraries, I'd suggest you use OpenSSL as installed from your Operating System package manager; it might save you some trouble.

Daniel Roethlisberger
  • 6,958
  • 2
  • 41
  • 59
  • see my edit on the original question post for the errors i got after using -L flag ..am i doing something wrong ..thanks for the answer – abhi Apr 29 '12 at 00:36
  • 1
    -ldl solved the problem with -L /path/ flag ..Can you please explain what -ldl does actually.many thanks for again answering one of my questions.. – abhi Apr 29 '12 at 00:53
  • @abhi -ldl instructs the linker to link dl library to your output. In this particular case it tells the linker to add it "by name", not "by path" as -L command-line parameter does – Alexey Vesnin Nov 07 '15 at 22:36
11

This might be relevant for people who tried to build their own openssl from source and then use it to compile other programs (in my case Git)

During configuration of openssl, add 'shared' option:

./config shared

This will create the required shared library libcrypto.so. You'll find more in the INSTALL file.

Also, if you run into this error during 'make'

"....can not be used when making a shared object

recompile with -fPIC

./config shared -fPIC

Daniel Hollas
  • 111
  • 1
  • 5
  • Comment for other lunatics, who had to compile git prerequisities such as libiconv from source into non-standard location. In that case, you need to modify CFLAGS and LDFLAGS in git Makefile. Add '-liconv -lcurl' to CFLAGS and LDFLAGS= -L_your_path_to_lib – Daniel Hollas May 28 '14 at 06:31
  • This solution works for those trying to compile tomcat native library (this comment is for the search engine mostly) – Gustavo Ulises Arias Méndez Mar 14 '16 at 17:07