Makefile总是重新编译某些部分

时间:2015-07-20 17:43:03

标签: c gcc makefile gnu-make

Example的目录结构是这样的。

示例 - 包含Makefile,main.c,xyz.c,xyz.h和子目录Hal和Interrupt_Config Hal - 包含test2.c和test2.h Interrupt_Config - 包含try.h

EXE   := Micro
CC    := gcc
CPPFLAGS := -IHal -IInterruptConfig
VPATH := Hal:InterruptConfig    
OUT_DIR := Output/
OUT_SRC := Output/source/
OUT_EXE := Output/output
LIBS = Hal InterruptConfig

MAIN_OBS := $(patsubst %.c,%.o,$(wildcard *.c))
INT_OBS  := $(patsubst %.c,%.o,$(wildcard InterruptConfig/*.c))
HAL_OBS  := $(patsubst %.c,%.o,$(wildcard Hal/*.c))
ALL_DEPS := $(patsubst %.o,%.d,$(MAIN_OBS) $(HAL_OBS) $(INT_OBS))

ALL_OBS := $(MAIN_OBS) $(INT_OBS) $(HAL_OBS)    

all: $(OUT_DIR) $(EXE)

$(OUT_DIR):
    mkdir -p $(OUT_DIR)
    mkdir -p $(OUT_SRC)
    mkdir -p $(OUT_EXE)

%.o: %.c
    $(CC) -o $(OUT_SRC)$@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

$(EXE): $(MAIN_OBS) $(HAL_OBS) $(INT_OBS)
    $(CC) -o $(OUT_EXE)$@ $(LDFLAGS) $(OUT_SRC)*.o $(LDLIBS)

$(HAL_OBS): %.o: %.c 
    $(CC) -o $(OUT_SRC)$(notdir $@) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

$(INT_OBS): %.o: %.c 
    $(CC) -o $(OUT_SRC)$(notdir $@) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $< 

-include $(ALL_DEPS)

clean:
    rm -rf $(OUT_DIR) $(ALL_DEPS)

.PHONY: all clean

每当我做的时候,它都会成功创建一个名为 Output 的目录,其子目录 source 包含所有目标文件和 output 包含名为 Micro 的可执行文件。第一次如果我确实成功构建了所有内容但是如果我再次 make ,我预计它应该给 make - 无事可做但是它会构建所有内容 $(OUT_DIR)规则。我无法弄清问题是什么。

重复制作 - 预期 - 没有

实际 -

gcc -o Output/source/main.o -MD -MP -IHal -IInterrupt_Config  -c main.c
gcc -o Output/source/xyz.o -MD -MP -IHal -IInterrupt_Config  -c xyz.c
gcc -o Output/source/test2.o -MD -MP -IHal -IInterrupt_Config  -c Hal/test2.c
gcc -o Output/output/nextgenrsm  Output/source/*.o

此外,我不确定我是否正确地执行了依赖项。

2 个答案:

答案 0 :(得分:1)

在不知道您的构建目录设置的情况下,很难为您提供准确的解决方案,但我的构建规则看起来像这样:

MAIN_OBS := $(add_prefix $(OUT_DIR), $(patsubst %.c,%.o,$(wildcard *.c)))

$(OUT_DIR):
    mkdir -p $(OUT_DIR)
    mkdir -p $(OUT_SRC)
    mkdir -p $(OUT_EXE)

$(OUT_SRC)/%.o: %.c
    $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

如果你有一个复杂的目录结构会变得复杂,因为你需要制作更多的目录或者想要重新命名对象。

答案 1 :(得分:0)

非常感谢mjr和Etan Reisner。我刚刚在这里发布了针对其他人的学习目的的最终Makefile。

更新

EXE :=nextgenrsm
CC  := gcc
CPPFLAGS := -IHal -IInterrupt_Config
VPATH := Hal:Interrupt_Config
OUT_DIR := Output/
OUT_SRC := Output/source/
OUT_EXE := Output/output/$(EXE)
LIBS = Hal Interrupt_Config

MAIN_OBS := $(addprefix $(OUT_SRC), $(patsubst %.c,%.o, $(wildcard *.c)))
INT_OBS :=  $(addprefix $(OUT_SRC), $(notdir $(patsubst %.c,%.o,$(wildcard Interrupt_Config/*.c))))
HAL_OBS := $(addprefix $(OUT_SRC), $(notdir $(patsubst %.c,%.o,$(wildcard Hal/*.c))))
ALL_DEPS := $(patsubst %.o,%.d, $(MAIN_OBS) $(HAL_OBS) $(INT_OBS))

ALL_OBS =  $(notdir $(MAIN_OBS) $(INT_OBS) $(HAL_OBS)))

all: $(OUT_DIR) $(OUT_EXE)

$(OUT_DIR):
        mkdir -p $(OUT_DIR)
        mkdir -p $(OUT_DIR)source/
        mkdir -p $(OUT_DIR)output/

$(OUT_EXE): $(MAIN_OBS) $(HAL_OBS) $(INT_OBS)
        $(CC) -o $@ $(LDFLAGS)  $(OUT_SRC)*.o $(LDLIBS)

$(OUT_SRC)%.o: %.c
        $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

-include $(ALL_DEPS)

clean:
        rm -rf $(OUT_DIR)

.PHONY: all clean