如何向make
传达脚本可以有条件地修改文件,以便make
等待stat
所有文件,直到该脚本完成运行?
考虑以下玩具示例系列文件:
// version
2
// foo.h - note the space between the 1 and the semicolon
static constexpr int VERSION = 1 ;
//update.py
import sys
with open(sys.argv[1]) as f:
cur = int(f.readlines()[0].split()[5])
with open('version') as f:
exp = int(f.readlines()[0].strip())
if cur < exp:
with open(sys.argv[1], 'w') as f:
print >> f, 'static constexpr int VERSION = {} ;'.format(exp)
// main.cxx
#include "foo.h"
#include <iostream>
int main() {
std::cout << VERSION << std::endl;
}
// makefile
all : a.out updater
a.out : main.o
g++ -o a.out main.o
main.o : main.cxx
g++ -std=c++11 -o main.o -c main.cxx -MP -MMD -MF main.d
.PHONY : updater
updater :
python update.py foo.h
-include main.d
这里的意图是我有一个文件foo.h
,它由脚本update.py
有条件地更新(如果你增加{{1}中的数字},version
将被更新 - 否则什么都不会发生。我想以某种方式将这一概念传达给foo.h
- 为了确定是否需要重新make
直到stat
,我才会foo.h
main.o
完成运行。我如何确保订购?
注意:update.py
这里只是一个占位符,表示一系列不易表达的复杂先决条件。简单地添加version
不是解决方案。
答案 0 :(得分:2)
如果您希望仅当脚本修改main.o
时重建a.out
和foo.h
,这可能是递归Make:
all : updater
@$(MAKE) a.out
...
main.o : main.cxx foo.h
...
答案 1 :(得分:1)
首先,如果您不希望make更新main.o
等,直到foo.h
更新后,您必须列出foo.h
作为先决条件:
main.o : main.cxx foo.h
g++ -std=c++11 -o main.o -c main.cxx -MP -MMD -MF main.d
(虽然我当然不会这样写,但我总是会使用这样的变量:
CXX = g++
CXXFLAGS = -std=c++11
DEPFLAGS = -MP -MMD -MF $*.d
main.o : main.cxx foo.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEPFLAGS) -o $@ -c $<
但那是我......)
其次,您必须有一条规则来更新foo.h
。正如你的建议,它应该是.PHONY
所以它总是运行,即使它并不总是更新foo.h
:
.PHONY: updater
updater:
python update.py foo.h
现在您必须连接这两个规则,因此您必须创建一个将foo.h
链接到updater
的规则:
foo.h : updater ;
请注意这里的分号,即 critical 。它的工作方式是这样的:updater
是虚假的,所以它总是会运行,这意味着依赖它的任何目标都会一直运行。很明显,您无法列出main.o : main.cxx updater
,因为每次都会重建main.o
。
因此,您可以引入一个中间规则foo.h : updater
。无论如何,您需要这样做,因为您需要列出foo.h
作为先决条件,因此您需要一个目标来构建它。
然而,这本身并没有帮助,因为make看到没有构建foo.h
的方法,所以它没有意识到在updater
运行时它构建了foo.h
。你可以通过为foo.h
创建一个空配方来解决这个问题。这就是;
的用途:
foo.h : updater ;
为此目标foo.h
创建一个空配方,这足以让make检查文件foo.h
是否已被修改。修改后(updater
),然后重建main.o
。如果未修改main.o
,则不会重建//Provisional value
int hi_score = INT_MIN;//#include <limits.h>
int selectIndex = -1;
for(i = 0; i < nNumbers; i++){
int dupCount = 0;
if(selectIndex != -1 && array[selectIndex] == array[i])
continue;//skip because It has already been calculated
for(j = 0; j < nNumbers; j++){//Examine all because unsorted
if((array[i] == array[j]))
++dupCount;
}
if(dupCount > 1){// need ?
int score = dupCount * dupCount * dupCount * array[i];
if(hi_score <= score){
hi_score = score;
selectIndex = i;
}
}
}
if(selectIndex != -1)
printf("%d\n", array[selectIndex]);
(除非有其他原因需要重建)。