第11课 - 自动生成依赖关系(上)

本文探讨了Makefile中目标文件依赖源文件时存在的问题及改进方案。分析了编译行为导致的缺陷,并提出通过自动化的手段来管理和更新依赖,以提高编译效率。

1. 值得思考的问题

  (1)目标文件(.o)是否只依赖于源文件(.c)

  (2)编译器如何编译源文件和头文件

    

 

2. 编译行为带来的缺陷

  (1)预处理器头文件中的代码直接插入源文件

  (2)编译器只通过预处理后源文件产生目标文件

综合上面两点,规则中以源文件为依赖,命令可能无法执行。

 

3. 下面的 makefile 有没有问题?

该篇博客中涉及的三个源文件,func.h、func.c、main.c

func.h头文件

#ifndef FUNC_H
#define FUNC_H

#define HELLO "hello scott"

void foo();

#endif

 

 

func.c源文件

 

#include "stdio.h"
#include "func.h"

void foo()
{
    printf("void foo() : %s\n", HELLO);
}

 

 

 

main.c源文件

 

#include <stdio.h>
#include "func.h"

int main()
{
    foo();

    return 0;
} 

 

 

 

原始的makefile

 

 

OBJS := func.o main.o

hello.out : $(OBJS)
    @gcc -o $@ $^
    @echo "Target File ==> $@"
 
$(OBJS) : %.o : %.c 
    @gcc -o $@ -c $<

 

 

main.cfunc.c 都包含了 func.h

这个makefile乍一看是没有问题的,但是仔细想一下,当更改 func.h 头文件中的内容时由于目标文件比依赖文件要新,所以程序不会重新编译

  

makefile中,只有当依赖文件目标文件更新时(依赖文件的时间 > 目标文件的时间),才能触发目标对应命令的执行。

解决方案:

  在依赖中添加 func.h 头文件,之后再去更改 func.h头文件中的内容,make会重新编译生成新的hello.out。

 

4. 实验中解决方案的问题

  (1)头文件作为依赖条件出现在每个目标对应的规则中

  (2)当头文件改动,任何源文件都将被重新编译(编译低效)

  (3)当项目中头文件数量巨大时,makefile 将很难维护

 

5. 疯狂的想法

  (1)通过命令自动生成对头文件的依赖

  (2)将生成的依赖自动包含进makefile

  (3)当头文件改动后,自动确认需要重新编译的文件

 

6. 预备工作(原材料)

  — Linux 命令 sed

  — 编译器依赖生成选项 gcc  -MM (gcc  -M)

6.1 Linux 中的 sed 命令

  (1)sed 是一个流编辑器,用于流文本的修改(增/删/查/改

  (2)sed 可用于流文本中的字符串替换

  (3)sed 字符串替换方式为:sed  'ssrcdesg'

    

6.2 sed 的正则表达式支持

  (1)在 sed 中可以用正则表达式匹配替换目标

  (2)并且可以使用匹配的目标生成替换结果

    

6.3 gcc 关键编译选项

 生成依赖关系

  • 获取目标的完整依赖关系

      gcc  -M  test.c

  • 获取目标的部分依赖关系  

      gcc  -MM  test.c

 

7. 小技巧:拆分目标的依赖

   将目标完整依赖拆分为多个部分依赖

   

 

转载于:https://www.cnblogs.com/hoiday/p/9265731.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值