我的src
文件夹中有一个文件夹结构,我希望将其保存在我的obj
文件夹中,其中包含所有.o
个文件。我不想使用mkdir
,因为跨平台使用会出现很多问题。相反,我做了
$(OBJECTS) := $(patsubst %,obj/%,$(subst /,_,$(SOURCES)))
现在的问题是,创建这些文件的规则的输入和输出文件名是不同的,这意味着要做
$(OBJECTS): obj/%.o: %.cpp
# whatever compile command
不再有效,因为obj/Core_Graphics_Window.o
的输出示例输入为Core/Graphics/Window.cpp
。
这仍然可以吗?
答案 0 :(得分:1)
如果要使用其他名称,则不能使用隐式规则或静态模式规则。您必须为每个目标创建显式规则。为了避免手动执行此操作,您需要做一些更高级的事情,例如使用eval / call组合:
COMPILE.cxx = whatever compile command
define cxx_rule
obj/$(subst /,_,$1).o: $1.cpp
$$(COMPILE.cxx) -c -o $$@ $$<
endef
$(foreach O,$(OBJECTS),$(eval $(call cxx_rule,$(basename $O))))
请仔细注意逃脱(加倍)的美元符号。要了解有关其工作原理的更多信息,请阅读this set of blog posts。
答案 1 :(得分:0)
试试这个(因为我没有,所以它可能不起作用)
echo ${SOURCES} | tr ' ' "\n" | perl -nwle '$c = $_; s!/!_!g; print "obj/$_ : $c\n\twhatever compile command"' > rules.mk
rules.mk : ${SOURCES}
include rules.mk
如果您要将每个目标文件转储到同一目录中,我建议您忘记源中的层次结构。然后你可以写一个
obj/%.o : %.cpp
# whatever compile command
通过构建适当的VPATH来获取源代码。
答案 2 :(得分:0)
(这不是另一个答案,只是对kim366评论的解释)。
为什么$(OBJECTS):$(SOURCES)不起作用?
扩展到
a.o b.o c.o : a.c b.c c.c
compiler command
这不是一个规则,告诉你如何从a.c创建a.o,从b.c创建b.o,从c.c创建c.o
这实际上是三条规则;它相当于
a.o : a.c b.c c.c
compiler command
b.o : a.c b.c c.c
compiler command
c.o : a.c b.c c.c
compiler command
通常,您可以在(GNU)make中使用两种规则:显式规则(其中依赖项列表由手指定)和模式/后缀规则(其中推导出依赖项列表)。在这两种情况下,目标都是单个文件。实际上,make对于生成多个文件的命令很困难(源代码生成器,如lex
,yacc
,protobuf
等。
例如,您无法告诉make protoc
同时创建.cc和.h文件:
%.pb.cc %.pb.h : %.proto
protoc .... $<
这是两个单独的规则,我已经看到它在并行构建多个作业时启动两个单独的protoc
进程(使用相同的命令行)。