我正在尝试构建一个简单的项目来学习 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
# Add a custom target for flashing
flash: atmega Atmega-lib/libatmega328p.a
@echo "Flashing the ATmega328P..."
avrdude -F -V -p m328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:$(OUTPUT_HEX):i
# Rule to create the hex file using avr-objcopy
$(OUTPUT_HEX): atmega
avr-objcopy -O ihex -R .eeprom $< $(OUTPUT_HEX)
我需要告诉 automake 的是在构建 atega 程序之前首先运行 SUBDIRS ,它在单独运行
make
时是如何运行的,但我不知道如何运行。
编辑:
我在 flash 规则之后添加了这一行,它起作用了。这是解决我的问题的正确方法吗?
# Add a custom target for flashing
flash:
$(MAKE)
@echo "Flashing the ATmega328P..."
avrdude -F -V -p m328p -c arduino -P /dev/ttyACM0 -b 115200 -U flash:w:$(OUTPUT_HEX):i
提前谢谢您!
我怎样才能做到只运行 make flash 就能构建一切,然后尝试运行规则?
最简单的解决方案:使
flash
的规则有(仅)all
作为先决条件。 这恰好映射到“在运行配方之前确保每个(默认)内容都是最新的”。 特别是因为 flash
是一个合成目标。
这里的问题是每个 makefile 都是独立的,因此根级 makefile 不了解子目录 makefile 中的规则,例如
Atmega-lib/libatmega328p.a
的规则。 Automake 生成的主要目标会进行递归(all
、clean
、等),但您不会自动获得任意目标的递归。
您还应该考虑经典论文中讨论的问题递归使得被认为是有害的。 Automake 可以很容易地用于为任何源布局生成非递归构建系统,并且以这种方式使用它是我的典型建议。 这也可以解决您的问题,我认为这是一个更好的解决方案。