【问题标题】:old Makefile for building library no longer works under FreeBSD用于构建库的旧 Makefile 不再适用于 FreeBSD
【发布时间】:2018-09-27 00:06:42
【问题描述】:

我最近没有做很多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' 说“有关 make 和 makefile 的更详尽描述,请参阅 PMake - 教程。”

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

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

【问题讨论】:

    标签: makefile freebsd bmake


    【解决方案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
    

    【讨论】:

    • 使用$(LIBTEST): $(LIBOBJ) 不是我想要的,因为它使目标依赖于外部对象文件。用于维护档案的括号语法是古老的,我过去曾在各种风格的 Unix 下使用它,包括 FreeBSD。你可以检查一下 pmake here 和 gmake here] 我当然可以通过简单地使用 gnumake 来解决它,但如果可能的话,我宁愿使用标准的 make。
    • 对,我已经用gmake 进行了尝试,它实际上似乎可以按您的预期工作(我可以想象make 的其他风格或版本也可以)。 gmake 如何理解 self 的成员是档案的先决条件?它有一个(隐式)模式规则使test.o成为libTest.a(test.o)的先决条件,不知道如何用(bsd)make的后缀规则来表达(实际上我不确定它是否可能)。
    • 这意味着尽管test.o 仍然会被构建和使用。我不确定,您要避免的“外部对象文件”是什么意思?您不想使用.o(从本地.c 构建)以防存档已经有该名称的成员?我想我想知道为了正确设计如何实现它(以及为什么将目标文件作为先决条件)所需的行为到底是什么不符合要求。
    猜你喜欢
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2016-04-27
    • 2014-03-13
    • 2012-04-13
    相关资源
    最近更新 更多