静态库的 make 中的奇怪行为

问题描述 投票:0回答:1

从 3.81 升级到 4.3 后,我遇到了奇怪的行为。 这个 makefile 描述了使用较旧的 GNU 语法构建静态库:

make

LIBNAME = testlib.a

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

4.3
的行为是始终生成lib,无论源文件是否已更改。 在 make 的输出中,似乎
make -p
正在执行隐式规则并在目录中搜索
make
test1.o
,但由于它们不在那里,它会从源生成新的它们,并用
 添加它们test2.o
命令,然后将它们从目录中删除。
在版本

3.81

中,它直接在ar中检查

testlib.a
,如果找到则不执行其他规则。
那么这个 makefile 必须重写吗?还是有其他可能获得旧的行为?

编辑:

现在在另一个 Linux Mint 系统上进行测试,使用 GNU

test1.o

4.3,具有相同的行为。

make

的已清理输出:

make -p


c makefile
1个回答
0
投票
确定

这两种情况之间的唯一区别是cc -c -o test1.o test1.c ar rv testlib.a test1.o r - test1.o cc -c -o test2.o test2.c ar rv testlib.a test2.o r - test2.o rm test1.o test2.o # GNU Make 4.3 # Gebaut für x86_64-pc-linux-gnu # Copyright (C) 1988-2020 Free Software Foundation, Inc. # Lizenz GPLv3+: GNU GPL Version 3 oder später <http://gnu.org/licenses/gpl.html> # Dies ist freie Software: Sie können sie nach Belieben ändern und weiter verteilen. # Soweit es die Gesetze erlauben gibt es KEINE GARANTIE. # „Make“-Datenbank; erstellt am: Wed Jan 24 19:47:38 2024 testlib.a(test2.o): test2.o # Die Suche nach impliziten Regeln wurde durchgeführt. # Wurzel impliziter/statischer Muster: „test2.o“ # Die Datei existiert nicht. # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # automatisch # @ := testlib.a # automatisch # * := test2.o # automatisch # < := test2.o # automatisch # + := test2.o # automatisch # % := test2.o # automatisch # ^ := test2.o # automatisch # ? := test2.o # automatisch # | := # Hashtabellen-Statistik für Variablen: # Load=8/32=25%, Rehash=0, Kollisionen=2/24=8% # Auszuführende Regel (eingebaut): $(AR) $(ARFLAGS) $@ $< test1.o: test1.c # Die Suche nach impliziten Regeln wurde durchgeführt. # Wurzel impliziter/statischer Muster: „test1“ # Datei ist ein Zwischenschritt in den Abhängigkeiten. # Zuletzt geändert 2024-01-24 19:47:38.902846541 # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # automatisch # @ := test1.o # automatisch # * := test1 # automatisch # < := test1.c # automatisch # + := test1.c # automatisch # % := # automatisch # ^ := test1.c # automatisch # ? := test1.c # automatisch # | := # Hashtabellen-Statistik für Variablen: # Load=8/32=25%, Rehash=0, Kollisionen=2/19=11% # Auszuführende Regel (eingebaut): $(COMPILE.c) $(OUTPUT_OPTION) $< testlib.a(test1.o): test1.o # Die Suche nach impliziten Regeln wurde durchgeführt. # Wurzel impliziter/statischer Muster: „test1.o“ # Die Datei existiert nicht. # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # automatisch # @ := testlib.a # automatisch # * := test1.o # automatisch # < := test1.o # automatisch # + := test1.o # automatisch # % := test1.o # automatisch # ^ := test1.o # automatisch # ? := test1.o # automatisch # | := # Hashtabellen-Statistik für Variablen: # Load=8/32=25%, Rehash=0, Kollisionen=2/24=8% # Auszuführende Regel (eingebaut): $(AR) $(ARFLAGS) $@ $< # Dies ist kein Ziel: test2.c: # Die Suche nach impliziten Regeln wurde durchgeführt. # Zuletzt geändert 2024-01-24 19:41:32.093558001 # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # Dies ist kein Ziel: .a: # Eingebaute Regel # Die Suche nach impliziten Regeln wurde nicht durchgeführt. # Zeit der letzten Änderung wurde nicht überprüft. # Datei wurde nicht aktualisiert. all: testlib.a # Die Suche nach impliziten Regeln wurde durchgeführt. # Die Datei existiert nicht. # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # Hashtabellen-Statistik für Variablen: # Load=0/32=0%, Rehash=0, Kollisionen=0/28=0% test2.o: test2.c # Die Suche nach impliziten Regeln wurde durchgeführt. # Wurzel impliziter/statischer Muster: „test2“ # Datei ist ein Zwischenschritt in den Abhängigkeiten. # Zuletzt geändert 2024-01-24 19:47:38.930846181 # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # automatisch # @ := test2.o # automatisch # * := test2 # automatisch # < := test2.c # automatisch # + := test2.c # automatisch # % := # automatisch # ^ := test2.c # automatisch # ? := test2.c # automatisch # | := # Hashtabellen-Statistik für Variablen: # Load=8/32=25%, Rehash=0, Kollisionen=2/19=11% # Auszuführende Regel (eingebaut): $(COMPILE.c) $(OUTPUT_OPTION) $< # Dies ist kein Ziel: test1.c: # Die Suche nach impliziten Regeln wurde durchgeführt. # Zuletzt geändert 2024-01-24 19:41:09.466140573 # Datei wurde aktualisiert. # Erfolgreich aktualisiert. testlib.a: testlib.a(test1.o) testlib.a(test2.o) # Die Suche nach impliziten Regeln wurde durchgeführt. # Zuletzt geändert 2024-01-24 19:47:38.93484613 # Datei wurde aktualisiert. # Erfolgreich aktualisiert. # Hashtabellen-Statistik für Variablen: # Load=0/32=0%, Rehash=0, Kollisionen=0/28=0% 的版本吗?也就是说,您是在具有两个不同版本的

make
的同一系统上运行它,还是在具有不同版本的操作系统和/或编译器的两个不同系统上运行它?
我敢打赌,除了使用不同版本的 

make

之外,您还使用了不同版本的 binutils。

在过去 10 年左右的某个时刻,有人想到了一个令人惊讶的好主意(不是!),即 

make

程序的默认行为应该改变 50 年来的状态,并使其“确定性” 。现在,我完全支持可重现的构建,但这应该是一种选择加入功能,而不是选择退出功能,特别是因为在

ar
中启用“确定性模式”完全破坏了 make 管理档案的能力。
如果您希望它起作用,您将必须手动禁用确定性模式。尝试添加:

ar

看看它是否能解决问题。

顺便说一句,在上面的 makefile 示例中,您忘记定义

ARFLAGS += -U

,因此它无法工作(该变量不是 GNU Make 的内置变量)。

    

© www.soinside.com 2019 - 2024. All rights reserved.