Makefile总是在重建

Aak*_*ash 4 makefile gnu-make

我使用以下简单的Makefile来构建一些简单的文件.我是制作Makefile的新手.我不知道为什么它继续重建,即使文件是在第一次制作之后构建的,而我不是在编辑任何文件.

EXE    = nextgenrsm
CC     = gcc
LIBS   = StarterWare_Files/
CFLAGS = -c 

INCLUDE_PATH =  StarterWare_Files/

MAIN_SRC = $(wildcard *.c)
MAIN_OBS = $(patsubst %.c,%.o,$(MAIN_SRC))

LIB_SRC = $(wildcard StarterWare_Files/*.c)
LIB_OBS = $(patsubst StarterWare_Files/%.c,%.o,$(LIB_SRC))

output: $(EXE)

$(EXE): $(MAIN_OBS) $(LIB_OBS)
    $(CC) $(MAIN_OBS) $(LIBS)$(LIB_OBS) -o $(EXE) 

$(MAIN_OBS): $(MAIN_SRC) 
    $(CC) $(CFLAGS) *.c -I$(INCLUDE_PATH)

$(LIB_OBS): $(LIB_SRC) 
    cd $(LIBS); \
    $(CC) $(CFLAGS) *.c -I../

clean:
    rm -rf $(LIBS)*.o $(EXE) *.o
Run Code Online (Sandbox Code Playgroud)

新编辑的MAKEFILE

EXE    = nextgenrsm
CC     = gcc
LIBS   = StarterWare_Files/
CPPFLAGS = _IStarterWare_Files/


MAIN_OBS = $(patsubst %.c,%.o,$(wildcard *.c))
LIB_OBS  = $(patsubst %.c,%.o,$(wildcard StarterWare_Files/*.c))

all: $(EXE)

$(EXE): $(MAIN_OBS) $(LIB_OBS)
   $(CC) -o $@ $(LDFLAGS) $(MAIN_OBS) $(LIB_OBS) $(LDLIBS)

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

ALL_DEPS = $(patsubst %.o,%.d,$(MAIN_OBS), $(LIB_OBS))
-include $(ALL_DEPS)

clean:
   rm -f $(LIB_OBS) $(EXE) $(MAIN_OBS) $(ALL_DEPS)

.PHONY: all clean
Run Code Online (Sandbox Code Playgroud)

每当我触摸StarterWare_Files/example.h并尝试再次制作时,它会抛出gcc无法指定-o with -c或-S with Multiple files的错误.基本上命令变成这样的东西gcc -o main.o -IStarterWare_Files -c main.c StarterWare_Files/test.h StarterWare_Files/add.h ..

Max*_*kin 13

您的默认目标是,output但您的makefile永远不会生成这样的文件,因此每次调用make它时都会尝试生成output文件.

解决方案是将output目标标记为虚假目标.以及clean目标:

.PHONY: output clean
Run Code Online (Sandbox Code Playgroud)

您可以充分利用内置的规则是编译.o.c自动变量,以减少你的makefile到:

EXE    := nextgenrsm
CC     := gcc
LIBS   := StarterWare_Files/
CPPFLAGS := -IStarterWare_Files

MAIN_OBS := $(patsubst %.c,%.o,$(wildcard *.c))
LIB_OBS  := $(patsubst %.c,%.o,$(wildcard StarterWare_Files/*.c))

all: $(EXE)
$(EXE) : $(MAIN_OBS) $(LIB_OBS)
    $(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS)

clean:
    rm -f $(MAIN_OBS) $(LIB_OBS) $(EXE)

.PHONY: all clean   
Run Code Online (Sandbox Code Playgroud)

如果你想自动生成头依赖关系生成添加:

# This rule produces .o and also .d (-MD -MP) from .c.
%.o : %.c
    $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

# This includes all .d files produced along when building .o.
# On the first build there are not going to be any .d files.
# Hence, ignore include errors with -.
ALL_DEPS := $(patsubst %.o,%.d,$(MAIN_OBS) $(LIB_OBS))
-include $(ALL_DEPS)

clean:
    rm -f $(MAIN_OBS) $(LIB_OBS) $(EXE) $(ALL_DEPS)
Run Code Online (Sandbox Code Playgroud)

  • `$ <`(第一个先决条件)是`$(EXE):$(MAIN_OBS)$(LIB_OBS)`食谱中的拼写错误.它应该是`$ ^`(所有先决条件).我刚编辑修复它. (3认同)
  • @EtanReisner,我对`$ <`的助记符是它是左箭头,第一个先决条件是"最左边".所以在视觉上我把它读作"那边的那个,一直到左边":)而且`$ ^`就是"那些文件在那里,在我之上".它运作良好,足以慢慢记忆......但对其他特殊变量没有帮助. (3认同)
  • 虽然这不会导致它重新编译任何东西,假设其他目标正确地创建目标文件(他们似乎这样做).哦,没有`$(LIB_OBS)`没有名字中的目录. (2认同)
  • 是的,我必须经常看待自己.我相信BSD使用命名变量来避免这种混淆. (2认同)
  • `%.o`目标中的`$ ^`是不正确的.它需要是`$ <`. (2认同)