zoukankan      html  css  js  c++  java
  • Makefile复习总结

    001_Makefile的引入及规则

    使用keil、mdk、avr 等工具开发程序时点点鼠标就可以编译了,

    它的内部机制是什么?它怎么组织管理程序?怎么决定编译哪一个文件?

    gcc -o  test   a.c  b.c     //简单

    a.c ==>APP     执行编译(预处理、编译、汇编)、链接

    a.c ==> xxx.s ==> xxx.o

    b.c ==> xxx.s ==> xxx.o

    再链接成test的执行程序。

    缺点:若对其中一个文件进行修改,则对所有文件都再处理一次

    Makefile通过比较时间来判断哪些文件被修改过。

     Makefile最基本的语法是规则;

    编写文件:a.c   b.c   c.c

    a.c
    #include <stdio.h>
    
    int main()
    {
        func_b();
        func_c();
        return 0;
    }
    
    
    b.c
    #include <stdio.h>
    
    void func_b()
    {
        printf("This is B
    ");
    }
    
    c.c
    #include <stdio.h>
    
    void func_c()
    {
        printf("This is C
    ");
    }

    编写Makefile如下:

    test:a.o b.o c.o
        gcc -o test a.o b.o c.o
    
    a.o:a.c
        gcc -c -o a.o a.c
    
    b.o:b.c
        gcc -c -o b.o b.c
    
    c.o:c.c
        gcc -c -o c.o c.c

    运行j结果:

    从运行结果看:当我们利用touch命令(只更改文件时间,不修改内容)修改后,确实执行了修改后的命令,不做任何改动直接touch,会提示test已经是最新的了。

     总结:

    Makefile的核心———规则:

    目标: 依赖1  依赖2  。。。

    【TAB】命令

    当“目标文件”不存在,

    某个依赖文件比目标文件“新”,

    则:执行“命令”

    002_Makefile的语法

    a. 通配符: %.o

      $@    表示目标

      $<      表示第一个依赖文件

      $^       表示所有依赖文件

     通过通配符简化上面的Makefile为:

    test:a.o b.o c.o
        gcc -o test $^
    
    %.o:%.c
        gcc -c -o $@ $<

    clean:
      rm *.o test

    以上写法存在不足,若目录中存在以clean命名的文件时,则执行make操作的时候就无法执行删除操作。怎么办能?此时利用假想目标就能很好的解决这个问题。

    b. 假想目标:.PHONY

    通过假想目标操作,修改Makefile为:

    test:a.o b.o c.o
        gcc -o test $^
    
    %.o:%.c
        gcc -c -o $@ $<
    
    clean:
      rm *.o test
    
    .PHONY: clean

    这样即使有同名文件也可以执行clean。

    c. 即时变量、延时变量、export

    简单变量(即时变量):

    A:= xxx       # A 的值即刻确定,在定义时

    B = xxx       #  B 的值使用到时才确定

    Makefile如下:

    A:= $(C)
    B = $(C)
    #C = abc
    
    all:
        @echo A = $(A)
        @echo B = $(B)
    C = abc

    运行结果如下:

    C = abc放在前面和放在后面对结果无影响,当执行make命令的时候,make程序本身会把整个Makefile读进去来分析,然后解析内部的变量,所以放前面和放后面不影响。

    :=       # 即时变量

    =   # 延时变量

    ?=  #延时变量,如果是第1次定义才有效,如果在前面该变量已定义则忽略这句

    +=    # 附加,它是即时变量还是延时变量取决于前面的定义

     003_Makefile函数

    a. $(foreach  var, list , text)

    b. $(filter pattern... ,text)      # 在text中取出符合pattern格式的值

      $( filter-out   pattern ... ,text)   # 在text中取出不符合pattern格式的值

    c.  $ (wildcard  pattern)        # pattern定义了文件名的格式,

                      # wildcard 取出其中存在的文件

    d. $(patsubst  pattern,  replacement,  $(var) )      # 从列表中取出每一个值

                            #  如果符合pattern

                            #   则替换为replacement

    004_Makefile实例

    a. 改进:支持头文件依赖

    b. 添加CFLAGS

    c. 编写裸板Makefile

  • 相关阅读:
    JavaScript-4.2函数,变量作用域---ShinePans
    2019-8-31-C#-简单读取文件
    2019-8-31-C#-简单读取文件
    2019-8-31-C#-大端小端转换
    2019-8-31-C#-大端小端转换
    2019-6-11-C#-标准性能测试
    2019-6-11-C#-标准性能测试
    2018-2-13-win10-uwp-右击选择-GridViewItem-
    2018-2-13-win10-uwp-右击选择-GridViewItem-
    2019-8-31-NuGet-如何设置图标
  • 原文地址:https://www.cnblogs.com/Liu-Jing/p/8393918.html
Copyright © 2011-2022 走看看