Выполнение команд avrdude в качестве целей SCons
Я хочу иметь возможность вызывать avrdude из SCons в качестве цели. Например, бег scons erase-device
для этого следует запустить команду avrdude.
Я пытаюсь сделать это, создав объекты Builder, которые вызывают avrdude, и добавив их в среду.
# 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)
С этим кодом scons всегда выходит, говоря, что делать нечего. Я думаю, что это потому, что, как показано на рисунке, я не даю исходные файлы для этих строителей (env.EraseDevice()
а также env.WriteFuses()
); поэтому SCons предполагает, что их не нужно называть.
Вот что я попробовал дальше. Я только что передал существующее имя файла этим двум строителям, чтобы сделать счастливыми сыновей, хотя это и не нужно. Проблема в том, что независимо от того, хочу ли я запустить scons write-fuses
, scons erase-flash
или другие цели, которые используют avrdude, scons действует так, как будто я пытаюсь написать предохранители. Если, например, имя файла, которое я передал, было foo.hex, то scons теперь думает, что он должен запустить write-fuses
target каждый раз, потому что scons считает, что 'avrdude' должен был генерировать выходной файл с именем foo, но этот файл никогда не генерируется.
Кроме того, выполнение этого означает, что мне нужно создать шестнадцатеричный файл перед стиранием устройства или программированием битов предохранителей, что обычно не требуется.
Как я могу создать цели в SCons, которые не требуют каких-либо источников для ввода и которые не генерируют никакого вывода?
Спасибо!
1 ответ
Вы на правильном пути, когда говорите, что scons ничего не запускает, потому что у него нет источников, которые можно превратить в выходные данные, но суть в том, что scons хочет создавать цели, и он не думал, что есть какие-то,
Один простой обходной путь - дать erase-device
а также write-fuse
командует фиктивными целями. Эти целевые файлы никогда не будут сгенерированы, поэтому, если scons определит, что эта цель должна быть построена (потому что она была указана в командной строке или является зависимостью чего-либо в командной строке), scons всегда будет запускать соответствующий avrdude ...
команда.
Я думаю, что использование Builders добавляет дополнительную сложность, которая вам не нужна. Сборщики хороши для создания новых сопоставлений исходного и целевого, но вам не нужно задействовать файлы.
ed = env.Command('erase.dummy', [], avrdude_base + ' -e')
ed = env.EraseDevice()
env.AlwaysBuild(ed)
env.Alias('erase-device', ed)
...
Как примечание стороны, scons --tree=all
хороший способ увидеть вычисленное дерево зависимостей scons Если вы озадачены тем, что делают scons, просмотр дерева зависимостей может помочь в отладке, когда ваша модель отличается от scons.