sonus21
sonus21

Reputation: 5388

Running all targets at once in a Makefile

I have a Makefile as below

all:
    bison -d -v parser.y
    flex  -o parser.lex.c parser.lex
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm 
clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c     

When i ran make in terminal then it only runs target all.

I have tried by adding .PHONY:all clean and .PHONY:clean even though it only runs all . What are the changes i should make in Makefile so that it runs all target ?

System Configurations:
Ubuntu 14.10
GNU Make 4.0

Upvotes: 7

Views: 16256

Answers (2)

user1795160
user1795160

Reputation:

If you really want to make all targets in the Makefile (you really don't want to, this is usually not how you use makefiles), you can add a target that has all the other targets of the Makefile as it's prerequisites:

.PHONY: all_targets
all_targets: all clean

.PHONY: all
all:
    # ... command script
.PHONY: clean
clean:
    # ... command script

In this particular example, making all followed by clean is complete nonsense, since all would build all files and clean would remove them. If you want to clean all files before building all (and you don't want to do this either), you can in fact just turn around the prerequisites of all_targets:

.PHONY: all_targets
all_targets: clean all

.PHONY: all
all:
    # ...
.PHONY: clean
clean:
    # ...

Again, this is really not how you want to use make, since it is designed to skip all the unnecessary work in the build process (that is, not recompiling those files that do not need to be recompiled, etc).

Also remember that you can call make with more than just one target to build. So in your example, you could also build all targets by executing

make all clean

Note that the targets will be built in the order they were passed to the command line, so the first target to be built here is all, followed by clean (which again is nonsense).

If you want to read more about how to correctly use makefiles, I suggest you to grab the book Managing Projects with GNU Make. It features a quite comprehensive explanation of almost all (GNU) Make features.

Edit: As tripleee pointed out, the all_targets target in the above examples should of course be a phony target.

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 81052

You want to run all and clean when you just type make? That's usually not useful since that would clean up what you just built (though in your case I see that your clean target doesn't actually do that).

To do this you want something like.

all: cparser clean

cparser:
    bison -d -v parser.y
    flex  -o parser.lex.c parser.lex
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm

clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c

Though that is still a fairly poor makefile and doesn't take advantage of any of the benefits that make affords you (like intelligently rebuilding things only when their prerequisites change).

I would suggest you probably want something more like this.

.PHONY: all
all: cparser

parser.lex: parser.y
    bison -d -v parser.y

parser.lex.% parser.tab.%: parser.lex
    flex  -o parser.lex.c parser.lex

cparser: parser.lex.c parser.tab.c
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm

.PHONY: clean    
clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c cparser

Assuming I recall correctly that flex will generate both the parser.lex.c and parser.tab.c files at the same time.

Note also that the prerequisites are chained and that clean now cleans the binary as well. You don't need to run make clean to have things rebuild correctly this way.

Upvotes: 10

Related Questions