Makefile 在错误的位置进行搜索

Makefile 在错误的位置进行搜索,makefile,Makefile,我是(GNU)制作的新手,并且发现它非常困难。我考虑切换到SCons,但我仍然想理解。 我在一个文件夹中有一个makefile,其中包含子目录./src、./obj/[release | debug]和./bin[release | debug]。MaFrm文件应该能够在./Src中获取C++源代码,将它们编译成适当的.Objo目录中的对象文件,并链接这些对象文件并将结果放入适当的./bin目录中。这是我的makefile(为简单起见进行了编辑): CONFIG=release #CONFIG=

我是(GNU)制作的新手,并且发现它非常困难。我考虑切换到SCons,但我仍然想理解。

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

CONFIG=release
#CONFIG=debug
OBJS=Container.o
OBJDIR=obj/$(配置)
BINDIR=bin/$(配置)
VPATH=src$(BINDIR)
vpath%.o$(OBJDIR)
.虚假:释放
发行:$(OBJS)
$(CXX)$(LXXFLAGS)-o$(BINDIR)/$@$^
Container.o:Container.cpp Container.hpp
$(CXX)-c$(CXXFLAGS)-o$(OBJDIR)/$@$<
第一次运行make时,“release”目标将在当前文件夹中以及$(OBJDIR)中搜索“Container.o”。如果找不到,将正确执行secong目标,并在正确的文件夹中生成目标文件。然后将执行“release”目标,但链接器将抱怨找不到“Container.o”

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


有没有一种方法可以让它在一次通过中工作?它让我发疯

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 $@ $<
CONFIG=release
#CONFIG=debug
OBJS=Container.o
TRUE_OBJS=$(addprefix obj/$(CONFIG)/,$(OBJS))
vpath%.cpp src
.PHONY:$(配置)
$(配置):bin/$(配置)/$(配置)
bin/$(配置)/$(配置):$(真)
$(CXX)$(LXXFLAGS)-o$@$^
$(TRUE_OBJS):obj/$(CONFIG)/%.o:%.cpp
$(CXX)-c$(CXXFLAGS)-o$@$<
但是您可以不使用它(并且不需要在需要更改配置时编辑makefile):

OBJS=Container.o
vpath%.cpp src
.PHONY:发布调试
释放:箱子/释放/释放
调试: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$@$<

您是否尝试交换规则?首先放入Container.o规则,然后放入release规则。我明白了。本质上,您去掉了vpath%.o$(OBJDIR),并明确地将路径放在对象文件的前面?这是有道理的!谢谢还有什么方法比CONFIG更好呢?我认为上面的第二种方法比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 $@ $<
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 $@ $<