我有一个像这样的Makefile:
baud=19200
src=dimmer
avrType=attiny13
programmerDev=/dev/ttyUSB003
programmerType=stk500v1
object:
avr-gcc -g -DF_CPU=$(avrFreq) -Wall -Os -mmcu=$(avrType) -c -o $(src).o $(src).cpp
read:
@for memory in calibration eeprom efuse flash fuse hfuse lfuse lock signature application apptable boot prodsig usersig; do \
avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
done
哪个有效。当我输入make read
时,会从微控制器中提取几个文件。由于连接速度慢和数据大小,这可能需要一段时间,因此我认为能够只键入make read flash
会很好,但我无法弄清楚如何做到这一点。
当然我可以输入read_flash
,read_hfuse
这样的条目...但我觉得它可以做得更聪明。
我还希望能够运行像make read all
这样的命令,它将从控制器依次执行每个文件。
现在我是创建Makfile的新手,所以也许我一起走错了轨道。请随时解释如何完成。
我在Linux上。
答案 0 :(得分:2)
如果您可以接受高度特定于GNU的makefile(并且我认为使用可移植的make
(例如GNU)比编写可移植的makefile更好),您可以相当容易地实现它:
ALL = calibration eeprom efuse flash fuse hfuse lfuse lock signature \
application apptable boot prodsig usersig
ifeq (read,$(firstword $(MAKECMDGOALS)))
WANT := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
ifneq ($(WANT),)
$(eval $(WANT):;@:)
endif
UNKNOWN := $(filter-out $(ALL),$(WANT))
ifneq ($(UNKNOWN),)
$(error Invalid arguments: $(UNKNOWN))
endif
endif
read-one = avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) \
-b$(baud) -v -U $1:r:./$(avrType).$1.hex:i
.PHONY: read
read:
$(foreach w,$(or $(WANT),$(ALL)),$(call read-one,$w) &&) :
如果命令行中的第一个参数是“read”,则会将WANT
变量设置为第一个参数之后的参数列表。然后,它将这些名称转换为无操作目标,并使read
目标为每个名称调用read-one
函数,或者如果未指定名称则调用$(ALL)
。
我会经常使用此类变体,例如make print VARIABLE...
,只会打印$(VARIABLE)
或make help TOPIC
来显示有关目标的信息。
答案 1 :(得分:1)
我会使用以下Makefile执行:make flash
或make hfuse
或make all
:
baud=19200
avrType=attiny13
programmerDev=/dev/ttyUSB003
programmerType=stk500v1
all: calibration eeprom efuse flash fuse hfuse lfuse lock signature \
application apptable boot prodsig usersig
%:
avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) \
-v -U $@:r:./$(avrType).$$memory.hex:i || rm ./$(avrType).$@.hex;
这可能不是便携式Make,但它适用于gnu make。这不允许任何其他规则,但您可以将此文件命名为read
并执行make -f read flash
。这样就可以将其他规则放在其他make文件中。
请注意,这不是特别安全,因为它会在make foo
上运行avrdude。要更严格地控制目标,您可以:
.SUFFIXES: .ph
.PHONY: efuse.ph eeprom.ph ...
all: efuse eeprom ...
.ph:
avrdude ...
这样,只有列为PHONY的目标才是有效目标。
答案 2 :(得分:1)
如何使模块列表成为具有默认值的可配置列表:
LIST = calibration eeprom efuse flash fuse \
hfuse lfuse lock signature application \
apptable boot prodsig usersig
read:
@for memory in $(LIST); do \
avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) \
-b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
done
然后调用make作为make
作为默认值,或调用make LIST="eeprom efuse"
作为两个模块。