2011-08-23 61 views
0

想象我有这样的:是否支持这种流程?

PROJECT1 := /path/to/first 
PROJECT2 := /path/to/second 
PROJECT3 := /path/to/third 

我做一个查找从里面他们收集所有c,cpp,h文件。我有类似:

PROJECT1_CPP := $(shell find $(PROJECT1) -name "*.cpp" -type "f") 
PROJECT1_C := ... (the same happens for PROJECT2 and PROJECT3) 

现在,我可以添加目标为他们每个人都喜欢:

project1.lib: $(PROJECT1_OBJS) 
    ... 

project2.lib: $(PROJECT2_OBJS) 
    ... 

project3.lib: $(PROJECT3_OBJS) 
    ... 

这种方法的事情是:有很多的重复代码(所有的动作为所有的构建几乎相同)。我希望能够做一些更通用的,如:

PROJECTS := /path/to/first 
PROJECTS += /path/to/second 
PROJECTS += /path/to/third 

然后以某种方式遍历它们并构建它们。事情是这样的伪代码:

foreach project in PROJECTS 
    gather C/C++ files 
    build them 
    link them 

link everything together 

你能不能给我任何指标,让我应该开始?在Make中这甚至可能吗?

+1

所有这些都可以完成,但是您想保留不同的'projectX.lib'吗?或者只是一个'final.lib'? –

+0

现在不同的库。我可以将它们组合成一个单一的。 – Geo

回答

1

它可以gnumake的做,我不知道其他品种。

首先,我们定义一个宏:

SOURCES = $(shell find $(1) -name "*.cpp" -type "f") 

然后我们可以把它叫做每个项目:

PROJECT1_CPP := $(call SOURCES,$(PROJECT1)) 
PROJECT2_CPP := $(call SOURCES,$(PROJECT2)) 
PROJECT3_CPP := $(call SOURCES,$(PROJECT3)) 

或者,如果有很多人(或我们懒惰):

PROJECTS := PROJECT1 PROJECT2 PROJECT3 
$(foreach proj,$(PROJECTS),$(eval $(proj)_CPP := $(call SOURCES,$($(proj))))) 

或者,如果我们真的

$(foreach proj,1 2 3,$(eval PROJECT$(proj)_CPP := $(call SOURCES,$(PROJECT$(proj))))) 

我们构建它们,而不是这样的:

project1.lib: $(PROJECT1_OBJS) 
    do something with $(PROJECT1_OBJS) 

project2.lib: $(PROJECT2_OBJS) 
    do something with $(PROJECT2_OBJS) 

project3.lib: $(PROJECT3_OBJS) 
    do something with $(PROJECT3_OBJS) 

我们改成这样:

project1.lib: $(PROJECT1_OBJS) 
    do something with $^ 

project2.lib: $(PROJECT2_OBJS) 
    do something with $^ 

project3.lib: $(PROJECT3_OBJS) 
    do something with $^ 

然后到这一点:

project1.lib: $(PROJECT1_OBJS) 

project2.lib: $(PROJECT2_OBJS) 

project3.lib: $(PROJECT3_OBJS) 

project1.lib project2.lib project3.lib 
    do something with $^ 

我们甚至可以把那到另一个$(foreach ... $(eval...)),但我们不要太过分了。

编辑:
你想过度?在你去:

PROJECT1 := /path/to/first 
PROJECT2 := /path/to/second 
PROJECT3 := /path/to/third  

all: 
     @echo linking $^ somehow 

define all_rules 
    PROJECT$(1)_CPP := $(shell find $(PROJECT$(1)) -name "*.cpp" -type "f") 

    project$(1).lib: $(PROJECT$(1)_CPP:.cpp=.o) 
     @echo making [email protected] from $$^ 

    all: project$(1).lib 
endef                    

$(foreach proj,1 2 3,$(eval $(call all_rules,$(proj)))) 

%.o: %.cpp 
    @echo making [email protected] from $< 
+0

Overboard似乎正是我需要:) – Geo

0

我会写一个脚本来生成每个项目的生成文件,执行使每个并删除它们如果一切顺利

1

您可以使用宏(define)在GNU制作和eval在飞行中添加规则。这并不容易,但它很有效。下面的代码假定项目的名称是项目所在目录的名称:

PROJECTS := /path/to/project1 /path/to/project2 

all: 
    # Do all libraries 


define def_rules 
v=$$(notdir $(1)) 
$$(v)_CPP := $$(shell find $(1) -name "*.cpp" -type "f") 
$$(v)_OBJS := $$(patsubst %.cpp,%.o,$$($$(v)_CPP)) 
$$(v).lib: $$($$(v)_OBJS) 
    lib ... $$< 
endef 

$(foreach pr,$(PROJECTS),$(eval $(call def_rules,$(pr))))