我有两个文件:assign1.c和ports.h。
仅供参考:我使用的是avr-gcc。
我构建了以下makefile,我也用它来处理其他项目(和其他TARGET)。
TARGET = assign2
LIB=
INCLUDE=ports.h
CFLAGS =-mmcu=atmega32 -Wall
CC = avr-gcc
SRC= $(TARGET).c
OBJ= $(SRC:.c=.o)
OBJCOPY = avr-objcopy
FORMAT = ihex
MSG_COMPILING = Compiling:
MSG_LINKING = Linking:
MSG_FLASH = Creating load file for flash:
all:elf hex
elf: $(TARGET).elf
hex: $(TARGET).hex
%.hex: %.elf
@echo $(MSG_FLASH) $@
@echo
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
$(RM) *.elf $(TARGET)
@echo
%.elf: $(OBJ) $(LIB)
@echo $(MSG_LINKING) $@
@echo
$(CC) $(CFLAGS) $^ -o $@
@echo
%.o: $(SRC) $(INCLUDE)
@echo $(MSG_COMPILING) $<
@echo
$(CC) $(CFLAGS) -c $<
@echo
.PHONY : clean
clean:
$(RM) *.o *.hex *.elf $(TARGET)
终端打印以下输出。
C:\Project>make
Compiling: assign2.c
avr-gcc -mmcu=atmega32 -Wall -c assign2.c
In file included from assign2.c:8:
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warnin
g "Compiler optimizations disabled; functions from <util/delay.h> won't work as
designed"
Linking: assign2.elf
avr-gcc -mmcu=atmega32 -Wall assign2.o -o assign2.elf
Compiling: assign2.c
avr-gcc -mmcu=atmega32 -Wall -c assign2.c
In file included from assign.c:8:
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warnin
g "Compiler optimizations disabled; functions from <util/delay.h> won't work as
designed"
avr-gcc elf.o assign2.elf -o elf
avr-gcc: elf.o: No such file or directory
make: *** [elf] Error 1
rm assign2.o
C:\Project>
出于某种原因,似乎第二次编译第一个文件并且崩溃了。
任何人都可以纠正我的错误吗?
答案 0 :(得分:3)
问题是你的模式规则。您正在编写这样的模式规则(在make扩展变量之后):
%.o: assign2.c ports.h
此规则告诉make的是,要构建的任何匹配%.o
模式的目标都可以通过编译assign2.c
来构建。这显然不正确:此规则只构建一个目标:assign2.o
。
因此make会读取你的makefile并希望构建一个名为elf
的文件。它看到elf
依赖于$(TARGET).elf
,所以它构建了它(这是第一个编译和链接,它有效)。然后make想要自己构建elf
。你没有宣称它是.PHONY,所以make假设它可能是一个真正的目标。
查看其内置规则,找到一个允许它构建elf
的规则,并找到一个内置规则:% : %.o
,它可用于从{编译程序{1}}具有相同前缀的文件。现在,对于目标.o
,make想要尝试构建文件elf
。啊哈!它看到有一个模式规则允许它基于elf.o
源文件构建任何.o
文件,因此它运行该规则(这是第二次编译),期望它构建assign2.c
..它显然没有。
然后使用不存在的elf.o
运行内置链接配方,然后失败。
解决问题的方法有两点:
首先,你应该总是声明你实际上不想构建的所有makefile目标.PHONY所以make不会尝试构建它们:
elf.o
其次,你不应该使用模式规则,前提条件也不是模式(这在某些特定情况下很有用,但一般情况下不是这样)。您应该将这些模式规则更改为明确的规则:
.PHONY: all elf hex
或者通过使用先决条件列表中的模式将它们变为完整模式规则:
assign2.elf: $(OBJ) $(LIB)
...
$(OBJ): $(SRC) $(INCLUDE)
...