makefile自动生成依赖

本文介绍了如何利用GCC的-M和-MM选项自动生成Makefile中的头文件依赖,并结合`include`指令来实现自动更新。通过分析一个简单的自动依赖Makefile例子,初学者可以了解如何编写和理解这种功能的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要参考 Makefile自动生成头文件依赖 和GNU make 中文手册(这个文档网上挺多,可自行百度)。

网上关于makefile的资料很多,甚至我买的linux编程书上都对它有些简单的介绍,不过很多资料都不是很详细。这里我推荐“GNU makefile中文手册“,很适合作为小白学习makefile的入门书籍,不过可能有些过于详细,可以跳着看。

一般而言,实用的makefile文件应当能够实现 自动生产头文件依赖 功能。而自动产生头文件功能的实现则依赖于编译器提供的自动产生依赖关系的功能。对于GCC而言,编译时实用 ”-M“ 选项,其将输出源文件中包含的包括标准库头文件在内的依赖关系,而 ”-MM“ 选项的输出则不会包含标准库头文件。

如对于程序

#include<stdio.h>
#include "./a.h"

extern void function_two();
extern void function_three();

int main()
{
	function_two();
	function_three();

	return 0;
}
对于gcc,如果实用 -M 选项,输出为

main.o: main.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h a.h

如果使用 -MM 选项,输出为

main.o: main.c a.h
具体区别非常清楚了。

可以看出使用 -MM 选项的GCC的输出和我们在makefile中写的依赖关系基本相同。那么makefile

在使用 Makefile 进行项目构建时,自动生成依赖关系是一个重要的功能,它能够确保头文件的更改也能触发相关源文件的重新编译。这一机制通常通过编译器(如 GCC)提供的 `-MM` 选项来实现,该选项可以生成源文件所依赖的头文件列表。 为了将这些自动生成依赖信息集成到 Makefile 中,常见的做法是为每个 `.c` 源文件生成一个对应的 `.d` 文件,其中包含其依赖关系[^1]。这些 `.d` 文件随后被包含进主 Makefile 中,使得 make 工具能够在头文件发生变化时正确地重新编译受影响的目标文件[^2]。 具体实现步骤如下: - 使用 `$(CC) -MM source.c > source.d` 命令生成每个源文件的依赖文件[^1]。 -Makefile 中使用 `include` 指令引入所有 `.d` 文件,这样 make 就会读取这些依赖信息并将其纳入整个构建流程中[^4]。 - 为了确保每次构建时都能获取最新的依赖信息,可以在 Makefile 中添加一个专门用于生成依赖文件的目标(例如 `depend`),并在构建主目标之前调用它[^2]。 下面是一个简化版的 Makefile 示例,演示了如何利用 GCC 的 `-MM` 功能和 `include` 指令来自动生成和管理依赖关系: ```makefile EXE=main CC=gcc SRC=$(wildcard *.c) OBJ=$(SRC:.c=.o) CFLAGS=-g all: depend $(EXE) depend: @$(CC) -MM $(SRC) > .depend -include .depend $(EXE): $(OBJ) $(CC) $(OBJ) -o $(EXE) clean: rm -f $(EXE) $(OBJ) .depend ``` 在这个示例中,`depend` 目标负责生成 `.depend` 文件,该文件包含了所有源文件与其依赖头文件之间的关系。`-include .depend` 行确保了这些依赖信息被加载到 Makefile 中,从而允许 make 根据需要更新目标文件。 此外,需要注意的是,GCC 默认会根据输入文件名自动推导出输出对象文件的名字。因此,在某些情况下,可以省略 `-o` 参数,直接使用 `gcc -c main.c` 来编动生成 `main.o` 文件[^5]。 综上所述,通过结合使用编译器的依赖生成能力和 Makefile 的 `include` 特性,可以有效地管理和维护复杂的项目结构,保证项目的高效构建与维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值