通过静态库检查依赖项

问题描述 投票:0回答:1

我正在在Linux上使用make构建多个可执行文件。每个可执行文件都有自己的文件夹,该文件包含一个小的makefile,其中包含共享的makefile.rules。因此,要构建项目,我用父makefile分别调用每个makefile。

喜欢这个:

# Find Makefiles
MKFLS += $(subst Makefile,,$(shell find */ -name Makefile ))

# Standard build rules, pass down to subordinate make files
all debug install: tags
    @$(foreach folder,$(MKFLS), $(MAKE) -C $(folder) $@ || exit;)

我将共享代码放在静态库中。每个文件都有自己的文件夹和makefile。在使用以下方式为exe或lib构建可执行库和静态库时,我正在建立依赖关系:

$(CC) $(CFLAGS) -c -MMD -MP -o $@ $<

然后包括生成的文件(仅针对该exe或lib):

-include $(OBJECTS:.o=.d)

现在,如果库的源文件或内部头文件之一发生更改,我想确保可执行文件能够生成。我尝试包括该库的生成的.d文件,但这没有用。

首先,每个可执行文件都定义了静态库及其生成位置:

# My Libraries
LOCALLIBS += $(UTILSLIB)/libone.a
LIBSRC += $(UTILSDIR)/onelib
LOCALLIBS += $(UTILSLIB)/libtwo.a
LIBSRC += $(UTILSDIR)/twolib

然后在包含的全局规则Makefile中:

# Rules For Library Dependencies
# Include library dependencies if they exist
-include $(shell find $(LIBSRC) -name \*.d )

# Rule to make libraries that are part of this source tree
$(LOCALLIBS):
    $(foreach folder,$(LIBSRC), $(MAKE)-C $(folder) $(MAKECMDGOALS) || exit;)
    @touch $(LOCALLIBS)

我不认为依赖项会贯穿静态库。因此,即使libone.a被构建,可执行文件也不会被构建。将需要第二次运行。我可以尝试使我的可执行文件依赖于libone.a中的对象,但是现在我的makefile变得凌乱和复杂。

所以...。有没有办法解决这个问题?什么是正确的方法?

makefile gnu-make
1个回答
0
投票

要获得所需的结果,必须提供目标文件,库和可执行文件的必备清单。

您已经有了目标文件的方法。您生成了依赖项列表文件:

$(CC) $(CFLAGS) -c -MMD -MP -o $@ $<

然后包括它们:

-include $(OBJECTS:.o=.d)

到目前为止,很好。 (我认为这已经可以正常工作了–您没有给我们足够的Makefile来进行测试。)

此方法将不是适用于库。它适用于目标文件,因为源文件包含头文件列表(如#include指令),并且编译器($(CC))知道如何将它们转换为必备列表。库构建工具($(AR)或您正在使用的任何工具)没有要读取的此类文件,也没有构建此类列表的方法。但是不要紧;对于每个库,您必须在其中指定想要的内容列表[[以某种方式,因此您的库规则应类似于以下内容:

libone.a: alpha.o beta.o $(AR) -cvq $@ $^. # or whatever you use
这会照顾图书馆。现在是可执行文件。假设您有一个可执行文件prime,它需要alphagamma中的代码。该规则将如下所示:

prime: gamma.o libone.a $(CXX) -o $@ $^. # or whatever you use

就是这样。可执行文件prime不依赖于gamma.h。如果更改gamma.h,Make将注意到gamma.o已过时,因此prime也已过时。并且prime不依赖于alpha.h;如果更改alpha.h,Make将注意到alpha.o已过时,因此libone.a也已过时,因此prime也已过时。

(一旦您做了很多工作,可能会有进一步的改进。)

© www.soinside.com 2019 - 2024. All rights reserved.