makefile中的动态条件

时间:2013-06-30 10:12:03

标签: makefile gnu-make

我保持相当复杂的makefile for Arduino

在makefile中,我有从*.hex文件构建*.cpp文件的目标。生成*.hex文件后,我想检查文件的十六进制大小是否小于微控制器的闪存。

为此,我添加了另一个名为verify_size的目标,如果十六进制大小较小,则触及*.sizeok文件。

以下是相关代码

$(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

我面临的问题是,当makefile第一次运行时,我收到一条错误,指出hex文件不存在。

经过一些调试后,我发现makefile在执行之前首先遍历整个文件。当它执行此初始传递时,尚未创建hex文件,因此根本不执行解析hex文件的语句。

有没有办法在makefile中添加动态条件,以便找到刚刚生成的hex文件的大小?

修改

根据@beta的建议,我将代码更改为

$(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

它正在发挥作用。但是有一个小问题。

在上面的代码中,我使用的是makefile $(SIZE)中定义的变量。但是当执行此shell脚本时,不会替换该值。相反,它只是用空值替换它。

如果我对值进行硬编码,它会起作用,但我无法使用makefile中定义的变量的值。是否可以访问它?

EDIT2

我已针对变量扩展问题发布separate question

1 个答案:

答案 0 :(得分:1)

如果尚未设置HEX_MAXIMUM_SIZE,则Make不应更新sizeok文件,并且我们不应该有一条实际上无法重建其目标的规则。我们只有在重建hex文件时才应更新sizeok文件。因此,不要使用$(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}'

告诉我们结果。