将依赖项添加到库中,并将它们添加到依赖于该库的二进制文件中

add dependencies to a library, and add them to a binary which depends on that library

我有:

我有一个非递归生成文件,它搜索 module.mk 个文件,并包含它们

modules := $(shell find . -name module.mk)
include $(modules)

如果我想创建一个静态库module.mk看起来像这样:

$(eval $(call make-lib, test_lib))

这将找到当前目录中所有 .cpp 个文件的列表,并调用 do-make-lib,其中:

do-make-lib定义如下(省略部分细节):

define do-make-lib
    $(addprefix $(addprefix $(LIB_DIR)lib,),.a): $(call src_to_obj, )
    @$(AR) $(ARFLAGS) $$@ $$?
endef

现在,当我构建一个 binary 时,module.mk 看起来像这样:

$(eval $(call make-bin, test_bin, test_lib))

同样,make-bin会找到当前目录下所有.cpp个文件的列表,调用do-make-bin,with:

所以,你有这些定义(比方说)

test_lib_DEPS := lib5 lib4 lib3 lib2 lib1
lib5_DEPS := lib6 lib3
lib6_DEPS := lib1
lib2_DEPS := lib1

手工展开test_lib_DEPS,发现首先要lib5,然后递归展开$lib5_DEPS,再递归展开lib4$lib4_DEPS等.深度优先扩展

expand = $(foreach _,,$_ $(call expand,${$__DEPS}))

$(error [$(call expand,${test_lib_DEPS})])

这给出了

$ make
1:9: *** [lib5 lib6 lib1  lib3  lib4  lib3  lib2 lib1  lib1 ].  Stop.

还不错。您可能希望梳理出这些重复项。 $(sort) 符合要求,但在链接时您可能希望保留顺序。按照类似的参数,我们可以用函数式风格编写一个 uniq 函数:return 参数的第一个元素,然后是 uniq 的递归调用,但是缺少第一个元素,因为我们已经有了。

test_lib_DEPS := lib5 lib4 lib3 lib2 lib1
lib5_DEPS := lib6 lib3
lib6_DEPS := lib1
lib2_DEPS := lib1

uniq = $(if ,$(firstword ) $(call uniq,$(filter-out $(firstword ),)))
depth-first = $(foreach _,,$_ $(call depth-first,${$__DEPS}))
expand = $(call uniq,$(call depth-first,))

$(error [$(call expand,${test_lib_DEPS})])

给予

$ make
1:10: *** [lib5 lib6 lib1 lib3 lib4 lib2 ].  Stop.