如何实现记住上一个构建目标的Makefile?

Ell*_*ron 6 makefile gnu-make target

假设你有一个带有两个伪目标的Makefile,'all'和'debug'.'debug'目标用于构建与'all'相同的项目,除了一些不同的编译开关(例如-ggdb).由于目标使用不同的编译开关,如果在两者之间切换,显然需要重建整个项目.但GNUmake自然不会认识到这一点.

所以,如果你输入,make all你会得到

Building ...
...
Run Code Online (Sandbox Code Playgroud)

如果你打字make debug,你就得到了

make: Nothing to be done for `debug'.
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:你如何在Makefile中实现一个干净的解决方案,注意到最后一个构建使用了不同的伪目标或不同的编译开关,而不是你想要的那个?如果它们不同,Makefile将重建所有内容.

bob*_*ogo 3

将构建产品放入不同的目录树中(当然同时保留源代码的一份副本)。这样,无论是调试还是发布(甚至其他),您始终只是最新版本的简短编译。也不存在混淆的可能性。

编辑

上面的草图。

src := 1.c 2.c 3.c
bare-objs := ${src:%.c=%.o}
release-objs := ${bare-objs:%=Release/%}
debug-objs := ${bare-objs:%=Debug/%}

Release/prog: ${release-objs}
Debug/prog: ${debug-objs}

${release-objs}: Release/%.o: %.c # You gotta lurve static pattern rules
    gcc -c $< -o $@

${debug-objs}: Debug/%.o: %.c
    gcc -c $< -o $@

Release/prog Debug/prog:
    gcc $^ -o $@

.PHONY: all
all: Release/prog ; echo $@ Success

.PHONY: debug
debug: Debug/prog ; echo $@ Success
Run Code Online (Sandbox Code Playgroud)

(免责声明:未经测试,甚至未通过 make 运行。)

就这样吧。它甚至是-j安全的,所以你可以这样做make -j5 all debug。有很多明显的样板需要清理。