在将make从3.81升级到4.3之后,我面临着一个奇怪的行为. 此生成文件使用旧的GNU语法描述静态库的构建:

LIBNAME = testlib.a

OBJ_FILES = \
            $(LIBNAME)(test1.o) \
            $(LIBNAME)(test2.o)
            
all: $(LIBNAME)
            
$(LIBNAME): $(OBJ_FILES)
    $(RANLIB) $@

make4.3的行为是,无论源文件是否已更改,都始终生成库. 在make -p的输出中,make似乎正在执行隐式规则并在目录中搜索test1.otest2.o,但由于它们不在目录中,因此它从源代码生成新的它们,使用ar命令添加它们,然后从目录中删除它们.

在版本3.81中,它直接签入test1.otestlib.a,如果找到它,则不执行其他规则.

那么这个makefile必须重写吗,或者有没有其他的可能性来获得旧的行为?

编辑:

现在在另一个Linux Mint系统上进行了测试,GNU make 4.3,相同的行为.

正如MadScientist提到的,输出make --trace:

<builtin>: update target 'test1.o' due to: test1.c
cc    -c -o test1.o test1.c
<builtin>: update target 'testlib.a(test1.o)' due to: test1.o
ar rv -U testlib.a test1.o
r - test1.o
rm test1.o

推荐答案

你是sure吗?这两种情况的唯一区别是make的版本不同?也就是说,您是在具有两个不同版本的make的同一系统上运行它,还是在具有不同版本的操作系统和/或编译器的两个不同系统上运行它?

我敢打赌,除了使用不同版本的make之外,您还在使用不同版本的binutils.

在过go 10年左右的某个时候,有人得到了一个惊人的聪明 idea (不是!),那就是ar计划的默认行为应该从它50年来的默认行为改变,并使其成为"确定性的".现在,我完全支持可复制的构建,但这应该是一个 Select 加入的能力,而不是一个 Select 退出的能力,特别是因为在ar中启用"确定性模式"完全摧毁了Make的归档管理能力.

如果你想让它工作,你必须手动禁用确定性模式. try 添加:

ARFLAGS += -U

看看它能不能解决问题.

顺便说一句,在上面的Makefile示例中,您忘记了定义RANLIB,所以它不能工作(该变量不是GNU make的内置变量).

C++相关问答推荐

是否可以在C中进行D3 D12申请?

自定义malloc实现上奇怪的操作系统依赖行为

修改pGM使用指针填充2-D数组但不起作用

如何将FileFilter添加到FileDialog GTK 4

C/C++中的状态库

Malloc(sizeof(char[Length]))是否不正确?

在传统操作系统上可以在虚拟0x0写入吗?

如果dim指定数组中的数据量,使用dim-1会不会潜在地导致丢失一个元素?

如何在ASM中访问C struct 成员

FRIDA-服务器成为端口扫描的目标?

用C语言计算文本文件中的整数个数

使用%f格式说明符打印整数值

为什么这个分配做得不好呢?

条件跳转或移动取决于未初始化值(S)/未初始化值由堆分配创建(Realloc)

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

不带Malloc的链表

宏观;S C调深度

gdb - 你能找到持有内部 glibc 锁的线程吗?

仅使用其内存地址取消引用 C 中的 struct

C23 中是否有 __attribute__((nonnull)) 的等效项?