首页 > 解决方案 > 为什么 gnumake 会重新制作中间文件?

问题描述

我有一个非常简单的makefile,如下所示:

.PHONY: clean all

CC              = /home/utils/gcc-5.2.0/bin/g++
CFLAGS          = -Wall -Werror -fPIC 

SRC             = $(wildcard *.c)
OBJ             = $(subst .c,.o,$(SRC))

.INTERMEDIATE: $(OBJ)

all: test.so

%.o: %.c
    $(CC) $(CFLAGS) -o $@ -c $<

test.so: $(OBJ)
    $(CC) -shared $^ -o $@

clean:
    @rm -f *.o *~ *.so

我在同一个目录中只有两个文件:ac 和 bc 当我执行“make all”时,我得到了以下完美的文件。

/home/utils/gcc-5.2.0/bin/g++ -Wall -Werror -fPIC  -o a.o -c a.c
/home/utils/gcc-5.2.0/bin/g++ -Wall -Werror -fPIC  -o b.o -c b.c
/home/utils/gcc-5.2.0/bin/g++ -shared a.o b.o -o test.so
rm a.o b.o

但是,如果我这样做:触摸交流;做所有

我得到了与上面相同的 make 执行顺序,这不是我所期望的。ac 和 bc 之间没有依赖关系我期望的是:

/home/utils/gcc-5.2.0/bin/g++ -Wall -Werror -fPIC  -o a.o -c a.c
/home/utils/gcc-5.2.0/bin/g++ -shared a.o b.o -o test.so
rm a.o

我不明白为什么 bc 再次编译。根据 gnumake 手册:

第一个区别是如果中间文件不存在会发生什么。如果一个普通文件 b 不存在,并且 make 考虑一个依赖于 b 的目标,它总是创建 b 然后从 b 更新目标。但是如果 b 是一个中间文件,那么 make 就可以不用管它了。它不会打扰更新 b 或最终目标,除非 b 的某些先决条件比该目标更新或有其他原因更新该目标。

bo 是一个中间文件,它不应该再次编译,因为 bc 没有改变。我错过了什么?

标签: gnu-make

解决方案


如果b.o没有重新编译,则test.so无法创建,因为它依赖于b.o. 如果已删除a.o,则无法创建共享库。b.ob.o

如果您尝试创建一个静态库,那么您可以使用 make 的特殊归档语法来替换a.o而无需重新编译b.o,但除非您使用归档特殊语法,否则这是不可能的,并且对于像您这样的共享库不能这样做重新尝试在这里建造。

默认情况下,这些.o文件不被视为中间文件是有原因的,并且通过添加.INTERMEDIATE目标来强制它们成为中间文件并不意味着您可以避免重建它们。


推荐阅读