1

我的 makefile 看起来像这样:

FOO_OBJECT_FILES := $(OBJDIR)/Foo.cpp.o
BAR_OBJECT_FILES := $(OBJDIR)/Bar.cpp.o $(OBJDIR)Bar.c.o
ALL_OBJECT_FILES := $(FOO_OBJECT_FILES) $(BAR_OBJECT_FILES)

$(BINDIR)/Foo.a: $(FOO_OBJECT_FILES)
    # Rules for making a static library out of Foo's object files go here.

$(BINDIR)/Bar.a: $(BAR_OBJECT_FILES)
    # This uses the exact same command sequence as the previous rule.

$(BINDIR)/All.a: $(ALL_OBJECT_FILES)
       # Ditto.

# ...

当(不是if)更多目标被添加到项目中时,开发人员将必须更新至少三件事:

  1. 新目标的目标文件列表
  2. 所有目标文件的列表
  3. 用于制作新目标的目标,即使它使用与其他目标相同的规则

有没有办法简化这个过程,还是我坚持下去?

我尝试使用通配符规则,但看起来它们不适用于宏。

$(BINDIR)/%.a: $(%_OBJECT_FILES)
    # ...

您可以将目标文件列表视为规则,但最终目标规则无法直接访问它们。

OBJECT_FILES_Foo: $(OBJDIR)/Foo.cpp.o
OBJECT_FILES_Bar: $(OBJDIR)/Bar.cpp.o $(OBJDIR)Bar.c.o
OBJECT_FILES_All: FOO_OBJECT_FILES BAR_OBJECT_FILES

$(BINDIR)/%.a: OBJECT_FILES_%
    # This rule can't see into the object file lists to use them to build.

没有更好的办法吗?

4

3 回答 3

1

您不能对 1 和 2 做太多事情,这些都是 Make 无法推断的任意事情。您可以稍微改进3:

$(BINDIR)/%.a:
    # commands for making a static library

# adding a new target:
QUARTZ_OBJECT_FILES := $(OBJDIR)/Quartz.cpp.o $(OBJDIR)Arbitrary.o
ALL_OBJECT_FILES += $(QUARTZ_OBJECT_FILES) 
$(BINDIR)/Quartz.a: $(QUARTZ_OBJECT_FILES)

您可以使用模板将这三行减少为一行:

$(eval $(call template, QUARTZ_OBJECT_FILES, $(OBJDIR)/Quartz.cpp.o $(OBJDIR)Arbitrary.o))

但这真的值得吗?

于 2011-10-26T22:47:26.333 回答
1

可能有很多方法可以做到这一点。一种这样的方式如下。新目标需要做的就是将其名称添加到模块列表中,并为其提供依赖项列表。

BINDIR := 斌
OBJDIR := 对象

模块 := Foo 酒吧

Foo_OBJS := $(OBJDIR)/Foo.cpp.o
Bar_OBJS := $(OBJDIR)/Bar.cpp.o $(OBJDIR)/Bar.co

################################################# ###
##
# 下面的任何内容都不需要更改。#
##
################################################# ###

All_OBJS := $(foreach mod, $(MODULES),$($(mod)_OBJS))

定义规则
$(BINDIR)/$(1).a: $($(1)_OBJS)
    @回声
    @echo '目标:$$@'
    @echo '部门:$$^'
endef

$(foreach lib, All $(MODULES), $(eval $(call rule,$(lib))))

##########################################
##
# 下一部分只是为了测试。#
##
##########################################

.PHONY:全部
全部:$(foreach lib,全部$(模块),$(BINDIR)/$(lib).a)

%.o:
    @echo 制作 $@
于 2011-10-26T22:48:51.523 回答
1

虽然其他答案为手动编写 makefile 提供了很好的解决方案,但您可以简单地使用 automake 来简化构建过程。

于 2011-10-27T09:52:18.507 回答