Makefiles

It may get tedious to type over and over again

gcc -o myProgram lex.yy.c something.tab.y -ll -ly

One fix, if you're not in an emacs shell, is to use the up-arrow.  This takes you to previous commands.

If you are using the emacs shell, !g repeats the last command starting with g.  If you were using grep and gcc and want to make sure it's gcc your'e repeating, use !gc or !gcc.

But the standard way is to create a Makefile.

There is one Makefile per directory, and its name is always Makefile.  So you'd put one project in a directory.  Here is a Makefile:


# Makefile for the something.l and something.y project.  (This is a comment:  it starts with a #.)
a.out: 		lex.yy.c y.tab.c 	# The first line is what you want built, :, tab or tabs, what it depends on.
		gcc lex.yy.c y.tab.c 	# The next line is whatever command builds it.
 #It's important to use tabs, not spaces (at least in some versions of Unix).
lex.yy.c: 	lex.l
		flex -i lex.l #the -i makes it case-insensitive
 #a.out depends on lex.yy.c and something.tab.c.  But how are these built?  We give Makefile the same info:
#what the thing depends on, then how to build it
y.tab.c: 	yacc.y
		bison -d yacc.y -o y.tab.c

So that's a Makefile.  To use it, type make.  make will use whatever Makefile is in the current directory.

Here's a pair of lines you may want to add to your Makefile:

clean:
		rm -f *~ *.o lex.yy.c y.tab.c y.tab.h a.out

This removes the output of lex, yacc, and the object files from the compiler, and the resulting program.  To activate it, type make clean .

Complete Makefile for you to cut and paste:

#This Makefile will work for a lot of different yacc projects
# Note the -i option on flex, which makes the program 
# case-insensitive
# Will Briggs
# Fall 2025

a.out: 		lex.yy.c y.tab.c
		gcc lex.yy.c y.tab.c

y.tab.c: 	yacc.y
		bison -d yacc.y -o y.tab.c

y.tab.h: 	yacc.y
		bison -d yacc.y -o y.tab.c

lex.yy.c: 	lex.l
		flex -i lex.l #the -i makes it case-insensitive

clean:
		rm -f *~ *.o lex.yy.c y.tab.c y.tab.h