使搜索依赖项位于错误的位置

时间:2011-12-21 03:58:24

标签: makefile

我对(GNU)Make相对较新,发现它难以置信。我考虑转换到SCons,但我仍然想了解。

我在一个文件夹中有一个makefile,它包含子目录./src,./obj/[release|debug]和./bin[release|debug]。 makefile应该能够获取./src中的C ++源代码,将它们编译到适当的./obj目录中的目标文件中,并链接这些目标文件并将结果放在相应的./bin目录中。这是我的makefile(为简单起见而编辑):

CONFIG = release
#CONFIG = debug

OBJS = Container.o

OBJDIR = obj/$(CONFIG)
BINDIR = bin/$(CONFIG)

VPATH = src $(BINDIR)
vpath %.o $(OBJDIR)

.PHONY: release

release:  $(OBJS)
    $(CXX) $(LXXFLAGS) -o $(BINDIR)/$@ $^

Container.o: Container.cpp Container.hpp
    $(CXX) -c $(CXXFLAGS) -o $(OBJDIR)/$@ $<

我第一次运行make时,“release”目标将在当前文件夹中以及$(OBJDIR)中搜索“Container.o”。如果找不到它,将正确执行secong目标,在正确的文件夹中生成目标文件。然后执行“释放”目标,但链接器会抱怨找不到“Container.o”......

第二次运行make时,“release”目标将搜索“Container.o”并在$(OBJDIR)中找到它。然后链接器将正确执行(找到“Container.o”的路径前置于文件名)。

有没有办法让它一次通过?它让我发疯了!

1 个答案:

答案 0 :(得分:0)

Make确实有一个很长的学习曲线,你正在尝试一些棘手的事情(而且它正在进入Make的一大弱点,差的通配符处理)。我不确定我的回答会不会引起混淆,但至少它会解决你的具体问题。

如果您想使用CONFIG方法,可以这样做:

CONFIG = release
#CONFIG = debug                                                                 

OBJS = Container.o

TRUE_OBJS = $(addprefix obj/$(CONFIG)/, $(OBJS))

vpath %.cpp src

.PHONY: $(CONFIG)

$(CONFIG): bin/$(CONFIG)/$(CONFIG)

bin/$(CONFIG)/$(CONFIG): $(TRUE_OBJS)
    $(CXX) $(LXXFLAGS) -o $@ $^                                               

$(TRUE_OBJS): obj/$(CONFIG)/%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) -o $@ $<

但是你可以不用它(并且在你想要改变配置的时候没有编辑makefile的烦恼):

OBJS = Container.o

vpath %.cpp src

.PHONY: release debug

release: bin/release/release
debug: bin/debug/debug

bin/release/release: $(addprefix obj/release/, $(OBJS))
bin/debug/debug: $(addprefix obj/debug/, $(OBJS))

bin/release/release bin/debug/debug:
    $(CXX) $(LXXFLAGS) -o $@ $^   

obj/release/%.o obj/debug/%.o: %.cpp
    $(CXX) -c $(CXXFLAGS) -o $@ $<