为什么当我执行make时没有-g选项(gdb),即使我把它写在makefile中



我正在为我的小项目编写一个makefile,这是我的makefile:

CC=gcc
CFLAGS=-I.
DEPS = parse.h y.tab.h
OBJ = y.tab.o lex.yy.o parse.o 
FLAGS = -g -Wall
LDFLAGS = -lpthread
default:all
all: lisod
lex.yy.c: lexer.l
flex $^
y.tab.c: parser.y
yacc -d $^
%.o: %.c $(DEPS)
$(CC) $(FLAGS)  -c -o $@ $< $(CFLAGS)
example: $(OBJ) example.o
$(CC) -o $@ $^ $(CFLAGS)
lisod: lisod.o csapp.o $(OBJ)   $(LDFLAGS) 
$(CC) -o $@ $^ $(CFLAGS) $(FLAGS)
# hello:
#   echo hello
clean:
rm -f *~ *.o example lex.yy.c y.tab.c y.tab.h lisod

但是当我执行make时,似乎没有-g选项,因此我无法使用gdb进行调试 以下是 make 输出的一部分:

gcc -I.   -c -o lisod.o lisod.c
gcc -I.   -c -o csapp.o csapp.c

但是当我执行make时,似乎没有-g选项,因此我无法使用gdb进行调试

如果您仔细查看输出,您会发现问题不在于具体的-g标志,而在于您提供的模式规则根本没有被使用。-I.选项首先出现而不是最后出现的事实证实了这一点。

您得到的是用于从相应的 .c 文件构建 .o 文件的默认规则。 您提供的规则在两者都适用时会覆盖内置规则,但在make的分析中,您的模式规则不会(总是(适用,因为它指定了最初可能不存在且没有构建规则的先决条件(至少y.tab.h(。 (请参阅GNU Make手册中的模式如何匹配。

事实上,你遇到了一个经典的问题make的世界模型:它不能很好地处理生成多个输出的配方,这些输出是其他规则的先决条件。 您可能对 Automake 手册对此主题的讨论感兴趣,该主题主要针对符合make实现,并提供了一系列越来越复杂(且越来越灵活(的规则。 建议将以下简单模式设置为"在大多数情况下足够":

y.tab.c: parser.y
yacc -d $^
# Add this, so make knows where y.tab.h comes from:
y.tab.h: y.tab.c
# I assume that parse.h is an ordinary source, not a generated one
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) $(FLAGS) -c -o $@ $<

请注意,我将CFLAGS移到了 compile 命令的开头而不是结尾。 虽然它可能不会在您的情况下产生任何影响,但它并不完全是风格上的,因为构建命令行上的选项顺序很重要。 这会极大地影响链接命令,但它也会影响编译命令,具体取决于所涉及的选项。

更新:

但是,只要您依赖于特定于GNUmake(模式规则(的功能,您不妨充分利用它们。 正如@MadScientist评论中所观察到的,GNUmake对待具有多个目标的模式规则的方式与它(和其他make(对待具有多个目标的普通规则的方式不同:它理解并期望规则配方的一次执行,以创建通过模式与一组先决条件匹配的所有目标。

因此,如果你打算使用模式规则,那么正如MS所观察到的那样,这甚至比上述"在大多数情况下足够"的替代方案更好:

%.tab.c %.tab.h : parser.%
yacc -d $^
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) $(FLAGS) -c -o $@ $<

最新更新