If someone else built and marked one of our dependencies, then that dependency would show up as *clean* in a later redo-ifchange, so other dependents of that file wouldn't be rebuilt. We actually have to track two session-specific variables: whether the file has been checked, and whether it was rebuilt. (Or alternatively, whether it was dirty when we checked it the first time. But we store the former.)
74 lines
1.9 KiB
Python
Executable file
74 lines
1.9 KiB
Python
Executable file
#!/usr/bin/python
|
|
import sys, os, errno
|
|
import vars, state, builder
|
|
from helpers import debug, err, mkdirp, unlink
|
|
|
|
|
|
def _dirty_deps(t, depth, fromdir):
|
|
debug('%s?%s\n' % (depth, t))
|
|
if state.isbuilt(t, fromdir):
|
|
debug('%s-- DIRTY (built)\n' % depth)
|
|
return True # has already been built during this session
|
|
if state.ismarked(t, fromdir):
|
|
debug('%s-- CLEAN (marked)\n' % depth)
|
|
return False # has already been checked during this session
|
|
|
|
stamptime = state.stamped(t, fromdir)
|
|
if stamptime == None:
|
|
debug('%s-- DIRTY (no stamp)\n' % depth)
|
|
return True
|
|
|
|
try:
|
|
realtime = os.stat(os.path.join(fromdir or '', t)).st_mtime
|
|
except OSError:
|
|
realtime = 0
|
|
|
|
if stamptime != realtime:
|
|
debug('%s-- DIRTY (mtime)\n' % depth)
|
|
return True
|
|
|
|
for mode,name in state.deps(t, fromdir):
|
|
if mode == 'c':
|
|
if os.path.exists(name):
|
|
debug('%s-- DIRTY (created)\n' % depth)
|
|
return True
|
|
elif mode == 'm':
|
|
if dirty_deps(name, depth + ' ', fromdir=vars.BASE):
|
|
debug('%s-- DIRTY (sub)\n' % depth)
|
|
return True
|
|
state.mark(t, fromdir)
|
|
return False
|
|
|
|
|
|
def dirty_deps(t, depth, fromdir=None):
|
|
if _dirty_deps(t, depth, fromdir):
|
|
state.unstamp(t, fromdir)
|
|
return True
|
|
return False
|
|
|
|
|
|
def should_build(t):
|
|
return not state.isbuilt(t) and dirty_deps(t, depth = '')
|
|
|
|
|
|
def maybe_build(t):
|
|
if should_build(t):
|
|
builder.build(t)
|
|
|
|
|
|
if not vars.TARGET:
|
|
err('redo-ifchange: error: must be run from inside a .do\n')
|
|
sys.exit(100)
|
|
|
|
rv = 202
|
|
try:
|
|
want_build = []
|
|
for t in sys.argv[1:]:
|
|
state.add_dep(vars.TARGET, 'm', t)
|
|
if should_build(t):
|
|
want_build.append(t)
|
|
|
|
rv = builder.main(want_build, maybe_build)
|
|
except KeyboardInterrupt:
|
|
sys.exit(200)
|
|
sys.exit(rv)
|