2017-07-02 84 views
0

我在我的src文件夹中有一个文件夹结构,我想将其保存在我的obj文件夹中,其中所有.o文件都包含在该文件夹中。我不想使用mkdir,因为跨平台使用会出现许多问题。相反,我做了具有不同输入和输出名称的Makefile通配符

$(OBJECTS) := $(patsubst %,obj/%,$(subst /,_,$(SOURCES))) 

现在的问题是,是创建这些文件是不同的规则,这意味着做

$(OBJECTS): obj/%.o: %.cpp 
    # whatever compile command 

不再起作用的输入和输出文件名,因为一个例子输出为obj/Core_Graphics_Window.o,输入为Core/Graphics/Window.cpp

这还能完成吗?

回答

0

试试这个(因为我没有,所以它可能无法正常工作)

  1. 收集的所有来源的列表以及它们的路径(明确或https://stackoverflow.com/a/2483203/2064196),我们姑且称之为来源。
  2. 创建依赖关系的显式列表:echo ${SOURCES} | tr ' ' "\n" | perl -nwle '$c = $_; s!/!_!g; print "obj/$_ : $c\n\twhatever compile command"' > rules.mk
  3. 制作rules.mk取决于来源:如果你倾倒在同一目录中的每个对象文件rules.mk : ${SOURCES}
  4. include rules.mk

,我建议你忘记了来源中的层次结构。然后你可以编写一个单独的

obj/%.o : %.cpp 
    # whatever compile command 

并通过构建适当的VPATH来获取源代码。

+0

事情是,我不能使用'obj /%。o:%.cpp',因为文件名是不同的; ''%'将不会相同 – kim366

+0

如果您放弃重命名对象,即Windows.cpp的目标文件是obj/Windows.o,则无论Windows.cpp位于何处,这都适用。 – Bulletmagnet

+0

呀,后来我已经重复... – kim366

1

如果您想使用不同的名称,则不能使用隐式规则或静态模式规则。您必须为每个目标创建明确的规则。为了避免手工做这个,你需要做一些票友,例如使用EVAL /调用组合:仔细

COMPILE.cxx = whatever compile command 

define cxx_rule 
obj/$(subst /,_,$1).o: $1.cpp 
     $$(COMPILE.cxx) -c -o [email protected] $$< 
endef 

$(foreach O,$(OBJECTS),$(eval $(call cxx_rule,$(basename $O)))) 

注意转义(加倍)美元符号。要了解更多关于这是如何工作的,你可以阅读this set of blog posts

+0

谢谢,我将通读它当我从学校回来时 – kim366

+0

这看起来与我的想法类似(构建一个规则列表,每个对象一个规则列表),除非它更好,因为它完全在make中。 – Bulletmagnet

0

(这不是另一个答案,只是解释kim366的评论)。

为什么$(OBJECTS):$(SOURCES)不起作用?

也扩展到

a.o b.o c.o : a.c b.c c.c 
    compiler command 

这不是告诉make如何从b.c和c.o从C.C

这其实是三个规则创建变交流a.o,B.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对于生成多个文件的命令有困难(源生成器,如lex,yaccprotobuf等)。

例如,你不能告诉做出protoc都将创建的.cc和.h文件:

%.pb.cc %.pb.h : %.proto 
    protoc .... $< 

这是两个单独的规则做出的,我已经看到了它发射两个独立的protoc进程(使用相同的命令行)并行构建多个作业时。

+0

好吧,不可能有不同的文件'%'中的名字? – kim366

+0

不,不管''''在一侧是否匹配,相同的东西将在另一侧替代。 – Bulletmagnet

+0

并且我没有可能做我想要的东西? – kim366

相关问题