makefile - 通过静态库检查 make 依赖项
问题描述
我在 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 变得混乱和复杂。
所以....有没有办法解决这个问题?这样做的正确方法是什么?
解决方案
要获得您要求的结果,您必须为目标文件、库和可执行文件提供生成先决条件列表。
您已经有了对象文件的方法。您生成依赖项列表文件:
$(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
需要来自alpha
和的代码的可执行文件gamma
。规则将如下所示:
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
已经过时了,因此 so is libone.a
,因此 so is prime
。
(一旦你完成了这么多工作,可能会有进一步的改进。)
推荐阅读
- java - 如何使用 JOption 窗格制作受用户影响的选项?
- javascript - 无限滚动(JS)+ iPhone - 图像未加载
- python - 使用 Python 作为后端的 ReactJS
- arrays - 为什么 ArrayPointer 给出分段默认值?
- laravel - 编辑前在 laravel 表单上禁用 CACHE(crome 和 safari 浏览器)
- assembly - 为什么将 300 除以 2 时会出现浮点异常 (SIGFPE)?
- ios - 快速创建按钮
- html - 在 DiagrammeR 节点中使用 HTML 表格时对齐文本中的换行符
- c# - 在 Visual Studio 中使用 .pdb 文件调试 VB 6.0 ActiveX DLL
- handlebars.js - 根据车把中的条件跳过迭代