2013-06-30 8 views
0

Я поддерживаю довольно сложный makefile for Arduino.Динамические условия в makefile

В make-файле у меня есть цель построить файл *.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 [email protected] 
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 запускается в первый раз, я получаю ошибку о том, что шестнадцатеричный файл не существует.

После некоторой отладки я обнаружил, что makefile сначала проходит весь файл перед его выполнением. Когда он выполняет этот начальный проход, шестнадцатеричный файл еще не создан, и поэтому инструкции, выполняющие разбор шестнадцатеричного файла, вообще не выполняются.

Есть ли способ, с помощью которого я добавляю динамические условия в make-файле, чтобы я мог найти размер только что сгенерированного шестнадцатеричного файла?

Edit:

на основе предположения @beta «ы я изменил код

$(OBJDIR)/%.hex: $(OBJDIR)/%.elf $(COMMON_DEPS) 
    $(OBJCOPY) -O ihex -R .eeprom $< [email protected] 
    @$(ECHO) 
    $(call avr_size,$<,[email protected]) 
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),) 
    if [ `$(SIZE) [email protected] | 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 

и она работает. Но есть одна небольшая проблема.

В приведенном выше коде я использую переменную, определенную в make-файле $(SIZE). Но когда этот скрипт оболочки выполняется, значение не заменяется. Вместо этого он просто заменяет его пустым значением.

Он работает, если я жестко задал значение, но я не могу использовать значение переменной, определенной в make-файле. Можно ли получить к нему доступ?

Edit2:

Я разместил separate question для переменного вопроса расширения.

+0

Re: ваш последний вопрос: поскольку вы не показываете, как установлен SIZE, мы не можем помочь вам. – MadScientist

+0

@MadScientist Я опубликовал [отдельный вопрос] (http://stackoverflow.com/q/17398980/24949) об этом и дал более подробную информацию о том, как установлена ​​переменная '$ (SIZE). – Sudar

ответ

1

Если HEX_MAXIMUM_SIZE не был установлен, Make не должен обновлять файл sizeok, и у нас не должно быть правила, которое не может фактически перестроить его цель. И мы должны обновить файл sizeok только после того, как мы перестроим шестнадцатеричный файл. Поэтому вместо правила для $(TARGET_HEX).sizeok, давайте просто сделаем его командой в правиле $(TARGET_HEX). (Вы не показали нам avr_size, поэтому я не могу определить ваш метод измерения размера шестнадцатеричного файла, поэтому я просто использую ls и предполагаю, что вы не используете имена патологических файлов.)

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

Теперь мы можем добавить условие, в случае HEX_MAXIMUM_SIZE не был установлен правильно:

$(TARGET_HEX): %.hex : %.cpps 
    # Commands to build the target file 
ifneq ($(strip $(HEX_MAXIMUM_SIZE)),1) 
    if [ `ls -l [email protected] | awk '{print $$5}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch [email protected] 
else 
    @echo Maximum Hex size is not specified. Make sure that [email protected] is small enough for the microcontroller\'s flash memory. 
endif 

EDIT:

Это может занять несколько итераций. Заменить строку:

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

с этим:

$(SIZE) [email protected] | awk 'FNR == 2 {print $$2}' 

и сказать нам результат.

+0

'$ (РАЗМЕР) $ @ | awk 'FNR == 2 {print $$ 2}' 'печатает правильное значение (1121) – Sudar

+0

Ваш исходный код работает, ожидайте, что' $ (SIZE) 'не будет расширяться. Я обновил вопрос. – Sudar

+0

@ Судар: Это странно, но это другой вопрос. Какую версию Make вы используете и какую ОС? – Beta

Смежные вопросы