代码之家  ›  专栏  ›  技术社区  ›  tycoon

MakeFile编译所有文件,即使这些文件已经编译过,并且之后没有被触碰

  •  0
  • tycoon  · 技术社区  · 2 年前

    这是我的makefile

    CFLAGS=-Wall -g -lm
    
    SHELL=/bin/bash
    
    CFILES=$(wildcard *.c)
    OBJECTS=$(patsubst %.c,%,$(CFILES))
    
    .PHONY: clean status all
    
    all: $(OBJECTS)
    
    #%:%.c
    #   gcc $(CFLAGS) -o $@ $^
    
    $(OBJECTS): $(CFILES)
        @echo "Running : $@ -> $^"
    #   gcc $(CFLAGS) -o $@ $(patsubst %,%.c,$@) 
    
    clean:
        rm -f $(OBJECTS)
    
    status:
        @git status
        @git diff --stat
    
    push: clean
        git push
    

    当我使用 %:%.c (规则在Makefile中注释)运行良好。通过所有这些,我只能认为这是一条规则 $(OBJECTS): $(CFILES) is认为对象中的任何目标都取决于$(CFILES)中的所有值。

    因此,每当它构建任何一个binray时,它都会看到它依赖于所有的CFILES,所以如果其中任何一个被修改,它都会重新编译任何c文件。

    所以我想知道有没有更好的方法来编写规则 $(对象):$(CFILES) ,如果这是问题的根源。否则,如果这条规则不是罪魁祸首,那么是什么导致了这一点。我知道我可以用 %:%.C 但我认为这可能会导致一些问题,因为这条规则也适用于 something.h .

    我是Makefiles的新手,所以如果你也详细说明原因,那会很有帮助,所以将来我可以防止这种情况发生

    1 回复  |  直到 2 年前
        1
  •  1
  •   MadScientist    2 年前

    你的怀疑是对的。当你写作时:

    foo bar biz : foo.c bar.c biz.c
            # do something
    

    (这是make在展开变量后看到的),make将其解释为:

    foo : foo.c bar.c biz.c
            # do something
    bar : foo.c bar.c biz.c
            # do something
    biz : foo.c bar.c biz.c
            # do something
    

    你的问题有点让人困惑,因为你用的是“对象”这个词,通常指的是对象文件( foo.o ),而不是二进制文件或可执行文件。

    不管怎样,你可以安全地做你想做的事 static pattern rules :

    $(OBJECTS): % : %.c
            @echo "Running : $< -> $@"
    #       gcc $(CFLAGS) -o $@ $<