2011-08-23 94 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))))