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.