最近我没有做太多的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-A Tutorial。”
这是准确的吗?我的印象是在最新版的FreeBSD中pmake被bsdmake取代了-这是我的问题的根源吗?
注意:我对答案归结为“使用GNU make可以做到这一点”不感兴趣,这是FreeBSD make的问题。
答案 0 :(得分:1)
$(LIBTEST): $(LIBTEST)($(LIBOBJ))
建议$(LIBTEST)
(此处为libTest.a
)的先决条件是该归档文件的$(LIBOBJ)
(此处为test.o
)成员,我不确定{{1 }}可以从中得出结论,但是对我来说(FreeBSD 11.0)它带有make
(这实际上意味着all
)已经是最新的了(另请参见标尺下面的示例)。将行更改为:
libTest.a
似乎很有意义(除非我错过了什么,应该是您想要的),目标文件是库目标的先决条件,并且规则会使用比目标更高的所有先决条件({{1} }。
这又引起我另一条评论。 $(LIBTEST): $(LIBOBJ)
似乎不仅不必要,而且实际上有害,因为这意味着$?
总是在调用rm
时重新编译,并且即使没有源代码,test.o
总是会更新。 )更改,因为中间先决条件目标不存在(即已过时)。
即使我解决所有问题并将make all
剥离到最低限度,我也确实会得到这种行为:
test.c