2014-12-09 48 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

相关问题