我在我的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的新手,所以我从几个地方收集了一些提示,但我可能没有以最优雅的方式编写它。我有几个问题可以改善它们:


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


在此先感谢您的帮助。

再见

最佳答案

不,您不需要(也不想)将目标列出为自己的先决条件。那没有道理,也行不通。

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

您可能需要阅读Auto-Dependency Generation以获得自动为.o文件生成正确依赖关系的方法。这将有助于解决您的一些问题。

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

所以


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

因此添加$(OBJDIR)/Parser.o: $(INCDIR)/Parser.h
Exercise.o大概取决于(至少)Exercise.h(可能还取决于Parser.h?)

因此,添加$(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h(或者可能添加$(OBJDIR)/Exercise.o: $(INCDIR)/Exercise.h $(INCDIR)/Parser.h
等等...


请注意,先决条件可以从任何地方组合,因此上述建议的行将与$(OBJDIR)/%.o: $(SRCDIR)/%.cpp规则结合,以形成给定.o文件的全套先决条件。

10-05 19:35