Reputation: 19992
I maintain a fairly complex makefile for Arduino.
In the makefile, I have target to build *.hex
file from *.cpp
file. After the *.hex
file is generated, I want to check whether the hex size of the file is less than the flash memory of the microcontroller.
To do that, I have added another target called verify_size
which touches a *.sizeok
file if the hex size is less.
Following is the relevant code
$(TARGET_HEX).sizeok: $(TARGET_HEX)
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),1)
ifeq ($(shell expr `$(call avr_size,$(TARGET_HEX)) | grep Program | awk '{print $$2}'` '<' $(HEX_MAXIMUM_SIZE)), 1)
touch $@
endif
else
@$(ECHO) Maximum Hex size is not specified. Make sure the hex file that you are going to upload is less than microcontrollers flash memory
endif
verify_size: $(TARGET_HEX) $(TARGET_HEX).sizeok
The problem I am facing is that when the makefile is run for the very first time, I get a error saying that the hex file doesn't exist.
After some debugging I found that makefile first goes through the entire file before executing it. When it does this initial pass, the hex file not created yet and therefore the statements which does the parsing of hex file is not executed at all.
Is there a way by which I add dynamic conditions in makefile so that I can find the size of the hex file that was just generated?
Edit:
Based on @beta 's suggestion I changed the code to
$(OBJDIR)/%.hex: $(OBJDIR)/%.elf $(COMMON_DEPS)
$(OBJCOPY) -O ihex -R .eeprom $< $@
@$(ECHO)
$(call avr_size,$<,$@)
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),)
if [ `$(SIZE) $@ | awk 'FNR == 2 {print $$2}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch [email protected] ; fi
else
@$(ECHO) Maximum Hex size is not specified. Make sure the hex file that you are going to upload is less than microcontrollers flash memory
endif
and it is working. But there is one small issue though.
In the above code, I am using a variable defined in makefile $(SIZE)
. But when this shell script executes, the value is not replaced. Instead it just replaces it with an empty value.
It works if I hardcode the value, but I am not able to use the value of the variable defined in makefile. Is it possible to access it?
Edit2:
I have posted a separate question for variable expansion issue.
Upvotes: 0
Views: 1327
Reputation: 99094
If HEX_MAXIMUM_SIZE
hasn't been set, Make should not update the sizeok
file, and we shouldn't have a rule that can't actually rebuild its target. And we should update the sizeok
file only when we rebuild the hex file. So instead of a rule for $(TARGET_HEX).sizeok
, let's just make it a command within the $(TARGET_HEX)
rule. (You haven't shown us avr_size
, so I can't figure out your method for measuring the size of the hex file, so I'll just use ls
and assume you aren't using pathological file names.)
$(TARGET_HEX): %.hex : %.cpps
# Commands to build the target file
if [ `ls -l $@ | awk '{print $$5}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch [email protected] ; fi
Now we can add a condition, in case HEX_MAXIMUM_SIZE
hasn't been set correctly:
$(TARGET_HEX): %.hex : %.cpps
# Commands to build the target file
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),1)
if [ `ls -l $@ | awk '{print $$5}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch [email protected]
else
@echo Maximum Hex size is not specified. Make sure that $@ is small enough for the microcontroller\'s flash memory.
endif
EDIT:
This may take a few iterations. Replace this line:
if [ `$(SIZE) $@ | awk 'FNR == 2 {print $$2}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch [email protected] ; fi
with this:
$(SIZE) $@ | awk 'FNR == 2 {print $$2}'
and tell us the result.
Upvotes: 1