用于构建库的旧 Makefile 在 FreeBSD 下不再工作

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

最近没怎么搞C编程,最近重温一个老项目,发现FreeBSD下老的Makefile建库已经不行了。这是曾经工作过的 Makefile 的简化版本:

TEST    = Test
LIBTEST = lib$(TEST).a

CC      = cc

.PRECIOUS: $(LIBTEST)

all: $(LIBTEST)

LIBSRC  = test.c

# Do not automatically delete library source files
.SECONDARY: $(LIBSRC)

LIBOBJ  = $(LIBSRC:%.c=%.o)

$(LIBTEST): $(LIBTEST)($(LIBOBJ))
        $(AR) $(ARFLAGS) $@ $?
        rm -f $?

clean:
        @rm -f *.o $(LIBTEST)

这里有一个简单的 C 程序:

/* test.c */
#include <stdio.h>

int
test(char const *text)
{
    printf("%s\n", text);
    return 1;
}

看起来像 Makefile 指令依赖:

$(LIBTEST): $(LIBTEST)($(LIBOBJ))

不再有效。结果是:

 ar -crD libTest.a
 rm -f

我一直在仔细阅读“man make”但没有成功。

令我困惑的一件事是“man make”说“有关 make 和 makefile 的更详尽描述,请参阅 PMake - 教程。”

这个准确吗?我的印象是 pmake 在最近版本的 FreeBSD 中被 bsdmake 取代了——这是我问题的根源吗?

注意:我对归结为“您可以使用 GNU make 做到这一点”的答案不感兴趣 - 这是 FreeBSD make 的问题。

makefile freebsd bsdmake bmake
1个回答
1
投票
$(LIBTEST): $(LIBTEST)($(LIBOBJ))

表明

$(LIBTEST)
(此处为
libTest.a
)的先决条件是该档案的
$(LIBOBJ)
(此处为
test.o
)成员,我不太确定
make
应该从中得出什么结论,但对我而言(FreeBSD 11.0) 它带有
all
(这实际上意味着
libTest.a
)已经是最新的(另请参见标尺下方的示例)。将行更改为:

$(LIBTEST): $(LIBOBJ)

似乎是有道理的(除非我错过了什么,否则应该是你想要的),目标文件是库目标的先决条件,并且规则使用比目标更新的所有先决条件更新库(

$?
)。

这让我又多了一条评论。

rm
似乎不仅没有必要,而且实际上是有害的,因为这意味着
test.o
总是在调用
make all
时重新编译,并且库总是得到更新,即使没有源(
test.c
)更改,因为中间先决条件目标是不存在(即过时)。


即使我解决了周围的所有问题并将

Makefile
剥离到最低限度,我也会真正得到这种行为:

$ ls
Makefile        test.c
$ cat Makefile 
libTest.a: libTest.a(test.o)
        $(AR) $(ARFLAGS) $@ $?
$ make
`libTest.a' is up to date.
$ ls
Makefile        test.c
© www.soinside.com 2019 - 2024. All rights reserved.