所以我有一段艰难的时间试图弄清楚如何制作我的Makefile,这样当我make
并编译发布版本然后再进行make debug
它如果文件尚未更新,则在gcc上设置新的-DDEBUG
和-g
编译调试版本。
例如:
make
make debug
注意我不想每次都要做一个干净,因为我不想重新编译文件,如果我连续做2 make
所以设置干净作为依赖不是这将是一个有效的答案
答案 0 :(得分:1)
您可能希望根据构建模式将目标文件编译到不同的目录中,例如:
# default mode, override with `make BUILD=release`
BUILD := debug
obj_dir := ${BUILD}
CFLAGS.debug := -g -O0
CFLAGS.release := -g -O3 -march=native -DNDEBUG
all : ${obj_dir}/test
# Example executable
${obj_dir}/test : ${obj_dir}/test.o
test.c :
echo "int main() { return 0; }" > $@
# Generic rules
${obj_dir} :
mkdir $@
${obj_dir}/%.o : %.c Makefile | ${obj_dir} # Also recompile when Makefile changes.
${CC} -c -o $@ ${CPPFLAGS} ${CFLAGS} ${CFLAGS.${BUILD}} -MD -MP $<
${obj_dir}/% : Makefile | ${obj_dir} # Also re-link when Makefile changes.
${CC} -o $@ ${LDFLAGS} $(filter-out Makefile,$^) ${LDLIBS}
clean :
rm -rf ${obj_dir}
-include $(wildcard ${obj_dir}/*.d)
${obj_dir}/*.d : ;
.PHONY: all clean
(奖励功能:自动依赖关系生成)。
用法:
[max@localhost:~/tmp] $ make
mkdir debug
echo "int main() { return 0; }" > test.c
cc -c -o debug/test.o -g -O0 -MD -MP test.c
cc -o debug/test debug/test.o
[max@localhost:~/tmp] $ make
make: Nothing to be done for 'all'.
[max@localhost:~/tmp] $ make BUILD=release
mkdir release
cc -c -o release/test.o -g -O3 -march=native -DNDEBUG -MD -MP test.c
cc -o release/test release/test.o
[max@localhost:~/tmp] $ make BUILD=release
make: Nothing to be done for 'all'.
答案 1 :(得分:0)
首先,您不应该运行make debug
- 这意味着您要构建不同的目标(debug
)。但是你没有,你想用不同的选项构建相同的目标。这就是你所做的,你运行一个不同的选项,一个变量值
>make DEBUG=Y
运行时
>make
你也真的传递了那个变量,只是将空字符串作为值。
现在,为了让它在Makefile中按你想要的方式工作,你可能希望它就像DEBUG
是必备文件一样,其配方如下:
foobar.o: foobar.c DEBUG
gcc $(if $(DEBUG), -DDEBUG -g) -c $< -o $@
当然,通常这不起作用,因为DEBUG
是变量,而不是文件。所以你需要一个黑客,我称之为“可靠的变量”。它基本上是一种声明变量的行为方式。我在其他一个答案中描述了这种技术:
答案 2 :(得分:0)
我曾经做过这样的事情,看起来像那样(归结为最低限度):
EXE := a.out
SRC := $(wildcard *.c)
ifneq ($(MAKECMDGOALS),debug)
OBJ := $(SRC:.c=.o)
else
OBJ := $(SRC:.c=-d.o)
endif
.PHONY: all debug
all: $(EXE)
debug: CFLAGS += -g -DDEBUG
debug: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
%.o %-d.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
诀窍是使用两个单独的目标文件列表,并根据目标选择一个。