我想打电话给SCons的avrdude作为目标。例如,运行scons erase-device应该运行avrdude命令。
我试图通过创建调用avrdude的Builder对象并将它们添加到环境中来做到这一点。
# a string forming a base avrdude command that we can just add on to in the targets
avrdude_base = 'avrdude -p ' + env['MCU'] + ' -c ' + icspdevice
# target to erase everything--flash, EEPROM, and lock bits (but not fuse bits)
erase_dev = Builder(action = avrdude_base + ' -e')
env.Append(BUILDERS = {'EraseDevice' : erase_dev})
ed = env.EraseDevice()
eda = env.Alias('erase-device', ed)
env.AlwaysBuild(eda)
# target to write the AVR fuses and lock bits
write_fuse = Builder(action = avrdude_base + ' -U lfuse:w:' + lfuse + ':m -U hfuse:w:' + hfuse +
':m -U efuse:w:' + efuse + ':m -U lock:w:' + lockbits + ':m')
env.Append(BUILDERS = {'WriteFuses' : write_fuse})
wf = env.WriteFuses()
wfa = env.Alias('write-fuses', wf)
env.AlwaysBuild(wfa)有了这段代码,scon总是退出,说没有什么可做的。我认为这是因为,按照代码显示的方式,我不给这些构建器(env.EraseDevice()和env.WriteFuses())任何源文件;因此,SCons假定它们不需要被调用。
所以这就是我接下来要做的。我只是将一个现有的文件名传入这两个构建器中,以使scon感到高兴,尽管它并不需要。现在的问题是,不管我是想运行scons write-fuses、scons erase-flash还是其他使用avrdude的目标,scon的表现都好像我在尝试编写保险丝。例如,如果我传入的文件名是foo.hex,那么scon现在认为它必须每次运行write-fuses目标,因为scon认为‘avr杜德’应该生成一个名为foo的输出文件,但是该文件从未生成。
而且,这样做意味着我必须在擦除设备或编程保险丝位之前构建十六进制文件,这通常是不必要的。
如何在SCons中创建不需要任何输入源且不生成任何输出的目标?
谢谢!
发布于 2010-11-04 06:42:05
你说scon没有运行任何东西是正确的,因为它没有任何源可以转化为输出,但关键是scon想要生成目标,而且它不认为有什么可以构建的。
一个简单的解决方法是提供erase-device和write-fuse命令虚拟目标。这些目标文件将永远不会生成,所以如果scon确定需要构建这个目标(因为它是在命令行上指定的,或者是命令行上某个东西的依赖项),scon将始终运行适当的avrdude ...命令。
我认为Builders的使用增加了您不需要的额外复杂性。构建器很适合为目标映射创建新的源代码,但实际上不需要涉及文件。
ed = env.Command('erase.dummy', [], avrdude_base + ' -e')
ed = env.EraseDevice()
env.AlwaysBuild(ed)
env.Alias('erase-device', ed)
...顺便提一下,scons --tree=all是查看scon的计算依赖树的一种很好的方法。如果您对scon正在做什么感到困惑,那么查看依赖树可以帮助您调试模型与scon不同的地方。
https://stackoverflow.com/questions/4093843
复制相似问题