0

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 $@.sizeok ; 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.

4

1 回答 1

1

如果HEX_MAXIMUM_SIZE没有设置,Make 不应该更新sizeok文件,并且我们不应该有一个不能真正重建其目标的规则。我们应该sizeok只在重建 hex 文件时更新文件。因此$(TARGET_HEX).sizeok,让我们将其作为规则中的命令而不是$(TARGET_HEX)规则。(您没有向我们展示avr_size,所以我无法弄清楚您测量 hex 文件大小的方法,所以我将使用ls并假设您没有使用病态文件名。)

$(TARGET_HEX): %.hex : %.cpps
    # Commands to build the target file
    if [ `ls -l $@ | awk '{print $$5}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch $@.sizeok ; fi

现在我们可以添加一个条件,以防HEX_MAXIMUM_SIZE没有正确设置:

$(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 $@.sizeok 
else
    @echo Maximum Hex size is not specified. Make sure that $@ is small enough for the microcontroller\'s flash memory.
endif

编辑:

这可能需要几次迭代。替换这一行:

if [ `$(SIZE) $@ | awk 'FNR == 2 {print $$2}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch $@.sizeok ; fi

有了这个:

$(SIZE) $@ | awk 'FNR == 2 {print $$2}'

并告诉我们结果。

于 2013-06-30T12:53:33.813 回答