0

I build a static library. The problem is that I can't link it from my Makefile

TARGET  =       AR1020
CC      =       gcc
CFLAGS  =       -Wall -std=c99 -I./inc/
LINKER  =       gcc -o
LFLAGS  =       -Wall -static -I./inc/


SRCDIR  =       src
INCDIR  =       inc
OBJDIR  =       obj
BINDIR  =       bin

LIBDIR  =       ./lib
LIBFLAG =       -li2c


SOURCES         :=      $(wildcard $(SRCDIR)/*.c)
INCLUDES        :=      $(wildcard $(INCDIR)/*.h)
OBJECTS         :=      $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm              =       rm -f

$(BINDIR)/$(TARGET): $(OBJECTS)
        @$(LINKER) $@ $(LFLAGS) -L$(LIBDIR) $(LIBFLAG) $(OBJECTS)
        @echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
        @$(CC) $(CFLAGS) -c $< -o $@
        @echo "Compiled "$<" successfully"

.PHONY: clean
clean:
        @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONY: remove
remove: clean
        @$(rm) $(BINDIR)/$(TARGET)
        @echo "Exacutable removed!"

My tree is:

|-- bin
|-- inc
|   |-- color.h
|   |-- EXT.h
|   |-- EXT.h~
|   |-- gpio_lib.h
|   `-- test.h
|-- lib
|   |-- i2c.c
|   |-- i2c.o
|   `-- libi2c.a
|-- Makefile
|-- obj
|   |-- AR1020.o
|   |-- gpio_lib.o
|   |-- gpio.o
|   `-- test.o
`-- src
    |-- AR1020.c
    |-- gpio_lib.c
    `-- libi2c.a

I want to link libi2c.a but I'm getting the error "undefined reference to '.....'. If I compile it manually like:

gcc src/AR1020.c lib/libi2c.a

Everything compiles as it should be. Can someone help me?

2 Answers 2

9

Libraries you want to link in needs to come after the object files that uses anything in those libraries, so

@$(LINKER) $@ $(LFLAGS) -L$(LIBDIR) $(LIBFLAG) $(OBJECTS)

should be

@$(LINKER) $@ $(LFLAGS) -L$(LIBDIR)  $(OBJECTS) $(LIBFLAG)
Sign up to request clarification or add additional context in comments.

Comments

0

I've found a useful article about linking libraries. http://docencia.ac.upc.edu/FIB/USO/Bibliografia/unix-c-libraries.html

The linker checks each file in turn. If it is an object file, it is being placed fully into the executable file. If it is a library, the linker checks to see if any symbols referenced (i.e. used) in the previous object files but not defined (i.e. contained) in them, are in the library. If such a symbol is found, the whole object file from the library that contains the symbol - is being added to the executable file. This process continues until all object files and libraries on the command line were processed.

Note that object files found on the command line are always fully included in the executable file, so the order of mentioning them does not really matter. Thus, a good rule is to always mention the libraries after all object files

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.