我有两个Makefile,一个用于我的应用程序,另一个用于其依赖库。该库与应用程序链接在一起。库的Makefile是使用一些第三方包含文件编写的,因此无法进行太多更改(特别是,我无法摆脱递归make 用法)。
我想要实现的是自动库(重新)构建作为应用链接规则的先决条件。
我尝试使用特殊的戳记文件执行此操作:粗略地说,库Makefile会在重建发生时更新戳记文件,并且应用程序Makefile使用< em> stamp 文件作为先决条件。
所以我的 app Makefile 看起来像是:
.PHONY: rebuild_libfoo
rebuild_libfoo:
+make -C path/to/libfoo STAMPDIR=out out/libfoo.stamp
all: rebuild_libfoo
out/libfoo.stamp: rebuild_libfoo
app: out/libfoo.stamp <... additional prerequisites ...>
<... recipe with linker execution ...>
all: app
和 libfoo Makefile 如下所示:
$(STAMPDIR)/libfoo.stamp: installation/libs/path/libfoo.a
touch $(STAMPDIR)/libfoo.stamp
installation/libs/path/libfoo.a: <... additional prerequisites ...>
<... recipe with ar execution ...>
all: installation/libs/path/libfoo.a
所以这个解决方案的优点在于,无论什么时候,我都能做到#34;在app目录中,只要发生更改,就会重建库。
但也存在一个大问题:应用链接规则未自动执行 。因此,即使库重建发生,应用程序也会与旧库版本保持链接。但是,如果我运行&#34; make all&#34;在app目录中第二次,然后应用程序与新版本链接 - 这显然是一个非常容易出错的行为。
据我所知,那是因为make在执行任何配方之前读取所有时间戳,所以&#34; rebuild_libfoo&#34;规则,尽管触摸了戳文件,但对应用链接规则没有直接影响。
这有什么解决方法吗?也许,任何方式强制重新读取文件时间戳?
答案 0 :(得分:0)
图书馆需要成为目标的先决条件。用最简单的形式
app: out/libfoo.stamp <... additional prerequisites ...> path/to/libfoo/libfoo.a
<... recipe with linker execution ...>
我正在使用GNU Make 3.81。我已将示例缩减为以下文件:
app.c
Makefile
path/to/libfoo/Makefile
path/to/libfoo/libsrc.c
Library Makefile:
CC = gcc
all: libfoo.a
libfoo.a: libsrc.o
$(AR) -r $@ $?
.PHONY: clean
clean:
rm -f libsrc.o libfoo.a
应用程序Makefile
.DEFAULT_GOAL = all
LD = gcc
.PHONY: rebuild_libfoo
rebuild_libfoo:
+make -C path/to/libfoo $(MAKECMDGOALS)
all: rebuild_libfoo app
app: app.o path/to/libfoo/libfoo.a
.PHONY: clean
clean:
+make -C path/to/libfoo $(MAKECMDGOALS)
rm -f app app.o
在应用程序目录中发出make
,我有
make -C path/to/libfoo
make[1]: Entering directory `/home/digitemp/make/path/to/libfoo'
gcc -c -o libsrc.o libsrc.c
ar -r libfoo.a libsrc.o
ar: creating libfoo.a
make[1]: Leaving directory `/home/digitemp/make/path/to/libfoo'
cc -c -o app.o app.c
cc app.o path/to/libfoo/libfoo.a -o app
第二次发出make
命令,导致无编译等(如预期的那样)。然后输入命令touch path/to/libfoo/libsrc.c
后跟make
会产生以下结果:
make -C path/to/libfoo
make[1]: Entering directory `/home/digitemp/make/path/to/libfoo'
gcc -c -o libsrc.o libsrc.c
ar -r libfoo.a libsrc.o
make[1]: Leaving directory `/home/digitemp/make/path/to/libfoo'
cc app.o path/to/libfoo/libfoo.a -o app
正如预期的那样,编译库对象文件并链接应用程序。