makefile库依赖 - 解决循环依赖 [英] makefile library dependencies - resolve circular dependency

查看:2805
本文介绍了makefile库依赖 - 解决循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的makefile中创建一个特性,它允许我指定一个特定库依赖的库列表

I am trying to build a feature into my makefile which allows me to specify a list of libraries a particular library depends on

将允许库的依赖项自动重建,如果库的依赖项被重建,并且依赖项添加到链接行。

This will allow dependants of a library to automatically be rebuilt if that library's dependencies are rebuilt, and also have the dependencies added to the link line.

我问了一个相关的问题SO 这里,并通过给定的答案,我想出了以下测试

I asked a related question on SO here, and working through a given answer, I came up with the following test

uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
expand-deps = $1 $(foreach _,$1, $(call expand-deps,$($__deps)))
make-dep-list = $(call uniq,$(call expand-deps,$1))

define make-lib
    $(warning $1_deps: $2)
    # capture the list of libraries this library depends on
    $1_deps = $2
endef

define make-bin
    # show the fully expanded list of libraries this binary depends on
    $(warning $1 dep-list: [$(call make-dep-list,$2)])
endef

#$(eval $(call make-lib, thread, log utils)) circular-dependency log->thread; thread->log
$(eval $(call make-lib, thread, utils))
$(eval $(call make-lib, log, thread))
$(eval $(call make-lib, order, log))
$(eval $(call make-lib, price, log))
$(eval $(call make-bin, test, order price))

运行上述makefile会产生以下结果:

running the above makefile yields the following results:

$ make
makefile:15:  thread_deps:  utils
makefile:16:  log_deps:  thread
makefile:17:  order_deps:  log
makefile:18:  price_deps:  log
makefile:19:  test dep-list: [order price log thread utils ]
make: *** No targets.  Stop.

库可能具有循环依赖性。

It is possible for libraries to have circular dependencies.

例如:日志库是多线程的,因此需要线程库。线程库可以发出日志语句,因此需要日志库。

As an example: The logging library is multi-threaded, so requires the thread library. The thread library can issue log statements, so requires the log library.

如果我取消注释具有循环依赖的行

If I uncomment out the line which has a circular dependency

$(eval $(call make-lib, thread, log utils))
$(eval $(call make-lib, log, thread))

makefile会陷入无限循环。

The makefile will get stuck in an infinite loop.

我如何允许用户指定循环依赖,并突破无限循环?

How can I allow users to specify circular dependencies, and break out of the infinite loop?

推荐答案

是递归地扩展 lib_deps (说)。在这样做的时候,你再次开始扩展 lib_deps 。无限循环(er,stack crash)。要阻止自己,你需要保留一个你已经扩展的东西的列表。退出功能风格,并将答案保存在全局扩展(ugh!)中,类似:

So, your problem is that you are recursively expanding lib_deps (say). While doing that you start expanding lib_deps again. Infinite loop (er, stack crash). To stop yourself you need to keep a list of things that you have already expanded. Falling out of functional style and keeping the answer in the global expansion (ugh!), something like:

expand-deps = \
  $(foreach _,$1, \
    $(if $(filter $_,${expansion}),, \
      $(eval expansion += $_)$(call expand-deps,${$__deps})))

make-dep-list = $(eval expansion :=)$(call expand-deps,$1)${expansion}

define make-lib
  $(warning $1_deps: $2)
  # capture the list of libraries this library depends on
  $1_deps := $2
endef

define make-bin
  # show the fully expanded list of libraries this binary depends on
  $(warning $1 dep-list: [$(call make-dep-list,$2)])
endef

$(eval $(call make-lib,thread,log utils))#circular-dependency log->thread; thread->log
#$(eval $(call make-lib,thread,utils))
$(eval $(call make-lib,log,thread))
$(eval $(call make-lib,order,log))
$(eval $(call make-lib,price,log))
$(eval $(call make-bin,test,order price))

(作为一个练习,你可能想以函数式的方式重写这个函数,全局 $ expansion 将其替换为传递的参数。)

(As an exercise you might like to rewrite this in functional style, i.e., get rid of the global $expansion replacing it with a parameter that gets passed around.)

这篇关于makefile库依赖 - 解决循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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