如何确保使用具有多个MAKE目标的Makefile中的正确设置编译目标文件

时间:2010-07-02 17:00:09

标签: makefile

我有一个小项目,可以从相同的源文件构建多个目标。目标需要使用不同的编译标志构建源文件。这实际上是在cygwin上,所以我会用它作为具体的例子,虽然我认为这是一个普遍的问题。

所以这将是Makefile的一个例子:

a: CFLAGS =

a: a.o c.o

b: CFLAGS = -mno-cygwin

b: b.o c.o

这原则上工作,构建一个将使用CFLAGS未编译的编译,而构建b将使用设置为-mno-cygwin的CFLAGS进行编译。但只有当c.o尚不存在时才会存在。

这样做

> make a b
处于原始目录的

将首先使用空CFLAGS编译a.c和c.c.然后它将尝试使用CFLAGS = -mno-cygwin构建b。但是由于c.o已经存在,它不会重新编译c.c导致链接器错误,因为目标文件需要具有相同的标志设置。

同样,cygwin-flag只是一个具体的例子,我正在寻找一个通用的解决方案。

我试过的是引入一个额外的目标来检查当前的CFLAGS并删除所有目标文件,如果它不匹配:

ARCH    = `echo $(CFLAGS)`
checkTarget:
-@if test "`cat .arch`" != "$(ARCH)"; then \
    rm *.o; \
    /bin/echo -n $(ARCH) > .arch; \
fi

将此目标作为两个目标的依赖项插入,可确保在需要时重新编译所有目标文件。

a: CFLAGS =

a: checkTarget a.o c.o

b: CFLAGS = -mno-cygwin

b: checkTarget b.o c.o

然而,这会重新编译每个目标文件,这是不必要的,并且在较大的项目中成为问题。

有更好的方法吗?

编辑: 在对单个答案的评论中包含一个暗示,您可以使目标文件取决于CFLAGS的内容。我无法弄清楚如何做到这一点,除了将它们放到临时文件中并与之前的文件进行比较,然后将其复制到依赖文件上。有没有更好的办法?

2 个答案:

答案 0 :(得分:2)

我们需要的是c.o的两个(或更多)版本,使用不同的标志进行编译并链接到不同的可执行文件中。您可以使用c_for_a.o等人为的文件名来执行此操作,但将它们保存在不同的目录for_a/for_b/中更为简洁:

a for_a/%: CFLAGS =

a: a.o for_a/c.o

b for_b/%: CFLAGS = -mno-cygwin

b: b.o for_b/c.o

(如果不清楚,我可以填写Makefile的其余部分。)

修改:
如果您不想保留多个c.o,则有时需要重新编译c.o. checkTarget这个想法可能会有一些改进。

当您构建b之类的目标并且c.o已经存在时,c.o是否构建为CFLAGS适合b的问题很重要,并使用checkTarget记录该信息。 但您不关心CFLAGS使用的是什么,只关注它们是b的{​​{1}} 。因此,您不必在CFLAGS文件中记录任何内容,只需在构建新目标时更新它:

checkTarget

答案 1 :(得分:0)