c++ 如何在Makefile中为多个目标依赖项对编写通用规则

aiazj4mn  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(173)

我想写一个Makefile来编译3个不同的C++文件,它们有各自独立的目标。所有这三个文件和其他未使用的文件都驻留在同一个目录中。例如,该目录可能包含文件a.cppb.cppc.cppd.cpp。在这四个文件中,我希望Makefile只为前三个文件(即a.cppb.cppc.cpp)运行构建命令。我将这三个文件存储在Makefile的一个变量中。类似地,我还将它们的目标存储在另一个变量中。我希望make使用a.cpp编译目标ab.cpp编译目标bc.cpp编译目标c。这是,然而,这只是一个例子。真实的项目有数百个目标。因此,我不想为每个目标手动编写规则。有没有一种方法可以告诉make使用其特定依赖项编译每个目标?
为了测试不同的方法,我创建了一个包含四个文件的小型测试项目:Makefileaabbcc。使用Makefile,我希望生成目标abc。所有这三个目标都只有一个依赖项,即它们的源文件。例如,a依赖于aa。我编写了一个测试Makefile来实现这一点,粘贴如下:

TARGETS = a b c                                                                                                                                                
DEPS = aa bb cc

$(TARGETS): $(DEPS)
        @echo $@ $<

这个Makefile只是打印出目标和它们的依赖项。当我执行这个Makefile时,我得到:

a aa

不过,我想要的是以下几点:

a aa
b bb
c cc

我该怎么做呢?注意,我需要专门构建存储在变量TARGETS中的对象,而不是其他对象。

uoifb46i

uoifb46i1#

它只构建一个目标的原因是make在默认情况下只构建makefile中的第一个目标,在你的例子中,变量被扩展后make会看到以下规则:

a b c: aa bb cc
        @echo $@ $<

这是 * 相同的 *(使)就好像你写了这个:

a: aa bb cc
        @echo $@ $<
b: aa bb cc
        @echo $@ $<
c: aa bb cc
        @echo $@ $<

由于a是第一个目标,当您键入make时,它将只生成a。如果您希望make生成所有目标,请将第一个目标设置为依赖于所有目标的内容,例如:

TARGETS = a b c                                                                                                                                                
DEPS = aa bb cc

all: $(TARGETS)

$(TARGETS): $(DEPS)
        @echo $@ $<

但是,当然,您可以从上面看到,这不是您想要的,因为每个目标都有所有先决条件,所以当bb更改时,所有abc都将重新构建。
为此,您需要使用a pattern rule。例如,如果您想从a.cpp构建a,您可以这样编写makefile:

TARGETS = a b c                                                                                                                                                
DEPS = aa bb cc

all: $(TARGETS)

%: %.cpp
        @echo $@ $<
mmvthczy

mmvthczy2#

如果目标名称不是从依赖项名称派生的,您还可以执行类似以下的操作:

TARGETS = a b foo

all:$(TARGETS)                                                                                                                                             

a:aa
b:bb
foo:bar

$(TARGETS):
        @echo $@ $<

.PHONY: all
.PHONY: $(TARGETS)

请注意,我将TARGETS声明为PHONY,因为您的配方不会创建具有这些名称的文件。

相关问题