c++ - 具有混合依赖性的 Makefile 模式规则

标签 c++ design-patterns makefile dependencies

我在 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. 还有其他建议吗?

在此先感谢您的帮助。

再见...

最佳答案

不,您不需要(也不希望)将目标列为其先决条件。这没有意义,也行不通。

$(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 文件的一组先决条件。

关于c++ - 具有混合依赖性的 Makefile 模式规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28065601/

相关文章:

c++ - std::thread 中的 Visual Studio 2012 错误 C2248

c++ - 即使我将单个节点设置为 NULL 并删除它们,递归清除二叉树也不起作用

javascript - 使用 Function.prototype.bind() 部分应用 mkdirp

javascript - 放弃 javascript 命名空间和揭示模块模式以支持智能感知

makefile - gnu make 模式规则匹配错误的规则

c++ - 防止所选项目在 QListView 中超出 View

c++ - 如何告诉 Boost.Test 在第一个失败的测试用例上停止?

design-patterns - 选择哪种设计模式

c++ - 使用 Cmake 来做 ./genMakefiles && make -j4

linux - 无法调试联编文件。生成文件 :9: *** missing separator. 停止