问题描述
我有什么:
我有一个非递归的makefile搜索 module.mk
modules:= $(shell find。-name module.mk)
include $(modules)
如果我要创建静态库, module.mk
看起来像这样:
$(eval $(call make-lib, test_lib))
这将找到所有 .cpp
文件,并调用 do-make-lib
,其中包含:
-
$ 1
是图书馆名称 -
$ 2
源文件列表
do-make-lib
定义如下一些细节省略为简洁):
define do-make-lib
$(addprefix $(addprefix $(LIB_DIR )lib,$ 1),。a):$(call src_to_obj,$ 2)
@ $(AR)$(ARFLAGS)$$ @ $$?
endef
现在,当我构建一个二进制 c $ c> module.mk 看起来像这样:
$(eval $(call make-类似地, make-bin $ c $ c>将在当前目录中找到所有 .cpp
文件的列表,并调用 do-make-bin
,其中:
-
$ 1
是二进制名称
-
$ 2
是源文件列表
-
$ 3
作为要链接的静态库列表
do-make-bin
定义如下:
define do-make-bin
$(addprefix $(BIN_DIR),$ 1): $(call src_to_obj,$ 2)\\ $
$(addsuffix .a,$(addprefix $(LIB_DIR)lib,$ 3) \\
-L / usr / lib -L $(LIB_DIR)\
-Wl $(,) - Bstatic $(addprefix -l,$ 3)\
-o $$ @
endef
我的问题:
库依赖于其他库。当我链接二进制,我需要给一个所有它依赖的库,以正确的顺序的列表。
$(eval $(call make-bin,my_bin,lib5 lib4 lib3 lib2 lib1))
我想要的:
我想传递一个额外的参数 make-lib
这是依赖关系的列表
$(eval $(call make-lib,test_lib,lib3 lib2 lib1))
do-make-lib
然后我可以创建一个变量,其中包含正在构建的库的名称,它捕获依赖性
伪代码(不确定语法 - 如何从其他变量构建变量?)
$ 1_DEPS = $ 3
然后当构建我的二进制文件时,我可以将libs的依赖包括为依赖,并将它们添加到链接行
伪代码(不确定语法)
define do-make-bin
#构建一个依赖列表,例如:lib2_DEPS lib2_DEPS lib1_DEPS
$ 1_DEPS = $ (addsuffix _DEPS,$ 3)
$(addprefix $(BIN_DIR),$ 1):$(call src_to_obj,$ 2)\
$(addsuffix .a,$(addprefix $(LIB_DIR )lib)$ b)
$(addsuffix .a,$(addprefix $(LIB_DIR)lib,$($ 1_DEPS)))))#include libs dependencies as二元
@ $(CXX)$(call src_to_obj,$ 2)\
-L / usr / lib -L $(LIB_DIR)\
-Wl $(,) - Bstatic $(addprefix -l, $ 3)$(addprefix -l,$($ 1_DEPS)))\#链接依赖关系的依赖关系
-o $$ @
endef
pre>
问题:
- 这是否可行?
- 有人可以帮我处理语法吗?
解决方案这些定义(例)
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 _,$ 1,$ _ $(call expand,$ {$ __ DEPS}))
$(错误[$ (call expansion,$ {test_lib_DEPS})])
$ make
1:9:*** [lib5 lib6 lib1 lib3 lib4 lib3 lib2 lib1 lib1]。停止。
很不错。你可能希望挑逗那些重复的。 $(sort)
符合帐单,但是当链接时,您可能想要保留排序。根据类似的参数,我们可以在函数式中写一个 uniq
函数:返回参数的第一个元素,然后递归调用 uniq $
test_lib_DEPS:= lib5 lib4 lib3 lib2 lib1
lib5_DEPS:= lib6 lib3
lib6_DEPS:= lib1
lib2_DEPS:= lib1
uniq = $(如果$ 1,$(firstword $ 1)$(call uniq,$ (filter-out $(firstword $ 1),$ 1)))
depth-first = $(foreach _,$ 1,$ _ $(call depth-first,$ {$ __ DEPS}))
expand = $(call uniq,$(call depth-first,$ 1))
$(错误[$(call expand,$ {test_lib_DEPS})])
提供
$ make
1:10:*** [lib5 lib6 lib1 lib3 lib4 lib2]。停止。
What I have:
I have a non-recursive makefile which searches for module.mk
files, and includes them
modules := $(shell find . -name module.mk)
include $(modules)
If I want to create a static library, the module.mk
looks like this:
$(eval $(call make-lib, test_lib))
Which will find a list of all .cpp
files in the current directory, and call do-make-lib
, with:
$1
being the library name$2
being the list of source files
do-make-lib
is defined as follows (some details omitted for brevity):
define do-make-lib
$(addprefix $(addprefix $(LIB_DIR)lib,$1),.a): $(call src_to_obj, $2)
@$(AR) $(ARFLAGS) $$@ $$?
endef
Now when I build a binary, module.mk
looks like this:
$(eval $(call make-bin, test_bin, test_lib))
Similarly, make-bin
will find a list of all .cpp
files in the current directory, and call do-make-bin
, with:
$1
being the binary name$2
being the list of source files$3
being the list of static libraries to link against
do-make-bin
is defined as follows:
define do-make-bin
$(addprefix $(BIN_DIR),$1): $(call src_to_obj,$2) \
$(addsuffix .a,$(addprefix $(LIB_DIR)lib,$3))))
@$(CXX) $(call src_to_obj,$2) \
-L/usr/lib -L$(LIB_DIR) \
-Wl$(,)-Bstatic $(addprefix -l,$3) \
-o $$@
endef
My problem:
Libraries depend on other libraries. When I link the binary, I need to give is a list of all the libraries it depends on, in the correct order.
$(eval $(call make-bin, my_bin, lib5 lib4 lib3 lib2 lib1))
What I want:
I would like to pass an additional parameter to make-lib
which is a list of dependencies
$(eval $(call make-lib, test_lib, lib3 lib2 lib1))
In do-make-lib
I could then make a variable which includes the name of the library being built, which captures the dependencies
pseudo code (not sure of syntax - how do I build a variable from another variable?)
$1_DEPS = $3
Then when building my binary I can include the libs' dependencies as dependencies of the binary, and also add them to the link line
pseudo code (not sure of syntax)
define do-make-bin
# build a list of dependencies, eg: lib2_DEPS lib2_DEPS lib1_DEPS
$1_DEPS = $(addsuffix _DEPS,$3)
$(addprefix $(BIN_DIR),$1): $(call src_to_obj,$2) \
$(addsuffix .a,$(addprefix $(LIB_DIR)lib,$3)) \
$(addsuffix .a,$(addprefix $(LIB_DIR)lib,$($1_DEPS))))) # include the libs dependencies as dependencies of the binary
@$(CXX) $(call src_to_obj,$2) \
-L/usr/lib -L$(LIB_DIR) \
-Wl$(,)-Bstatic $(addprefix -l,$3) $(addprefix -l,$($1_DEPS))) \ # link against dependencies' dependencies
-o $$@
endef
Questions:
- Is this feasible?
- Can someone help me with the syntax?
解决方案 So, you have these definitions (say)
test_lib_DEPS := lib5 lib4 lib3 lib2 lib1
lib5_DEPS := lib6 lib3
lib6_DEPS := lib1
lib2_DEPS := lib1
Expanding test_lib_DEPS
by hand, we find we first want lib5
, followed by the recursive expansion of $lib5_DEPS
, then lib4
and $lib4_DEPS
etc. A depth-first expansion.
expand = $(foreach _,$1,$_ $(call expand,${$__DEPS}))
$(error [$(call expand,${test_lib_DEPS})])
This gives
$ make
1:9: *** [lib5 lib6 lib1 lib3 lib4 lib3 lib2 lib1 lib1 ]. Stop.
Pretty good. You may wish to tease out those duplicates. $(sort)
fits the bill, but when linking you probably want to preserve ordering. Following similar arguments we can write a uniq
function in functional style: return the first element of the arguments, followed by a recursive call of uniq
, but with the first element missing since we already have it.
test_lib_DEPS := lib5 lib4 lib3 lib2 lib1
lib5_DEPS := lib6 lib3
lib6_DEPS := lib1
lib2_DEPS := lib1
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
depth-first = $(foreach _,$1,$_ $(call depth-first,${$__DEPS}))
expand = $(call uniq,$(call depth-first,$1))
$(error [$(call expand,${test_lib_DEPS})])
Giving
$ make
1:10: *** [lib5 lib6 lib1 lib3 lib4 lib2 ]. Stop.
这篇关于向库中添加依赖项,并将它们添加到取决于该库的二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!