2014-12-09 74 views
1

我有一個Makefile,它可以從一個目錄中生成來自幾個不同Python腳本(腳本打印到stdout)的JSON。Makefile從不同目錄中的Python腳本中生成JSON

/src 
    scriptOne.py 
    scriptTwo.py 
    scriptThree.py 

哪個JSON輸出到文件夾:

/templates 
    scriptOne.json 
    scriptTwo.json 
    scriptThree.json 

我試圖進行重組,這樣,例如,每個腳本在其自己的子目錄和Makefile文件中創建JSON的模板隨之而來的子目錄如下:

/src 
    /importantTemplates 
     scriptOne.py 
    /notSoImportantTemplates 
     scriptTwo.py 
     scriptThree.py 

和輸出:

/templates 
    /importantTemplates 
     scriptOne.json 
    /notSoImportantTemplates 
     scriptTwo.json 
     scriptThree.json 

當前生成文件如下:

SOURCES := $(shell echo src/*.py) 
TARGETS := $(patsubst src/%.py,templates/%.json,$(SOURCES)) 

all: $(TARGETS) 

clean: 
    rm -f $(TARGETS) 

templates/%.json: src/%.py 
    python2 $< > [email protected] 

我試圖改變通配符來包括用於每行的子目錄例如/src/*/*.py,雖然我剛剛結束了以下內容:

make: Nothing to be done for `all'. 

回答

1

你想爲這個靜態模式規則(4.12 Static Pattern Rules)。

SOURCES := $(wildcard src/*/*.py) 
TARGETS := $(patsubst src/%.py,templates/%.json,$(SOURCES)) 

all: $(TARGETS) 

clean: 
     rm -rf templates 

$(TARGETS) : templates/%.json: src/%.py 
     mkdir -p $(@D) 
     python2 $< > [email protected] 

你可能避免在規則體需要mkdir -p,如果你想(和一起去的順序,唯一的先決條件上的目錄,而不是),但我不知道這種努力是值得的節約執行成本。如果您想要,可以通過組合兩條線mkdir -p $(@D) && python2 $< > [email protected]來避免多餘的外殼。

+0

工作完美,謝謝! – cejast 2014-12-09 14:53:44

1

請注意,您運行make第二次,它會給你的消息(如果沒有新的文件):

make: Nothing to be done for `all'. 

嘗試運行make clean並查看是否收到相同的消息。

這裏是Makefile文件,將你想要做什麼:

SOURCES := $(wildcard src/*/*.py) 
TARGETS := $(patsubst src/%.py,templates/%.json,$(SOURCES)) 
FOLDERS := $(sort $(dir $(TARGETS))) 

all: $(TARGETS) 

clean: 
    rm -rf $(TARGETS) $(FOLDERS) 

$(FOLDERS): 
    mkdir -p [email protected] 

$(TARGETS): $(SOURCES) $(FOLDERS) 
    python2 $< > [email protected] 

文件夾變量將包含你需要在模板目錄下創建的文件夾。 (排序將刪除重複項,所以每個文件夾將只出現一次)

$(FOLDERS)規則將創建文件夾。 乾淨的規則也會刪除文件夾。

如果您需要添加更多的來源,只是做這樣的:

SOURCES := $(wildcard src/*/*.py) 
SOURCES += $(wildcard src/*.py) 
...  
+0

'$(FOLDERS)'應該是一個訂單唯一的先決條件,因此您可以從'mkdir'命令中刪除'-p'標誌。 'rm -rf'應該是'$(RM)-r'。 '$(patsubst src /%.py,templates /%.json,$(SOURCES))'可能是'$(SOURCES:src /%.py = templates /%.json)''。 'SOURCES'可以使用'$(shell find ...)'。 – Chnossos 2014-12-09 13:29:18

+0

@Chnossos爲什麼你會推薦'$(shell)'over'$(wildcard)'?乾淨目標上的'-f'意味着它永遠不會失敗(否則它會在連續運行兩次時失敗)。 – 2014-12-09 13:43:48

+0

這使得每個輸出json文件都依賴於*每個*輸入python文件。你需要一個靜態模式規則而不是'$(TARGETS):$(SOURCES)'規則。 '$(TARGETS):templates /%.json:src /%.py'或類似的東西。 – 2014-12-09 13:52:40