为什么不在第一次运行时构建一个目标文件?

时间:2013-01-25 07:17:41

标签: makefile target

我有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

出于某种原因,在make的第一次运行中,shellparser.o未构建:

> 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

如果我再次运行它,那么它会正确构建它:

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

那么我有什么乱序,以至于第一次不构建它?

1 个答案:

答案 0 :(得分:1)

第一次尝试构建时,Make不知道lemon输出shellparser.c,因此它不会尝试构建它。重建时,shellparser.c确实存在,因此Make使用它。解决方案是明确告诉Make lemon输出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("> ");
     }

我也重命名了getline所以它会建立在我的Mac上;感谢您发布所有来源!