theory
theory

Reputation: 9897

Why doesn't make build an object file on the first run?

I have this Makefile:

CFLAGS := $(CFLAGS) -std=c99

shell: main.o shellparser.o shellscanner.o
    $(CC) -o shell main.o shellparser.o shellscanner.o

main.o: main.c shellparser.h shellscanner.h

shellparser.o: shellparser.h

shellparser.h: shellparser.y lemon
    ./lemon shellparser.y

shellscanner.o: shellscanner.h

shellscanner.h: shellscanner.l
    flex --outfile=shellscanner.c --header-file=shellscanner.h shellscanner.l

# Prevent yacc from trying to build parsers.
# http://stackoverflow.com/a/5395195/79202
%.c: %.y

lemon: lemon.c
    $(CC) -o lemon lemon.c

For some reason, on the first run of make, shellparser.o isn't built:

> make
cc -o lemon lemon.c
./lemon shellparser.y
flex --outfile=shellscanner.c --header-file=shellscanner.h shellscanner.l
cc  -std=c99   -c -o main.o main.c
cc  -std=c99   -c -o shellscanner.o shellscanner.c
cc -o shell main.o shellparser.o shellscanner.o
i686-apple-darwin10-gcc-4.2.1: shellparser.o: No such file or directory
make: *** [shell] Error 1
rm shellscanner.c

If I run it again, it then builds it correctly:

> make
cc  -std=c99   -c -o shellparser.o shellparser.c
cc -o shell main.o shellparser.o shellscanner.o

So what do I have out-of-order such that it doesn't build it the first time?

Upvotes: 2

Views: 131

Answers (1)

andrewdotn
andrewdotn

Reputation: 34873

The first time you try to build, Make doesn’t know that lemon outputs shellparser.c, so it doesn’t try to build it. When you rebuild, shellparser.c does exist, so Make uses it. The solution is to explicitly tell Make that lemon outputs shellparser.c:

diff --git a/Makefile b/Makefile
index bf2655e..d6b288d 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ main.o: main.c shellparser.h shellscanner.h

 shellparser.o: shellparser.h

-shellparser.h: shellparser.y lemon
+shellparser.c shellparser.h: shellparser.y lemon
        ./lemon shellparser.y

 shellscanner.o: shellscanner.h
diff --git a/main.c b/main.c
index 81ec151..4179981 100644
--- a/main.c
+++ b/main.c
@@ -33,7 +33,7 @@ void parse(const char *commandLine) {
 }

 // Borrowed from http://stackoverflow.com/a/314422/79202.
-char * getline(void) {
+char * my_getline(void) {
     char * line = malloc(100), * linep = line;
     size_t lenmax = 100, len = lenmax;
     int c;
@@ -69,7 +69,7 @@ int main(int argc, char** argv) {
     void* shellParser = ParseAlloc(malloc);
     char *line;
     printf("> ");
-    while ( line = getline() ) {
+    while ( line = my_getline() ) {
         parse(line);
         printf("> ");
     }

Also I renamed getline so it would build on my mac; thanks for posting all your source!

Upvotes: 1

Related Questions