26

I have built OpenSSL from source (an intentionally old version; built with ./config && make && make test) and would prefer to use what I have built without doing make install to link against my program.

The command that's failing is:

gcc -Wall -Wextra -Werror -static -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto 
-Iopenssl/openssl-0.9.8k/include -o myApp source1.o source2.o common.o`

And I receive a series of errors similar to:

common.c:(.text+0x1ea): undefined reference to `SSL_write'

This makes me think there's something funky with my OpenSSL. If I omit -Lopenssl/openssl-0.9.8k/ from my command, the error changes to being unable to:

/usr/bin/ld: cannot find -lssl
/usr/bin/ld: cannot find -lcrypto

Am I compiling OpenSSL incorrectly? Or how should I best resolve this?

jww
  • 97,681
  • 90
  • 411
  • 885
mrduclaw
  • 3,965
  • 4
  • 36
  • 37

4 Answers4

38

Silly "Linux-isms" strike again! Apparently, I need to change my command such that the -L and -l stuff is at the end like (despite what man gcc seems to indicate):

gcc -Wall -Wextra -Werror -static -o myApp source1.o source2.o common.o -Lopenssl/openssl-0.9.8k/ -lssl -lcrypto -Iopenssl/openssl-0.9.8k/include

iammilind
  • 68,093
  • 33
  • 169
  • 336
mrduclaw
  • 3,965
  • 4
  • 36
  • 37
  • 22
    It's the `-lssl -lcrypto` that need to be at the end. When a library is scanned by the linker, only the functions for which there are already undefined references are linked. So you need to put the "consuming" objects at the start of the link line, and the "supplying" objects at the end. – caf Dec 06 '10 at 01:35
  • 2
    I'm always weird about accepting my own answers. I'll switch it now though. – mrduclaw Mar 29 '14 at 15:10
  • How does it differ for clan llvm? – saruftw Jun 13 '17 at 19:05
6

Why don't you want to use make install? It can copy generated binaries in the directory you want if you previously passed it to ./configure --prefix $HOME/target_library_install_directory

If you used this trick with every library you build and install, you could then add the target directory to the LIBRARY_PATH environment variable and avoid using -L option.

jopasserat
  • 5,721
  • 4
  • 31
  • 50
  • This is good to know, but I'm not sure it's easier than just moving around where I put my `-L`. Up-voted, nonetheless. – mrduclaw Dec 04 '10 at 16:09
  • I'm going to go ahead and accept this as the answer as it's likely the right way to do it. In my particular case, I didn't want everyone that checked out my code (and the modified OpenSSL code) to have to do anything but `make`. – mrduclaw Dec 05 '10 at 03:09
3

If you use Autotools, or you are building an Autools project like cURL, then you should be able to use pkg-config. The idea is the Autotools package will read OpenSSL's package configuration and things will "just work" for you.

The OpenSSL package configuration library name is openssl.

You would use it like so in a makefile based project.

%.o: %.c
        $(CC) -o $@ -c `pkg-config --cflags openssl` $^

target: foo.o bar.o baz.o
        $(CC) -o $@ `pkg-config --libs openssl` $^

Also see How to use pkg-config in Make and How to use pkg-config to link a library statically.

jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    thanks for this answer about `pkg-config`. Can you explain like i'm five, what the `pkg-config` is and how exactly it works? how its achieved that it auto-magically just find all links to include dirs etc. Of course I could use it like magic but its great to know how it works internally – barney Dec 28 '17 at 14:30
0

Another approach is to use pkg-config to preserve compatibility. This is an example of makefile when needs to link OpenSSL.

CC = gcc
CFLAGS = \
    -I. \
    -D_GNU_SOURCE=1

LDFLAGS = `pkg-config --libs inih`
LDFLAGS += `pkg-config --libs libcurl`
LDFLAGS += `pkg-config --libs liburiparser`
LDFLAGS += `pkg-config --libs openssl`


# Executable
foo: foo.o
    $(CC) -o $@ $^ $(LDFLAGS)


foo.o: foo.c 
    $(CC) -c $(CFLAGS) $< -o $@ 

pylover
  • 7,670
  • 8
  • 51
  • 73