Как перейти в подкаталоги с помощью пользовательского правила, используя automake и autotools

Вопрос или проблема

Я пытаюсь создать простой проект, чтобы изучить autotools и automake. У меня есть подкаталог под названием Atmega-lib, который собирает статическую библиотеку под названием libatmega328p.a. Проблема, с которой я сталкиваюсь, заключается в том, что когда я запускаю make flash, я получаю следующее сообщение:

make: *** No rule to make target 'Atmega-lib/libatmega328p.a', needed by 'atmega'.  Stop.

Но запуск make сначала, а затем make flash работает. Как я могу сделать так, чтобы запуск только make flash собирал все, а затем пытался выполнить правило?

Вот мой Makefile:

SUBDIRS = Atmega-lib

#SUBDIRS = Atmega-lib
AM_CFLAGS = -I$(SUBDIRS)/include -Wall -Wextra -std=c89 -g -Wpadded -Wconversion -fno-common -mmcu=atmega328p -Wl,--gc-sections -Wshadow -Wdouble-promotion -Wundef
# -nostdlib 

OUTPUT_HEX = atmega328p.hex

bin_PROGRAMS = atmega
atmega_LDADD = Atmega-lib/libatmega328p.a
atmega_SOURCES = main.c

# Добавьте пользовательскую цель для прошивки
flash: atmega Atmega-lib/libatmega328p.a
    @echo "Прошивка ATmega328P..."
    avrdude -F -V -p m328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:$(OUTPUT_HEX):i

# Правило для создания hex файла с использованием avr-objcopy
$(OUTPUT_HEX): atmega
    avr-objcopy -O ihex -R .eeprom $< $(OUTPUT_HEX)

Вещь, которую мне нужно сказать automake, – это сначала запустить SUBDIRS перед сборкой программы atmega, точно так же, как это происходит при запуске make отдельно, но я не знаю, как это сделать.

РЕДАКТИРОВАТЬ:

Я добавил эту строку сразу после правила flash, и это сработало. Было ли это правильным способом решения моей проблемы?

# Добавьте пользовательскую цель для прошивки
flash:
    $(MAKE)
    @echo "Прошивка ATmega328P..."
    avrdude -F -V -p m328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:$(OUTPUT_HEX):i

Спасибо заранее!

Ответ или решение

Чтобы решить проблему с зависимостями в вашем проекте, использующем Automake и Autotools, вам нужно убедиться, что при вызове make flash сначала собираются все необходимые сайты, включая создание статической библиотеки libatmega328p.a в каталоге Atmega-lib. Это можно сделать, добавив несколько дополнительных правил в ваш файл Makefile.am.

1. Основная проблема

Как вы заметили, при вызове команды make flash возникает ошибка, потому что Make не знает, что необходимо сначала построить подкаталог Atmega-lib. Ваша правка, которая добавляет вызов $(MAKE) в целевой flash, решает проблему, однако это не самое элегантное и правильное решение с точки зрения архитектуры Makefile. Использование $(MAKE) для рекурсивного вызова может привести к потенциальным проблемам и не всегда является оптимальным.

2. Рекомендуемое решение

Чтобы правильно настроить ваш Makefile так, чтобы сначала выполнялась сборка подкаталогов, вы можете использовать следующий подход:

SUBDIRS = Atmega-lib

AM_CFLAGS = -I$(SUBDIRS)/include -Wall -Wextra -std=c89 -g -Wpadded -Wconversion -fno-common -mmcu=atmega328p -Wl,--gc-sections -Wshadow -Wdouble-promotion -Wundef

OUTPUT_HEX = atmega328p.hex

bin_PROGRAMS = atmega
atmega_LDADD = Atmega-lib/libatmega328p.a
atmega_SOURCES = main.c

# Описание ваших выходных файлов
$(OUTPUT_HEX): atmega
    avr-objcopy -O ihex -R .eeprom $< $(OUTPUT_HEX)

# Расширенное правило для флешинга
flash: $(OUTPUT_HEX)
    @echo "Flashing the ATmega328P..."
    avrdude -F -V -p m328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:$(OUTPUT_HEX):i

# Убедитесь, что правила для подкаталогов выполняются перед построением программы
.PHONY: all flash
all: $(subdir-objects)

3. Объяснение изменений:

  • flash как зависимость от OUTPUT_HEX: Теперь цель flash зависит от $(OUTPUT_HEX), которое, в свою очередь, зависит от atmega. Это значит, что при выполнении make flash, Make будет знать, что ему нужно сначала собрать все зависимости.

  • Использование .PHONY: добавленный .PHONY позволяет сделать цели all и flash явными для Make, что улучшает читаемость и поддержку Makefile.

  • Встраивание всех правил в логическую структуру: Это способствует лучшему пониманию и поддержанию вашего Makefile. Теперь стоит ожидать, что, когда вы выполняете make flash, он правильно пройдет цепочку зависимости и соберет все необходимые файлы.

Заключение

Ваше первоначальное решение для вызова $(MAKE) в целевой flash — это ненадежный способ улучшающего процесса, и конструкция выше обеспечит более правильный и управляемый подход. Этот метод более декларативный и позволяет избежать неопределенных состояний в будущем, когда вы будете вносить изменения в проект или добавлять новые зависимости.

Оцените материал
Добавить комментарий

Капча загружается...