1

So I have to create a makefile that would generate the application described below and make sure each generated file has its own rule.

For the makefile: The first tool is flex, which takes a file called spec.l and generates a file called lex.yy.c. Another tool called bison expects a file calledspec.y and will generate the file spec.tab.c. If bison is called using the directives -vd, it will also generate a file called spec.tab.h (which is needed when compiling lex.yy.c). The two C files can be compiled into object files and then linked together with the yacc (-ly) and lex (-ll) libraries to generate the compiler (a.out. The makefile you describe must generate the following commands if you were starting just with spec.l and spec.y:

flex spec.l bison -vd spec.y gcc -c lex.yy.c gcc -c spec.tab.c gcc spec.tab.o lex.yy.o -ly -ll 

i am not sure where to start with this problem

edit: what i have so far

compiler: spec.tab.o lex.yy.o gcc spec.tab.o lex.yy.o -ly –ll lex.yy.c: spec.l flex spec.l spec.tab.c: spec.y bison -vd spec.y spec.tab.o: spec.tab.c gcc -c spec.tab.c lex.yy.o: lex.yy.c spec.tab.h gcc –c lex.yy.c clean: rm –f *.c *.o a.out 
3
  • So, what's the problem then? What don't you understand here? Do you know about the built in rules? Can you proceed from there? Commented Nov 30, 2012 at 5:03
  • In case you haven't found it already here's a link to start you off. A quick read of chapters 1-3 should get you going. Commented Nov 30, 2012 at 5:07
  • In case it wasn't clear: you do need to indent the command(s) associated with a dependency, and you need to leave a blank line between a command and the next dependency (otherwise, it thinks you're listing two or more commands to execute for a dependency). Commented Nov 30, 2012 at 6:50

1 Answer 1

2

You have to tell the make about the dependencies. For example, lex.yy.c depends on spec.l:

lex.yy.c: spec.l flex spec.l 

The first line say lex.yy.c depends on spec.l. The second tells how to generate an updated version of lex.yy.c when spec.l is newer. We pretty much repeat that pattern with the other files. In the case of calledspec.y, we have two results that are produced from the same input/command. At least with GNU make, you can specify that like this:

spec.tab.c spec.tab.h: calledspec.y bison -vd calledspec.y 

Then you pretty much repeat the process for dependencies of .o (or .obj, etc.) files on headers and C files:

lex.yy.o: lex.yy.c spec.tab.h $(cc) -c lex.yy.c 

One final note: unless you specify otherwise, make will build the first target specified in the makefile, so you normally want to arrange it with the final executable first, and other targets after that:

parser: lex.yy.o y.tab.o $(cc) -o parser lex.yy.o y.tab.o lex.yy.o: lex.yy.c spec.tab.h $(cc) -c lex.yy.c 

And so on. This only applies to targets though, not to macros, so you'll typically see a few things like:

cflags = -O2 

...at the beginning of a make file. Then the lines the invoke the compiler will use that, something like:

lex.yy.o: lex.yy.c spec.tab.h $(cc) $(cflags) -c lex.yy.c 

And when this is executed, the cflags macro will be expanded, so the command that gets executed is gcc -O2 -c lex.yy.c (and it predefines cc to the name of the compiler it normally expects to use, so Microsoft's make sets it to cl, GNU to gcc, etc.)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.