如何获得递归Makefile中目标的依赖关系?

时间:2019-03-23 10:30:48

标签: makefile gnu-make

当一个项目依赖于其他具有自己的makefile的项目时,将使用递归make,如下所示:

client_obj = Client.objects.create(name='client1')

status = create_database('client1')

def create_database('client1'):
    con = None
    dbname = 'client1'
    con = connect(dbname='postgres', user='***', host = 
    'localhost', password='***')
    con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
    cur = con.cursor()
    cur.execute("SELECT 1 FROM pg_catalog.pg_database WHERE 
    datname = '{}' ".format(dbname))

    exists = cur.fetchone()
    if not exists:
        cur.execute('CREATE DATABASE ' + dbname)
        print "DATABASE NOT EXISTS"
    else:
        print "DATABASE EXISTS"

 cur.close()
 con.close()

但是,明显的问题是make无法确定LIBDIR := path/to/lib LIBNAME := library.a LIBPATH := $(LIBDIR)/$(LIBNAME) $(LIBPATH): $(MAKE) -C $(LIBDIR) $(LIBNAME) 的依赖关系,因为它是在$(LIBPATH)的递归makefile中定义的。

我目前正在使用.PHONY目标来强制检查子项目是否需要重建:

$(LIBDIR)

虽然这使我可以在需要时触发重建,但仍然需要遍历许多目录并调用多次,只是发现不需要做任何事情。

是否有一种方法可以将依赖项从子Makefile中删除,所以我可以将其添加为$(LIBPATH): always_build $(MAKE) -C $(LIBDIR) $(LIBNAME) .PHONY: always_build 的依赖项,以便仅在确实需要调用子Makefile时才调用它。 >

1 个答案:

答案 0 :(得分:1)

如果您的意思是,以自动化的方式,则不会。即使有也没有任何意义。

为了获得这些先决条件,您必须调用make来计算它们。一旦该子品牌计算出它们,它将通知父品牌,并且父品牌将检查先决条件,然后如果有任何过时的情况,它将再次调用子品牌,这将重新计算实际构建目标的先决条件。

远离更高的效率,实际上您要做的工作大约是原来的三倍!

在递归制造方案中,您当前最好的方法是将过时的计算委托给子制造。

您真正要问的是使用一个非递归的make环境,在该环境中,make的单个实例知道所有先决条件并确定什么已经过时。但是请注意,这并不能真正解决“不读取大量makefile”的问题。

最终,如果不检查项目是否完全是最新的,就无法知道项目是完全最新的。这意味着要检查所有依赖关系。