Makefile:什么都不做
Makefile: nothing to be done
我正在使用Bison和Flex构建一个解析器。为了编译所有内容,我使用了一个简单的makefile。但是,我不是创建makefile的专家。makefile正在工作,除了一些事情:
更改file.cpp中的源代码不会被makefile检测到。无事可做make clean
解决了这个问题,但这当然不是必需的。我找到了很多makefile教程,但是没有一个讨论这类问题。
CC=g++
CFLAGS=-Wall -std=c++11 -ll
EXECUTABLE=parser
OBJS=parser.tab.cpp lex.yy.c
FILES= file.cpp
all: parser
parser.tab.cpp parser.tab.hpp: parser.ypp
bison -d parser.ypp
lex.yy.c: parser.l parser.tab.hpp
flex parser.l
parser: $(OBJS) $(FILES)
$(CC) $(CFLAGS) $(OBJS) $(FILES) -o $(EXECUTABLE)
clean:
rm -rf *o $(EXECUTABLE) $(OBJS)
当然,我可以使用make -B all
,然后我检测到一些奇怪的东西:
bison -d parser.ypp
bison -d parser.ypp
flex parser.l
g++ -Wall -std=c++11 -ll parser.tab.cpp lex.yy.c file.cpp -o parser
为什么bison -d parser.ypp
做两次?
现在使用下面的makefile:
CC = g++
CFLAGS = --std=c++0x -O2
SOURCES = $(wildcard */*.cpp *.cpp) parser/parser.cpp
OBJECTS = $(SOURCES:.cpp=.o) scanner/scanner.o parser/parser.o
EXECUTABLE = calculator
all: parser/parser.cpp scanner/scanner.cpp $(EXECUTABLE)
parser/parser.cpp:
cd parser && bison -d -o parser.cpp grammar.ypp && cd ..
scanner/scanner.cpp: parser/parser.hpp
cd scanner && flex -o scanner.cpp lexer.l && cd ..
$(EXECUTABLE): $(OBJECTS)
$(CC) $^ -o "$@"
%.o: %.cpp
$(CC) $(CFLAGS) -c "$<" -o "$@"
clean:
rm -rf $(OBJECTS) $(EXECUTABLE) parser/parser.cpp parser/parser.hpp scanner/scanner.cpp
将file.cpp
作为构建cpp文件的依赖项。当你更改file.cpp
:
CC=g++
CFLAGS=-Wall -std=c++11 -ll
EXECUTABLE=parser
OBJS=parser.tab.cpp lex.yy.c
FILES= file.cpp
all: parser
parser.tab.cpp : parser.ypp $(FILES)
bison -d parser.ypp
lex.yy.c: parser.l parser.tab.hpp $(FILES)
flex parser.l
parser: $(OBJS) $(FILES)
$(CC) $(CFLAGS) $(OBJS) $(FILES) -o $(EXECUTABLE)
clean:
rm -rf *o $(EXECUTABLE) $(OBJS)
你的问题之一是这个
a b: c
do something
makefile
中的表示:
-
a
取决于c
;运行do something
-
b
取决于c
;运行do something
不像您希望的那样,a
和b
都是作为do something
的结果构建的。由于您有parser.tab.cpp
和parser.tab.hpp
作为显式依赖项(分别为parser
和lex.yy.c
), make
将构建它们,并运行相同的命令两次(如果您尝试并行构建,这将是有趣的)。
如果你能负担得起改变你的构建系统,你可能想看看Scons,它能更直观地做到这一点。
我也倾向于把你的make分开一点,这样每个。o都是独立构建的,所以你有这样的东西:
file.o: file.cpp
lex.yy.o: lex.yy.c parser.tab.hpp
parser: lex.yy.o parser.tab.o file.o
,因为这意味着它不太可能重新构建你不想要的东西,更有可能重新构建你想要的东西——如果你改变了。hpp,你就不会真的想重新构建lex.yy.c。但是您需要重新构建。o文件
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- @CPPFLAGS@在 Makefile.in 中意味着什么?
- 什么是 Eclipse 中的 MakeFile
- 分别创建目标文件,然后在Makefile中将它们链接在一起的目的是什么?< / h1 >
- Makefile:什么都不做
- 我的简单g++ Makefile有什么问题?
- 什么时候应该在Makefile中使用-c或-o GCC选项?
- 我的makefile有什么问题?无法实现
- Makefile错误:什么都不做
- Makefile中的这一行是什么意思?
- 如何识别冗余库从Makefile?有没有什么工具可以分析图书馆的使用情况?
- 使用makefile有什么好的理由吗