传递一个额外的参数来制作

时间:2012-12-14 18:29:43

标签: linux makefile

我有一个像这样的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_flashread_hfuse这样的条目...但我觉得它可以做得更聪明。

我还希望能够运行像make read all这样的命令,它将从控制器依次执行每个文件。

现在我是创建Makfile的新手,所以也许我一起走错了轨道。请随时解释如何完成。

我在Linux上。

3 个答案:

答案 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 flashmake hfusemake 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"作为两个模块。