The Action object is confused by the cmdstr argument
This issue was originally created at: 2010-06-03 12:42:50.
This issue was reported by: marclefevre.
marclefevre said at 2010-06-03 12:42:50
I'm using SCONS version:
SCons by Steven Knight et al.:
engine: v2.0.0.alpha.20100508.r4833, 2010/05/08 14:32:19, by bdeegan on blackdog5000
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
to build a medium sized hierarchical software project in C. I'm trying to create a builder that will pack our output binary and I wanted to provide my own COMSTR equivalent. Gary O. on the mailing list suggested that I consider using the Action object.
I followed the man page and converted my original code:
bld = Builder(action = os.path.join('..', '..', 'Tools', 'packSegs') + ' $SOURCE $TARGET 0x0000 C Q')
env.Append(BUILDERS = {'Binary' : bld}
to:
binaryAction = Action([[os.path.join('..', '..', 'Tools', 'packsegs'), '$SOURCE', '$TARGET', '0x0000', 'C', 'Q']], 'Packing $TARGET')
env.Append(BUILDERS = {'Binary' : binaryAction}
and invoked with:
core0axf = env.Program('core0.axf', core0Objects + mtver)
env.Binary('dorado.bin', core0axf)
The original builder worked as desired, but the Action object-based version generated the following stack trace:
scons: Reading SConscript files ...
AttributeError: 'NodeList' object has no attribute 'subst':
File "C:\SEFA\branches\mlefevre\scons\Platform\Dorado\SConstruct", line 251:
env.Binary('dorado.bin', core0axf)
File "C:\Python26\Lib\site-packages\scons-2.0.0.alpha.20100508\SCons\Environment.py", line 258:
return MethodWrapper.__call__(self, target, source, *args, **kw)
File "C:\Python26\Lib\site-packages\scons-2.0.0.alpha.20100508\SCons\Environment.py", line 222:
return self.method(*nargs, **kwargs)
File "C:\Python26\Lib\site-packages\scons-2.0.0.alpha.20100508\SCons\Action.py", line 547:
cmd = self.strfunction(target, source, env, executor)
File "C:\Python26\Lib\site-packages\scons-2.0.0.alpha.20100508\SCons\Action.py", line 728:
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
to which Gary replied:
Hi Marc; I think you've found a bug. I tried your code and it fails for me too. I put some print stmts in Action.py, and it looks like the target and env are getting swapped around somewhere!
Substituting "Packing $TARGET"
target= [<SCons.Script.SConscript.SConsEnvironment instance at 0x0270B738>]
source= ['dorado.bin'] env= ['foo.exe']
Weird. Please submit a bug report with your testcase.
-- Gary
I'm happy to supply the SConstruct file and some SConscript files if you need them, but it'll take some work to remove intellectual property from them before I do. Let me know if you want/need them.
garyo said at 2010-06-14 20:38:10
Greg Noel found that this is actually user error. You are passing an Action object as an element of the BUILDERS dict. Only Builder objects should be in BUILDERS. To fix, do this:
bld = Builder(action=binaryAction)
env.Append(BUILDERS= {'Binary', bld})
instead. Perhaps this error can be detected and trapped, since the failure mode is pretty obtuse.
gregnoel said at 2010-06-21 11:54:51
Bug party triage. The Action needs to be converted into a Builder before trying to attach it to the Environment. Gary to add an error for this case.
So the problem in this case the user's SConscript tries to add an Action as a Builder, rather than adding a Builder which uses that action?
Given that builders are currently added by appending to the 'BUILDERS' construction var, one could add a special case in the Append code, which already has several special cases (maybe too many?). But then you haven't covered other ways of adding, like manual list appending, or AppendUnique, or .... If builders were added by calling a dedicated register method, this would be much easier to catch and warn/error about.
Open to suggestions - or we could just close as nothing reasonable we can do?