【问题标题】:Makefile pattern rule with mixed dependencies具有混合依赖项的 Makefile 模式规则
【发布时间】:2015-01-22 10:58:00
【问题描述】:

我在 Makefile 中编写了以下几行代码:

PROJECTS  = ExamsGenerator ExercisesImporter
VERSION   = .v0.0
EXTENSION = .Exe

BINDIR    = ../bin
CONFDIR   = ../config
DATADIR   = ../data
DOCDIR    = ../doc
INCDIR    = ../include
LIBDIR    = ../lib
OBJDIR    = ../obj
SRCDIR    = ../src

INCDIRS   = $(INCDIR:%=-I%)

CC        = g++
CCVAR     = -D__DATADIR__=\"$(DATADIR)\"

CFLAGS    = -g -Wall $(shell root-config --cflags)  $(INCDIRS)
LDFLAGS   = -g -Wall $(shell root-config --ldflags)
LDLIBS    =          $(shell root-config --glibs)

MEG_DEP  = Functions.h Parser.h Test.h
MEG_DEPS = $(patsubst %,$(INCDIR)/%,$(MEG_DEP))

MEI_DEP  = Functions.h Parser.h Exercise.h
MEI_DEPS = $(patsubst %,$(INCDIR)/%,$(MEI_DEP))

MEG_OBJ   = mainExamsGenerator.o Parser.o Test.o
MEG_OBJS  = $(patsubst %,$(OBJDIR)/%,$(MEG_OBJ))

MEI_OBJ   = mainExercisesImporter.o Parser.o Exercise.o
MEI_OBJS  = $(patsubst %,$(OBJDIR)/%,$(MEI_OBJ))

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(MEG_DEPS) $(MEI_DEPS)
    @echo "\nCreating object: $@"
    $(CC) $(CCVAR) $(CFLAGS) -c -o $@ $<

all: $(PROJECTS)
    @echo "\n"

ExamsGenerator: $(MEG_OBJS)
    @echo "\nLinking $@"
    $(CC) $(CCVAR) $(CFLAGS) $(LDLIBS) -o $(BINDIR)/$(@)$(VERSION)$(EXTENSION) $^

ExercisesImporter: $(MEI_OBJS)
    @echo "\nLinking $@"
    $(CC) $(CCVAR) $(CFLAGS) $(LDLIBS) -o $(BINDIR)/$(@)$(VERSION)$(EXTENSION) $^

.SILENT:

.PHONY: clean

clean:
    \rm -f $(BINDIR)/*$(EXTENSION) $(OBJDIR)/*.o *~ $(INCDIR)/*~ $(SRCDIR)/*~

我是 Makefile 新手,所以我从几个地方获得了提示,我可能没有以最优雅的方式编写它。我有几个问题需要改进:

  1. 我真的需要将 $(OBJDIR)/%.o 添加到依赖项中吗?
  2. 以这种方式编写 Parser.h 被列出两次。是否可以重写此模式规则以避免它?例如,如果修改了 Exercise.h,我不想重新编译 MEG 的东西。将添加新的依赖项,我想以一种智能的方式管理它们。
  3. 还有其他建议吗?

提前感谢您的帮助。

再见...

【问题讨论】:

    标签: c++ design-patterns makefile dependencies


    【解决方案1】:

    不,您不需要(也不想)将目标列为其自身的先决条件。那没有意义,也行不通。

    $(patsubst %,prefix/%,$(var))可以写成$(addprefix prefix,$(var))

    您可能想阅读Auto-Dependency Generation 以了解自动为.o 文件生成正确依赖项的方法。它将帮助您解决一些问题。

    但是,如果您不想花哨,那么您需要记住的是,您需要为每个目标列出所有该目标所依赖的文件,而不是其他文件。

    所以

    1. Parser.o 大概取决于(至少)Parser.h

      所以添加$(OBJDIR)/Parser.o: $(INCDIR)/Parser.h

    2. Exercise.o 大概取决于(至少)Exercise.h(也可能还取决于Parser.h?)

      所以添加$(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h(或者可能是$(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h $(INCDIR)/Parser.h

    3. 等等……

    请注意,先决条件从它们所在的任何位置组合,因此上述建议的行将与 $(OBJDIR)/%.o: $(SRCDIR)/%.cpp 规则组合以形成给定 .o 文件的完整先决条件集。

    【讨论】:

    • 我已经更改了我的问题并复制了整个 Makefile。
    • 如果 MEG 将依赖 Function1.h 和 Function2.h 上的 MEI(没有源文件)怎么办?在这种情况下,规则 $(OBJDIR)/%.o: $(SRCDIR)/%.cpp 是不够的。
    • 当您在我的回答中包含其他行中的这些先决条件时,它就足够了。您列出了需要它们的目标的先决条件。因此,如果有 Function1.o,您将有 Function1.o: Function1.h 行,等等。
    • 非常感谢。我会试试你的建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多