如何在makefile中创建一个步骤来生成预处理文件并从这些文件进行编译?

时间:2016-06-19 01:41:09

标签: makefile c-preprocessor avr

我从以前编译avr微控制器程序的项目中获取了一个makefile。我遇到了一些问题,我设置的IO端口/数据方向地址是导致微控制器故障和复位的问题。因此我想在makefile中添加一个步骤,让它生成预处理文件,然后从这些预处理文件中编译。我不太熟悉规则/依赖关系如何在makefile中工作,所以我已经制作了,我相信,在理解makefile的工作原理时,这是一个简单的错误。制作预处理文件/目标文件以及最终的.elf文件的规则必定是错误的。直到我添加了尝试创建预处理文件的步骤,创建.elf文件工作正常。关于规则/依赖关系如何在make中工作的简单错误/理解是什么?

当我向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中的规则。

1 个答案:

答案 0 :(得分:0)

我的错误来自于我的目录中没有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)。我还将$(PROCESS_FILES)添加到$(OUTPUT).elf: $(OBJ_FILES),因此该规则将独立生成预处理文件和目标文件。我必须将$(OBJ_FILES): %.o : %.e更改为$(OBJ_FILES): %.o : %.c才能使其发挥作用。