gnu-make - 为什么 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 没有改变。我错过了什么?
解决方案
如果b.o
没有重新编译,则test.so
无法创建,因为它依赖于b.o
. 如果已删除a.o
,则无法创建共享库。b.o
b.o
如果您尝试创建一个静态库,那么您可以使用 make 的特殊归档语法来替换a.o
而无需重新编译b.o
,但除非您使用归档特殊语法,否则这是不可能的,并且对于像您这样的共享库不能这样做重新尝试在这里建造。
默认情况下,这些.o
文件不被视为中间文件是有原因的,并且通过添加.INTERMEDIATE
目标来强制它们成为中间文件并不意味着您可以避免重建它们。
推荐阅读
- asp.net-core-identity - 如何在视图中获取 Asp.net Core Identity 用户
- python - Keras 批量训练在线预测不学习
- java - 如何使用 LambdaMetaFactory 调用构造函数?
- php - php-encrypt 比较两个数据
- r - 从文本中去除数字:R
- python - 更快的代码温度传感器 - Raspberry Pi
- html - 页脚社交图标在调整大小时不会均匀分布
- sql-server - 在实体框架中恢复 SQL Server 数据库
- java - 反序列化服务器响应
- c# - 构建电报 azure bot 以提供动态问卷以及位置共享