如何让avr-gcc将 *.o输出到Makefile中带有“%.o”的分隔文件夹中:%.c '?

mfpqipee  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(118)

如第一张截图所示,我理想的AVR项目结构是:

  1. *.o*.elf*.hex文件位于build文件夹中。
  2. PomoScheler.cpinDefines.h作为主文件位于根文件夹中,而其他*.c*.h位于src文件夹中。
    但是,无论如何,*.o总是在与*.c相同的文件夹中生成,如第二个屏幕截图所示。
    (我在截图下面附上了我的努力和整个Makefile)
    第一次
    首先,我在$@之前尝试了build/,但没有成功。终端还是一样。
    第一个
    其次,我试着添加mv $@ build,明确地将其移动到build文件夹。但没有任何React。甚至echo也没有显示在终端中。
# My second Makefile endeavor
%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
    mv $@ build
    echo ---------Hello---------

第三,我删除了$(HEADERS),用$^替换了$<,只是试一下。mv被执行了。但是这次它找不到*.o文件,尽管我在Makefile中有VPATH = src:build
第一个
我的整个Makefile都在这里。请帮帮我。

# My whole Makefile

MCU   = atmega328p
F_CPU = 1000000UL  
BAUD  = 9600UL

LIBDIR = ~/Developer/bin/avr8-gnu-toolchain-darwin_x86_64/avr/include

PROGRAMMER_TYPE = usbtiny
PROGRAMMER_ARGS =   

CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude

##########------------------------------------------------------##########

VPATH = ./src:./build

TARGET = $(lastword $(subst /, ,$(CURDIR)))

SOURCES=$(wildcard *.c src/*.c $(LIBDIR)/*.c)
OBJECTS=$(SOURCES:.c=.o)
HEADERS=$(SOURCES:.c=.h)

CPPFLAGS = -DF_CPU=$(F_CPU) -DBAUD=$(BAUD) -I. -I$(LIBDIR)
CFLAGS = -Os -g -std=gnu99 -Wall
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums 
CFLAGS += -ffunction-sections -fdata-sections 
LDFLAGS = -Wl,-Map,build/$(TARGET).map 
LDFLAGS += -Wl,--gc-sections 
TARGET_ARCH = -mmcu=$(MCU)

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o build/$@

$(TARGET).elf: $(OBJECTS)
    $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o build/$@

%.hex: %.elf
    $(OBJCOPY) -j .text -j .data -O ihex build/$< build/$@

all: $(TARGET).hex 

size:  $(TARGET).elf
    $(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf

clean:
    rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
    $(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
    $(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
    $(TARGET).eeprom

flash: $(TARGET).hex 
    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
vom3gejh

vom3gejh1#

这显然是不对的:

OBJECTS = $(SOURCES:.c=.o)

因为您要创建的对象文件不是foo.o等,而foo.o等是将扩展到的对象文件;目标文件为build/foo.o等。因此必须为:

OBJECTS = $(patsubst %.c,build/%.o)

你试图欺骗make,告诉它你的方法将构建一个目标(foo.o),但实际上构建一个完全不同的目标(build/foo.o),无论你是让编译器直接做,你使用mv,还是任何其他方法,你都注定要失败。
如果你只是告诉make你的食谱实际上是做什么的,你会有一个简单得多的时间:

build/%.o: %.c
        mkdir -p $(@D)
        $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $^ -o $@

您可能对要放入其他目录的其他规则有类似的问题。
你不能通过试图对make隐藏它来做到这一点。Make必须知道文件 * 实际上在 * 哪里。
顺便说一句,VPATH在这里帮不上忙VPATH是用来查找 source 文件,它不能用来查找 generated 文件所以您可以使用VPATH来查找您.c文件,但不能查找您.o文件

相关问题