在使用make
和bison
的项目中,我很难指定编译后的语法grammar.tab.c
取决于语法输入grammar.y
,每个目标文件取决于相应的源文件(包括grammar.tab.o
),并且可执行文件取决于所有对象文件。
问题在于,当grammar.tab.c尚不存在时运行make
意味着没有尝试构建它,并且在生成可执行文件时yyparse
函数丢失了。
我的Makefile
是:
CFLAGS = -g -Wall
YACC = bison -d -r all
OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
HEADERS=grammar.tab.h hex.h compiler.h types.h
all: grammar.tab.h c
clean:
rm -f $(OBJ) *.tab.c *.tab.h c c.exe *.output
c: $(OBJ)
$(CC) -o $@ $(OBJ) $(CFLAGS)
grammar.tab.c: grammar.y
$(YACC) grammar.y
grammar.tab.h: grammar.y
$(YACC) grammar.y
%.o: %.c $(HEADERS)
$(CC) -c $< $(CFLAGS)
如果我用以下方法更改它:
OBJ=$(patsubst %.c, %.o, $(wildcard *.c)) grammar.tab.o
然后,如果尚不存在编译的语法,它将构建该语法。但是如果它已经存在,那么
生成可执行文件时,将出现两次有关
yyparse
的错误(大概是因为$OBJ
两次包含grammar.tab.o
)。我的目标是生成一个Makefile:
make
命令正确构建可执行文件,并根据需要重建中间文件。 *.c
文件(即,在添加新的源文件时不需要更改)。 make
功能,只要一次只有一两个即可。 他人的语法构建Makefile如何工作?
编辑好的,这些都是不错的答案。我选择了过滤器,因为这是最小的更改。我真的很高兴每个人似乎都知道我在说什么-我很被告知要使用拜占庭式的东西,例如automake ;-)。
感谢大家。
最佳答案
如果使用的是GNU make,则可以使用过滤谓词从目标的依赖项中手动排除特定文件。像这样:OBJ=$(filter-out $(grammar.tab.o), $(patsubst %.c, %.o, ...)) grammar.tab.o
。
首先,将grammar.tab.o从现有的目标文件中排除(可能不存在),然后在所有情况下都将其重新添加。诚然有点回旋处,但它的工作原理。这就是我们在工作中使用的。
关于makefile - 使用make生成野牛语法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1691696/