有没有一种方法可以配置makefile在调试模式下链接其他对象?

时间:2019-05-13 10:13:14

标签: makefile gnu-make

我正在尝试编写一个支持发布模式和调试模式的makefile,而在调试模式下,我想链接一个额外的对象debug.o来覆盖调试功能。

例如:

CFLAGS = -Wall -I$(INCPATH)

INCPATH = include
TARGET = foo
OBJ = foo.o bar.o

# release mode
all: build run clear

# debug mode
debug: CFLAGS += -g -DDEBUG
debug: OBJ += debug.o
debug: build gdb-run clear

# link objects
build: $(OBJ)
    gcc $(CFLAGS) -o $(TARGET) $(OBJ)

# compile source code
%.o: %.c $(INCPATH)/*.h
    gcc $(CFLAGS) -c $@ $<

# default run mode
run:
    ./$(TARGET)

# debug run mode
gdb-run:
    gdb --args $(TARGET)

clear:
    rm -f $(OBJ) $(TARGET)

我希望在我调用$(OBJ)时将其从foo.o bar.o debug.o扩展到make debug,但是它只会扩展到foo.o bar.o,因为目标在解析后会立即扩展。

我尝试使用.SECONDEXPANSION:,但无法解决问题。

我也尝试过$(eval OBJ += debug.o),但是即使在运行$(OBJ)时,也导致将foo.o bar.o debug.o扩展到make all

这可能吗,还是我应该解决?

编辑:通过@matt

修复了一个错字

2 个答案:

答案 0 :(得分:0)

为此,我将GNU make "conditional" mechanism与名为MODE的 make 变量一起使用。就您而言,

MODE = RELEASE
OBJ = foo.o bar.o
ifeq ($(MODE),DEBUG)
   OBJ += debug.o
endif
[...]

然后使用其中一个进行构建

make    # a MODE=RELEASE build by default

make MODE=DEBUG

答案 1 :(得分:0)

  

我希望它将$(OBJ)扩展为foo.o bar.o debug.o

它是在配方中执行的,但不在先决条件列表中。

6.11 Target-specific Variable Values

  

与自动变量一样,这些值仅在目标配方的上下文中(以及在其他特定于目标的分配中)可用。

因此,您必须遵守条件才能实现目标。

顺便说一句。 CFLAGS = -Wall -I(INCPATH)是一个错字。 %.o: %.c $(INCPATH)/*.h是完全错误的-真正需要时使用$(通配符...)。同样,将所有发生的build更改为$(TARGET),因为这实际上是您正在构建的foo。然后修改您的makefile-每次运行后清理所有内容可能不是一个好主意。