2012-12-14 166 views
1

我有一個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上。

回答

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來顯示有關目標的信息。

+0

我不明白你的第一句話,你能澄清一下嗎? 「如果你可以接受一個高度GNU特定的makefile(我認爲使用便攜式make比GNU更好,而不是寫入便攜式makefile),」 – jippie

+0

這個答案包含一個makefile,它只能在GNU make。從這個意義上說,它不是「便攜」的。我也在說這不一定是件壞事,因爲不是編寫一個可移植的makefile,最好定位一個可移植的'make'程序。見[保羅的製造規則](http://mad-scientist.net/make/rules.html)中的第一個條目。 – Idelic

1

我會做:make flashmake hfusemake all與下面的Makefile:

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 [email protected]:r:./$(avrType).$$memory.hex:i || rm ./$(avrType)[email protected]; 

這可能是不可移植作,但它在GNU工程化妝。這不允許任何其他規則,但您可以將此文件命名爲read並執行make -f read flash。這將允許其他規則放置在其他make文件中。

請注意,這不是特別安全,因爲它會在make foo上運行avrdude。爲了更好地控制目標,你可以這樣做:

.SUFFIXES: .ph 
.PHONY: efuse.ph eeprom.ph ... 
all: efuse eeprom ... 
.ph: 
     avrdude ... 

這樣,只有列爲PHONY的目標纔是有效的目標。

+0

這絕對不是可移植的:任何包含'%'的目標的行爲都是實現定義的。 –

+0

Thnx。問題在於,我在Makefile中實際上存在少數其他規則,爲了便於閱讀,我忽略了這些規則。我用那個更新了這個問題。我真的很想將所有規則放在一個Makefile中。 – jippie

+0

就可移植性而言,'for'循環也不是非常便攜的; o)我希望能夠使它在同一時間更具便攜性。 – jippie

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 LIST="eeprom efuse"只是兩個模塊。