有没有办法在调试模式下将 makefile 配置为 link 个额外对象?
Is there a way to configure makefile to link extra objects on debug mode?
我正在尝试编写一个支持发布模式和调试模式的 makefile,而在调试模式下,我想 link 一个额外的对象 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)
我预计它会在我调用 make debug
时扩展 $(OBJ)
到 foo.o bar.o debug.o
,但它只会扩展到 foo.o bar.o
,因为目标在解析时会立即扩展。
我试过使用 .SECONDEXPANSION:
,但无法解决。
而且我也尝试过 $(eval OBJ += debug.o)
,但这导致 $(OBJ)
扩展到 foo.o bar.o debug.o
,即使 运行 make all
.
这可能吗,还是我应该解决这个问题?
编辑:修正了一个拼写错误,感谢@matt
为此,我使用 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
I expected it expand $(OBJ) to foo.o bar.o debug.o
它在配方中执行此操作,但不在先决条件列表中。
6.11 Target-specific Variable Values
As with automatic variables, these values are only available within the context of a target’s recipe (and in other target-specific assignments).
所以你必须坚持使用条件来实现你的目标。
顺便说一句。 CFLAGS = -Wall -I(INCPATH)
是一个错字。 %.o: %.c $(INCPATH)/*.h
显然是错误的——在真正需要的时候使用 $(wildcard ...) 。还要将所有出现的 build
更改为 $(TARGET)
,因为它确实是 foo
您正在构建的内容。然后修改您的 makefile - 在每个 运行.
之后清理所有内容可能不是一个好主意
我正在尝试编写一个支持发布模式和调试模式的 makefile,而在调试模式下,我想 link 一个额外的对象 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)
我预计它会在我调用 make debug
时扩展 $(OBJ)
到 foo.o bar.o debug.o
,但它只会扩展到 foo.o bar.o
,因为目标在解析时会立即扩展。
我试过使用 .SECONDEXPANSION:
,但无法解决。
而且我也尝试过 $(eval OBJ += debug.o)
,但这导致 $(OBJ)
扩展到 foo.o bar.o debug.o
,即使 运行 make all
.
这可能吗,还是我应该解决这个问题?
编辑:修正了一个拼写错误,感谢@matt
为此,我使用 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
I expected it expand $(OBJ) to foo.o bar.o debug.o
它在配方中执行此操作,但不在先决条件列表中。
6.11 Target-specific Variable Values
As with automatic variables, these values are only available within the context of a target’s recipe (and in other target-specific assignments).
所以你必须坚持使用条件来实现你的目标。
顺便说一句。 CFLAGS = -Wall -I(INCPATH)
是一个错字。 %.o: %.c $(INCPATH)/*.h
显然是错误的——在真正需要的时候使用 $(wildcard ...) 。还要将所有出现的 build
更改为 $(TARGET)
,因为它确实是 foo
您正在构建的内容。然后修改您的 makefile - 在每个 运行.