1

I am trying to build a program with g++, but i'm getting "undefined references".

The folder structure:

Makefile
libs/
  libcrypotpp.a
  libz.a
sources/
  here are the sources and headers
out/
objfiles/

The Makefile looks like the following:

#makefile for program
#needs libz.a and libcryptopp.a

CC = g++
SOURCES = sources/*.cpp
LIBS = -lcryptopp -lz -pthread
LIBPATH = libs/
OBJPATH = objfiles/
OUTPUT = out/
OBJS = *.o
HEADERPATHS = -Isources -Isources/cryptopp

all:
    echo "Program"
    echo "------------------"
ifneq ("$(wildcard libs/libz.a)", "")
    echo "ZLIB found!"
ifneq ("$(wildcard libs/libcryptopp.a)", "")
    echo "Cryptopp found!"  #all librarys found
    $(CC) $(HEADERPATHS) -L$(LIBPATH) $(LIBS) $(SOURCES)
    mv *.o $(OBJPATH)
else
    echo "error: Cryptopp(libs/libcryptopp.a) was not found!"
endif
else ifneq ("$(wildcard libs/libcryptopp.a)", "")
    echo "Cryptopp found!"
    echo "error: ZLIB(libs/libz.a) was not found!"
else
    echo "error: ZLIB(libs/libz.a) was not found!"
    echo "error: Cryptopp(libs/libcryptopp.a) was not found!"
endif

.SILENT: all

g++ compiles, but then outputs the undefinded references:

undefined references

Why does it fail?

luk-ry
  • 53
  • 5
  • 4
    Aren't you supposed to put the libs after the sources `$(CC) $(HEADERPATHS) $(SOURCES) -L$(LIBPATH) $(LIBS)`. – john Nov 23 '12 at 11:41
  • See http://stackoverflow.com/questions/9966959/noobish-linker-errors-when-compiling-against-glib/9966989#9966989 – hmjd Nov 23 '12 at 11:53
  • Your Makefile is pretty confusing. Remove all the `if`s and reduce it to just `$(CC) ...`. This would make it clearer and easier to read. The linker will already complain and tell you, if it can't find any libraries. – Olaf Dietsche Nov 23 '12 at 11:57

1 Answers1

2

As (static) libraries can contain a lot of code that remains unused in most applications that link to them, linkers tend to be very conservative about what parts of a static library they will link into the application.

In some cases, this makes our lives as a developer more difficult, as you have to follow unwritten rules to get everything to play nicely. Some of those unwritten rules are

  • that the linker processes its inputs in the order they are given on the command line
  • that the linker only considers libraries in the first pass over the inputs These two combined have the effect that libraries can only resolve unresolved symbols that were found in earlier inputs to the linker.

The result is that, to keep the linker happy, libraries should be specified last and if library A depends on library B, A should be specified before B.

Bart van Ingen Schenau
  • 15,488
  • 4
  • 32
  • 41