有没有办法在Makefile中自动生成依赖树?

2 投票
2 回答
2112 浏览
提问于 2025-04-16 16:04

抽象问题:
我正在编写一个中型的C++/C程序,这个程序结构非常模块化。它有一个通用接口,可以让你插入多个不同的源代码,这些源代码有相同的函数声明,但实现方式不同,这样就能生成具有不同功能的可执行文件。

我正在设计一个构建系统,负责处理编译的工作。目前,它能够根据配置文件的内容抓取特定的源代码,并将它们放到一个临时文件夹中,使用合适的通用名称。现在,我只需要编译这个项目。

问题是,我的源代码数量是变化的,而这些源代码所依赖的头文件也可能会随着不同的实现而改变。换句话说,静态的makefile无法满足我的需求。

‘1.’
仅仅使用Makefile系统,有没有办法自动生成Main.cpp需要编译的对象文件(.o文件)列表?

我知道我可以通过写一个小的python脚本来实现这个功能,让我的makefile调用这个脚本,然后这个脚本会解析C文件,检查它们的依赖关系,从基础的Main.cpp文件开始,生成一个自定义的makefile。

但是如果有更标准的解决方案,或者能在make中实现的方式,我不想使用这种临时的解决办法。

‘2.’
如果makefile系统无法做到这一点,我应该继续使用我的自定义python脚本,还是有更优雅的解决方案?

...............

为了更清楚地说明,我确实没有一个固定的依赖/源代码/头文件/对象文件列表,我也不想强迫我的最终用户维护这样一个列表。

我需要某种方法,根据我的C文件的内容自动生成这个树状结构。

如果这个问题听起来“傻”,我表示歉意,我对make的世界相对较新——像大多数人一样,我是自学的。

谢谢!

如果有任何问题,请随时问我。

顺便说一下,我的项目源代码太多,无法全部发布,而且出于保密和研究原因,我也不能这样做。

2 个回答

-3

简化构建的一种方法是跳过依赖关系。也就是说,每次都重新编译所有的东西。只有当构建需要做很多次,或者花费的时间比较长(这个“长时间”是根据具体情况来定的),而且依赖关系变化很大的时候,才有必要进行详细的依赖构建。

0

没错,如果你在用GCC的话!这里有我在当前项目中用到的一部分Makefile(为了真实的用途,我会把这个放到公共领域,随便用吧)。

CC=$(CROSS)gcc -c -g -Wall -Werror -ansi -pedantic $(DEFINES) -I./include

%.o: %.c .d/%.d
    # Your build code here

.d/%.d: %.c
    @$(CC) -MM $< -MF $@

-include $(OBJECTS:%.o=.d/%.d)
-include $(LOBJECTS:%.o=.d/%.d)

如果我漏掉了什么,告诉我,我会再检查一下我的Makefile。

注意,$(OBJECTS)是我想要放进最终程序里的对象列表,而$(LOBJECTS)是正在编译成静态库的对象列表。$(OBJECTS)和$(LIB)(由$(LOBJECTS)生成)最后会被编译成一个可执行文件。所以整个过程涉及到不同类型对象的多次构建,然后再链接等等。

哦,对了,确保你先执行mkdir .d,否则可能会失败。你需要在版本控制中检查一个空的.d目录。

唯一需要注意的是,你得列出源文件。不过,如果你愿意,可以设置一个小工具,使用find命令来帮你找到所有源文件。

最后,这个过程可能可以整理得更高效、更易读,使用多个目标(%.o .d/%d)可能会更好;我得去研究一下。谢谢你提醒我。

撰写回答