在我的项目中,所有.cpp文件都存储在

Classes/
Classes/Something/
Classes/Something/Else
...


我想将所有.cpp文件分别编译到Bin /目录,用_替换/,以便:

Classes/First.cpp -> Bin/Classes_First.o
Classes/Foo/Bar.cpp -> Bin/Classes_Foo_Bar.o


现在,我想创建用于编译的规则:

Bin/%.o: $(subst _,/,%.cpp)
    $(COMPILER)g++ $(COMPILE_FLAGS) -c -o $@ $^


我试过了:

制作Bin / Classes_Test.o

但是编译失败。

所以我创建了调试模式:

%.cpp:
    @echo CPP: $@


现在打印:

CPP: Classes_Test.cpp


为什么?!

因此,我将模式更改为:

Bin/%.o: $(subst _,/,Test1_Test2.cpp)


我看到:

CPP: Test1/Test2.cpp


我有些困惑,如果我使用通配符作为源,那么为什么subst不起作用...

最佳答案

这是评估订单问题。

当make解析makefile时,它将评估$(subst)调用,但是$(subst)的参数此时为文字字符串%.cpp,其中没有替代内容,因此不会执行任何操作。

在目标评估/执行时,填充了目标模式和prereq模式中的%,但$(subst)早已消失。

为此,您将需要手动(以一种或另一种方式)将输出文件映射到输入文件。您可以执行此操作,并保留%.o模式规则目标以使实际配方运行(因此,您只需要生成一堆Bin/Test1_Test2.o: Test1/Test2.cpp行)即可。

另外,我相信您可以使用secondary expansion来做到这一点:

.SECONDEXPANSION:
Bin/%.o: $$(subst _,/,%.cpp)

07-24 09:44