我怎样才能在 makefile 中有一个步骤来生成预处理文件并从这些文件进行编译?
How can I have a step in a makefile to generate preprocess files and compile from those files?
我从以前的项目中获取了一个 makefile,该项目为 avr 微控制器编译程序。我 运行 遇到了我设置的 IO ports/data 定向地址的一些问题,这导致微控制器出现故障并重置。因此,我想在我的 makefile 中添加一个步骤,让它生成预处理文件,然后从这些预处理文件进行编译。我不太熟悉 rules/dependencies 如何在 makefile 中工作,所以我认为我在理解 makefile 的工作方式时犯了一个简单的错误。我制作预处理 files/object 文件和最终 .elf 文件的规则一定是错误的。直到我添加了尝试创建预处理文件的步骤,创建 .elf 文件才能正常工作。 rules/dependencies 在 make 中如何工作,我的简单 mistake/understanding 是什么?
我如何看待这个工作是当我询问 make all
它看到它有 led.elf 的依赖性。要创建它,它依赖于基于 $(OUTPUT).elf: $(PROCESS_FILES)
行的预处理文件,因此它从这一行开始。但是,当我尝试 make all
时,出现错误 make: *** No rule to make target 'main.c', needed by 'main.e'. Stop.
,我不明白为什么。谁能帮助我理解 make 文件?
SRC_FILES=\
main.c led.c comm.c
#Object files
PROCESS_FILES=$(SRC_FILES:.c=.e)
OBJ_FILES=$(PROCESS_FILES:.e=.o)
#Directories where to look for include files
INC_DIRS=\
-I. \
#Output file name
OUTPUT=led
#Programmer and port
PROG=dragon_isp
PORT=usb
#Debugging host and port
DHOST=localhost
DPORT=6423
#Compiler related params
MCU=atmega2560
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS= -mcall-prologues -std=gnu99 -funsigned-char -funsigned bitfields \
-fpack-struct -fshort-enums -mmcu=$(MCU) -Wall -Wstrict-prototypes \
$(INC_DIRS)
#Optimization level
CFLAGS+=-Os
#Debug info
CFLAGS+=-gdwarf-2
#Generate hex file ready to upload
all: $(OUTPUT).elf
$(OBJCOPY) -R .eeprom -O ihex $(OUTPUT).elf $(OUTPUT).hex
#Link output files
$(OUTPUT).elf: $(PROCESS_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
#Create object files
$(PROCESS_FILES): %.e : %.c
$(CC) -E $(CFLAGS) $< -o $@
$(OBJ_FILES): %.o : %.e
$(CC) -x $(CFLAGS) $< -o $@
#Create assembler file of a C source
%.s: %.c
$(CC) -S $(CFLAGS) $< -o $@
#Cleans all generated files
clean:
rm -f $(OBJ_FILES)
rm -f $(OUTPUT).elf
rm -f $(OUTPUT).hex
rm -f $(OUTPUT).map
编辑:我现在不在电脑旁,所以我无法检查这个,但考虑到我的问题,我开始认为我在该目录中没有名为 main.c 的文件。即使我这样做了,我仍然认为 makefile 无法正常工作,因为我不完全理解 makefile 中的规则。
我的错误是因为我的目录中没有 main.c
文件。确保在弄乱 OBJ_FILES 或类似变量时备份文件,并有一行将删除 make clean
时该变量中的任何内容。
至于规则,我必须做一个小修改才能达到我想要的效果。我改变了
$(OUTPUT).elf: $(PROCESS_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
至
$(OUTPUT).elf: $(OBJ_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
这会发现它需要目标文件,而目标文件又需要预处理的文件。
编辑:我也将 OBJ_FILES=$(PROCESS_FILES:.e=.o)
更改为 OBJ_FILES=$(SRC_FILES:.c=.o)
。我还在 $(OUTPUT).elf: $(OBJ_FILES)
中添加了 $(PROCESS_FILES)
,因此该规则将独立生成预处理文件和目标文件。我必须将 $(OBJ_FILES): %.o : %.e
更改为 $(OBJ_FILES): %.o : %.c
才能完成这项工作。
我从以前的项目中获取了一个 makefile,该项目为 avr 微控制器编译程序。我 运行 遇到了我设置的 IO ports/data 定向地址的一些问题,这导致微控制器出现故障并重置。因此,我想在我的 makefile 中添加一个步骤,让它生成预处理文件,然后从这些预处理文件进行编译。我不太熟悉 rules/dependencies 如何在 makefile 中工作,所以我认为我在理解 makefile 的工作方式时犯了一个简单的错误。我制作预处理 files/object 文件和最终 .elf 文件的规则一定是错误的。直到我添加了尝试创建预处理文件的步骤,创建 .elf 文件才能正常工作。 rules/dependencies 在 make 中如何工作,我的简单 mistake/understanding 是什么?
我如何看待这个工作是当我询问 make all
它看到它有 led.elf 的依赖性。要创建它,它依赖于基于 $(OUTPUT).elf: $(PROCESS_FILES)
行的预处理文件,因此它从这一行开始。但是,当我尝试 make all
时,出现错误 make: *** No rule to make target 'main.c', needed by 'main.e'. Stop.
,我不明白为什么。谁能帮助我理解 make 文件?
SRC_FILES=\
main.c led.c comm.c
#Object files
PROCESS_FILES=$(SRC_FILES:.c=.e)
OBJ_FILES=$(PROCESS_FILES:.e=.o)
#Directories where to look for include files
INC_DIRS=\
-I. \
#Output file name
OUTPUT=led
#Programmer and port
PROG=dragon_isp
PORT=usb
#Debugging host and port
DHOST=localhost
DPORT=6423
#Compiler related params
MCU=atmega2560
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS= -mcall-prologues -std=gnu99 -funsigned-char -funsigned bitfields \
-fpack-struct -fshort-enums -mmcu=$(MCU) -Wall -Wstrict-prototypes \
$(INC_DIRS)
#Optimization level
CFLAGS+=-Os
#Debug info
CFLAGS+=-gdwarf-2
#Generate hex file ready to upload
all: $(OUTPUT).elf
$(OBJCOPY) -R .eeprom -O ihex $(OUTPUT).elf $(OUTPUT).hex
#Link output files
$(OUTPUT).elf: $(PROCESS_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
#Create object files
$(PROCESS_FILES): %.e : %.c
$(CC) -E $(CFLAGS) $< -o $@
$(OBJ_FILES): %.o : %.e
$(CC) -x $(CFLAGS) $< -o $@
#Create assembler file of a C source
%.s: %.c
$(CC) -S $(CFLAGS) $< -o $@
#Cleans all generated files
clean:
rm -f $(OBJ_FILES)
rm -f $(OUTPUT).elf
rm -f $(OUTPUT).hex
rm -f $(OUTPUT).map
编辑:我现在不在电脑旁,所以我无法检查这个,但考虑到我的问题,我开始认为我在该目录中没有名为 main.c 的文件。即使我这样做了,我仍然认为 makefile 无法正常工作,因为我不完全理解 makefile 中的规则。
我的错误是因为我的目录中没有 main.c
文件。确保在弄乱 OBJ_FILES 或类似变量时备份文件,并有一行将删除 make clean
时该变量中的任何内容。
至于规则,我必须做一个小修改才能达到我想要的效果。我改变了
$(OUTPUT).elf: $(PROCESS_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
至
$(OUTPUT).elf: $(OBJ_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $(OUTPUT).elf -Wl,-Map,$(OUTPUT).map
这会发现它需要目标文件,而目标文件又需要预处理的文件。
编辑:我也将 OBJ_FILES=$(PROCESS_FILES:.e=.o)
更改为 OBJ_FILES=$(SRC_FILES:.c=.o)
。我还在 $(OUTPUT).elf: $(OBJ_FILES)
中添加了 $(PROCESS_FILES)
,因此该规则将独立生成预处理文件和目标文件。我必须将 $(OBJ_FILES): %.o : %.e
更改为 $(OBJ_FILES): %.o : %.c
才能完成这项工作。