In a project that uses make
and bison
, I'm having difficulty specifying that the compiled grammar grammar.tab.c
depends on the grammar input grammar.y
, that each object file depends on a corresponding source file (including grammar.tab.o
), and that the executable depends on all object files.
The problem is that running make
when grammar.tab.c does not yet exist means that there is no attempt to build it, and when the executable is built the yyparse
function is missing.
My Makefile
is:
CFLAGS = -g -Wall
YACC = bison -d -r all
OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
HEADERS=grammar.tab.h hex.h compiler.h types.h
all: grammar.tab.h c
clean:
rm -f $(OBJ) *.tab.c *.tab.h c c.exe *.output
c: $(OBJ)
$(CC) -o $@ $(OBJ) $(CFLAGS)
grammar.tab.c: grammar.y
$(YACC) grammar.y
grammar.tab.h: grammar.y
$(YACC) grammar.y
%.o: %.c $(HEADERS)
$(CC) -c $< $(CFLAGS)
If I change it with:
OBJ=$(patsubst %.c, %.o, $(wildcard *.c)) grammar.tab.o
Then it will build the compiled grammar if it doesn't already exist. But if it does already exist, then
when building the executable, there will be an error about yyparse
being provided twice (presumably because $OBJ
contains grammar.tab.o
twice).
What I'm aiming for is a Makefile that:
- Will correctly build the executable on a
make
command, rebuilding intermediate files as necessary. - Will pick up all
*.c
files in the directory (i.e. doesn't need to be changed when new source files are added). - Is easy to read and understand. I don't mind learning new
make
features as long as it's only one or two at a time.
How do others' grammar-building Makefiles work?
Edit Ok, those are great answers. I went with the filter-out one, since it was the smallest change. I'm really glad that everyone seemed to know exactly what I'm talking about -- I was apprehensive about being told to use something byzantine like automake ;-).
Thanks everyone.