GNU make有时不会在VPATH中声明的文件夹中搜索

时间:2013-07-19 15:03:26

标签: c++ makefile gnu-make flex-lexer

我正在尝试使用 GNU make (版本3.81)构建一个小型C ++项目,但我必须调用 make 两次,因为第一次运行失败。这是我的项目目录:

project
    makefile
    include
        lexer.hpp   
    src
        main.cpp
        lexer.l

以下是我的makefile:

CC = g++
CPPFLAGS = -I include
VPATH = include src

OBJECTS = main.o lexer.o

test: $(OBJECTS)
$(CC) $(CPPFLAGS) -lfl -o $@ $^

main.o: lexer.hpp main.cpp
    $(CC) -c $(CPPFLAGS) $^

lexer.o: lexer.cpp
    $(CC) -c $(CPPFLAGS) $^

lexer.cpp: lexer.l
    flex -t $^ > src/lexer.cpp

.PHONY: clean

clean:
    rm -fR $(OBJECTS) src/lexer.cpp test

第一次运行 make 时,我得到以下输出,其中 make 抱怨没有找到lexer.cpp文件。但我不明白为什么 make 不在VPATH中声明的文件夹中寻找。

g++ -c -I include include/lexer.hpp src/main.cpp
flex -t src/lexer.l > src/lexer.cpp
g++ -c -I include lexer.cpp
g++: error: lexer.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [lexer.o] Error 1

但是,如果我再次调用 make ,则会找到lexer.cpp,编译工作正常。

g++ -c -I include src/lexer.cpp
g++ -I include -lfl -o test main.o lexer.o

为什么?

P.S。我为可怜的英语道歉。

1 个答案:

答案 0 :(得分:2)

这条规则错了:

lexer.cpp: lexer.l
        flex -t $^ > src/lexer.cpp

这个规则告诉make它将构建一个文件lexer.cpp,这就是make期望它做的事情,并且在规则完成之后make认为该文件已准备就绪,它将使用该文件名当其他目标依赖它时。但规则的真正含义是构建src/lexer.cpp

要正确编写此规则,您需要将其写为:

src/lexer.cpp: lexer.l
        flex -t $^ > $@

(您编写的每个make规则都应该始终更新文件$@

但是,通常VPATH不适合查找生成的文件(目标文件等:由make生成的任何文件)。它仅对查找源文件很有用(文件make不会自行构建)。