selfbg
selfbg

Reputation: 315

Cannot link static library from Makefile

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?

Upvotes: 0

Views: 2220

Answers (2)

Kewal Takhellambam
Kewal Takhellambam

Reputation: 101

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

Upvotes: 0

nos
nos

Reputation: 229058

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)

Upvotes: 9

Related Questions