【问题标题】:Makefile always recompiling some sectionsMakefile 总是重新编译某些部分
【发布时间】:2015-07-20 17:43:03
【问题描述】:

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

每当我进行 make 时,它​​都会成功创建一个名为 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

我也不确定我是否正确地做依赖关系。

【问题讨论】:

  • 我遇到了类似的问题,我将 OUT_DIR 列为依赖项,以确保它在尝试将源代码编译到其中之前已生成。不幸的是,每次更改文件时目录都会更改,这导致我的构建也每次生成都重建所有内容。不过,我没有看到您将 OUT_DIR 列为对您的文件的依赖项。
  • 您违反了Rules of Makefiles 的规则 2。您的规则会生成与目标名称不匹配的文件。因此,无法知道您的目标是最新的,因为它可以告诉您的目标文件不存在
  • 你看过你的 .d 文件了吗?
  • 你的规则应该是这样的:$(OUT_EXE/SRC)/%.o: %.c

标签: c gcc makefile gnu-make


【解决方案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 $<

如果你有一个复杂的目录结构,它会变得复杂,因为你需要创建更多的目录或者对你的对象重命名感兴趣。

【讨论】:

  • 对不起我的意思是Output/source/main.o 你可以阅读前面的目录结构寻求帮助
  • 构建可执行文件的规则是什么。
【解决方案2】:

非常感谢 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多