Home > Blockchain >  How to make static libraries with Makefile?
How to make static libraries with Makefile?

Time:12-08

This is the Makefile

CC=gcc
CFLAGS=-Wall -pedantic -Werror -g 
LDFLAGS=-lm
RM=rm -f
SOURCES=$(wildcard *.c)
TARGETS=$(SOURCES:.c=)
OBJECTS=$(SOURCES:.c=.o)

.PHONY: all clean

all: test_stack

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

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

%.a: %.o
    ar rcs $@ $<
    ranlib $@

test_stack: genstacklib.a test_stack.o
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

clean:
    $(RM) $(OBJECTS) $(TARGETS)

I have the files genstacklib.c, genstacklib.h and test_stack.c Now I want to compile genstacklib as static library When test_stack calls the methods of genstacklib, it throws an exeception: for example: "undefined reference to `genStackNew'" I don't get why test_stack can't access the methods, for my current understanding it should have access to the library.

CodePudding user response:

Please copy and paste the exact errors you get into your question, with proper formatting, and also including the compile or link command that make printed. A statement like "throws an exception" is not precise and in fact is not really accurate because exceptions are thrown from running programs, but (if I understand your problem correctly) you are not able to link your program.

The problem is that the order of arguments to the linker is critical: all libraries must appear on the link line after all object files. Also the order of libraries matters but since you have only one that's not an issue.

In your rule:

test_stack: genstacklib.a test_stack.o
        $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

The $^ variable expands to the prerequisites, in this case genstacklib.a test_stack.o. So on your link line the library will appear before the object file, which won't work. Rewrite your rule like this:

test_stack: test_stack.o genstacklib.a
        $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

so the library comes after the object files and it will probably work.

As an aside, the variable LDFLAGS generally contains flags that manage the linker. Library references like -lm are traditionally put into a variable LDLIBS instead. Of course this is just convention but it's useful to follow conventions unless there's a good reason not to.

  • Related