Gcc Makefile-编译不同目录中的单个对象

Gcc Makefile-编译不同目录中的单个对象,gcc,makefile,gnu-make,Gcc,Makefile,Gnu Make,我一直在浏览网络,但我想不出正确的方法来实现这一点。只是尝试创建一个简单的Makefile,它接受我的源代码并只构建更改的文件。我需要将所有的.o文件放在同一个输出文件夹中。我现在一切正常,除了如果我改变一个文件,整个事情就会重建。例如,如果我更改main.c,它也将编译EOL.c。然而,如果没有任何改变,它说明什么都不需要做 NAME=Program CC=arm-none-eabi-gcc CFLAGS=-c -Wall -O0 -std=c99 \ -nostartfiles --sp

我一直在浏览网络,但我想不出正确的方法来实现这一点。只是尝试创建一个简单的Makefile,它接受我的源代码并只构建更改的文件。我需要将所有的.o文件放在同一个输出文件夹中。我现在一切正常,除了如果我改变一个文件,整个事情就会重建。例如,如果我更改main.c,它也将编译EOL.c。然而,如果没有任何改变,它说明什么都不需要做

NAME=Program

CC=arm-none-eabi-gcc
CFLAGS=-c -Wall -O0  -std=c99 \
-nostartfiles --specs=nano.specs \
-mthumb -fmessage-length=0 \
-fsigned-char -ffunction-sections \
-fdata-sections -mcpu=cortex-m0

BID?=_DEV
DEFINES= -DPROD -DBLD_ID=\"$(BID)\"
LDFLAGS= -nostartfiles 
INCLUDES= -ISrc/App/Include -ISrc/Device/CMSIS/Include 
SOURCES= Src/main.c Src/App/Source/Application.c Src/App/Source/EOL.c Src/Svc/Source/TimerManager.c
OBJECTS=$(OBJECTS1:.c=.o)
OBJECTS1=$(SOURCES:.S=.o)
OFILES1=$(notdir ${OBJECTS})
OFILES=$(addprefix $(OBJDIR)/,$(OFILES1))
OBJDIR=Output

.PHONY: all rebuild clean

all: $(OBJDIR) $(SOURCES) $(OBJDIR)/$(NAME).hex

%.hex: %.elf
    arm-none-eabi-objcopy -O ihex $< $@

%elf: $(OBJECTS)
    $(CC) $(LDFLAGS) $(OFILES) -o $@


rebuild: clean all

.SECONDARY:
.c.o:
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $(OBJDIR)/$(notdir $@)

.S.o:
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $(OBJDIR)/$(notdir $@)

$(OBJDIR):
    mkdir $(OBJDIR)

clean:
    rm -f $(OBJDIR)/*.o $(OBJDIR)/*.elf $(OBJDIR)/*.hex $(OBJDIR)/*.bin
NAME=程序
CC=arm none eabi gcc
CFLAGS=-c-壁-O0-标准=c99\
-nostartfiles--specs=nano.specs\
-mthumb-fmessage length=0\
-fsigned char-fffunction节\
-fdata截面-mcpu=cortex-m0
出价?=\u开发
DEFINES=-DPROD-DBLD\u ID=\“$(投标)\”
LDFLAGS=-nostartfiles
INCLUDES=-ISrc/App/Include-ISrc/Device/CMSIS/Include
SOURCES=Src/main.csrc/App/Source/Application.csrc/App/Source/EOL.csrc/Svc/Source/timermager.c
OBJECTS=$(OBJECTS1:.c=.o)
OBJECTS1=$(源:.S=.o)
OFILES1=$(notdir${OBJECTS})
OFILES=$(addprefix$(OBJDIR)/,$(OFILES1))
OBJDIR=输出
.骗子:所有人都要干净
全部:$(OBJDIR)$(源代码)$(OBJDIR)/$(名称).hex
%.hex:%.elf
arm none eabi objcopy-O ihex$<$@
%elf:$(对象)
$(CC)$(LDFLAGS)$(文件)-o$@
重建:清除所有
.中学:
.c.o.:
$(CC)$(CFLAGS)$(定义)$(包括)$<-o$(OBJDIR)/$(notdir$@)
S.S.o.:
$(CC)$(CFLAGS)$(定义)$(包括)$<-o$(OBJDIR)/$(notdir$@)
$(OBJDIR):
mkdir$(OBJDIR)
清洁:
rm-f$(OBJDIR)/*.o$(OBJDIR)/*.elf$(OBJDIR)/*.hex$(OBJDIR)/*.bin

此生成文件存在几个问题。基本上,您的规则的目标不是它们实际生成的文件,并且规则的前提条件不是它实际需要的文件

假设您已修改了
Src/main.c
,并尝试使用以下规则重建
Output/Program.elf

%elf: $(OBJECTS)
    $(CC) $(LDFLAGS) $(OFILES) -o $@
先决条件(
$(对象)
)实际上是
Src/main.o Src/App/Source/EOL.o
等等。这些文件不存在--它们从不存在--但它们有一个规则:

.c.o:
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $(OBJDIR)/$(notdir $@)
我们如何告诉Make在哪里找到与
输出/EOL.o
对应的源文件?方法不止一种,但一个好方法是使用:

我们所要做的就是创建一个源目录列表,将其传递给vpath,然后修改模式规则:

SRCDIRS := $(dir $(SOURCES))
vpath %.c $(SRCDIRS)

$(OBJDIR)/%.o: %.c
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $@
我看不出“cmake”标记与问题之间的关系。CMake不是Make。
vpath %.c Src/App/Source

Output/EOL.o: EOL.c
   ...
SRCDIRS := $(dir $(SOURCES))
vpath %.c $(SRCDIRS)

$(OBJDIR)/%.o: %.c
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $@
%elf: $(OFILES)
    $(CC) $(LDFLAGS) $^ -o $@