makefile - 用于构建库的旧 Makefile 不再适用于 FreeBSD
问题描述
最近没怎么做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 的问题。
解决方案
$(LIBTEST): $(LIBTEST)($(LIBOBJ))
表明 (here ) 的先决条件$(LIBTEST)
是libTest.a
该存档的$(LIBOBJ)
(here 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
推荐阅读
- html - 带引导程序的可触发辅助导航栏
- webpack - 在 dontet core razorpages 项目中捆绑 javascript 的最佳方式
- macos - 尝试在 Airflow 上运行 DockerOperator 时权限被拒绝
- java - Scrub 搜索栏在运行时出现问题
- api - 从授权代码流存储 OAuth 访问令牌的最佳方式
- node.js - NPM 发布 - 在 npm 安装期间将文件安装为根文件,而不是在 node_modules 内
- flutter - 在颤动中使用文本字段“取消选择”按钮
- python - Python:第二个窗口中的图片
- python - Django 文件未上传内联表单集 createview
- mysql - 无法连接到烧瓶 - 使用 docker-compose 的 mysql 应用程序