向库中添加依赖项,并将它们添加到取决于该库的二进制文件 [英] add dependencies to a library, and add them to a binary which depends on that library

查看:266
本文介绍了向库中添加依赖项,并将它们添加到取决于该库的二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有什么:



我有一个非递归的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.

这篇关于向库中添加依赖项,并将它们添加到取决于该库的二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆