HA -- got a small repro testcase!
SConstruct: --
# This tests the too-many-rebuilds problem with SCons 2.3.1 (test)
# Run like this: scons all-defuns.obj
# Test setup (only runs once)
import os.path
if not os.path.exists('mkl'):
os.mkdir('mkl')
if not os.path.exists('test.c'):
open('test.c', 'w').write('int i;')
env=Environment()
env.SharedObject('all-defuns.obj', 'all-defuns.c')
results = env.Command('all-defuns.c', 'test.c', Copy('$TARGET', '$SOURCE'))
env.Depends(results, '#mkl')
--
Run that twice as scons all-defuns.obj. The second time _shouldn't_
rebuild anything, but it will re-run the Copy command. SCons 2.3.0
correctly doesn't do anything the second time.
Note: just running scons with the above SConstruct won't show the bug;
there's an ordering dependency here, so just scons considers the targets
in a different order from scons all-defuns.obj.
Dirk, I guess the ball's in your court! :-) Of course I want to keep
helping to solve it but at least you and interested others (hi Roberto!)
can give it a try.
I'll check in some of my new tracing code soon; it's been helpful to me so
far.
-- Gary
On Sun, Feb 2, 2014 at 3:49 PM, Gary Oberbrunner ga...@oberbrunner.comwrote:
Well, my smaller test case with just the important files works fine so
far. It's probably just _too_ small. But in the meantime I have a more
complete understanding of what's happening.
I traced through the taskmaster as all this is happening.
Note that in Taskmaster-speak, considering is prior to evaluating.
1. Taskmaster considers all-defuns.obj (This is in find_next_ready_node)
- That checks node status of all children (via target.children()
because Node.children() defaults its scan arg to 1),
including all-defuns.c and recursively the dir mkl
- mkl is in state no_state (never examined), so
it returns changed=True which means all-defuns.c has changed --
and that gets cached as the node status for all-defuns.c (incorrectly).
This happens during the get_all_children() call for all-defuns.obj.
2. Taskmaster evaluates mkl; it's actually fine and taskmaster marks
it up-to-date (in taskmaster).
3. Taskmaster evaluates all-defuns.c;
It checks node up-to-date states for children and itself
and it itself is cached as out of date (see #1 above), so it
decides to rebuild it.
Some possibilities for fixing or workarounds:
- Maybe a node changed state that relies on a no_state child should
not get cached? (This could be a little complicated to implement)
- maybe no_state shouldn't mean changed? But it probably can't
mean not changed either... would have to add a third don't know
state.
- maybe if we encounter a no_state object while checking parents it
should try to set its state? (but that would require evaluating it, and
it's too early for that)
--
Gary
--
Gary
___
Scons-dev mailing list
Scons-dev@scons.org
http://two.pairlist.net/mailman/listinfo/scons-dev