• Linux C应用编程-2-Makefile编写


    1.基本规则

    1. #规则格式
    2. target ... : prerequisites ...
    3.   command1
    4.   command2
    5.    
    6. #例如
    7. main: main.o stack.o maze.o
    8.    gcc main.o stack.o maze.o -o main
    • main是规则的目标(Target),main.ostack.omaze.o是规则的条件(Prerequisite),command是规则的命令列表。

    • 目标和条件之间的关系是:欲更新目标,必须首先更新它的所有条件;所有条件中只要有一个条件被更新了,目标也必须随之被更新。

    • 如果一个目标拆开写多条规则,则只有一条规则允许有命令列表,其它规则不能有命令列表,否则make会报警告并且采用最后一条规则的命令列表。

    • “更新”就是执行一遍规则中的命令列表(commands),命令列表中的每条命令必须以一个Tab开头。

    make执行步骤

    1. 尝试更新Makefile中第一条规则的目标main,第一条规则的目标称为缺省目标,只要缺省目标更新了就算完成任务了,其它工作都是为这个目的而做的。由于是第一次编译,main文件还没生成,显然需要更新,但规则说必须先更新了main.ostack.omaze.o这三个条件,然后才能更新main

    2. 所以make会进一步查找以这三个条件为目标的规则,这些目标文件也没有生成,也需要更新,所以执行相应的命令(gcc -c main.cgcc -c stack.cgcc -c maze.c,通过隐含规则)更新它们。

    3. 最后执行gcc main.o stack.o maze.o -o main更新main

                                                         Makefile的依赖关系图

    2.隐含规则与模式规则

    • 如果一个目标在Makefile中的所有规则都没有命令列表,make会尝试在内建的隐含规则(Implicit Rule)数据库中查找适用的规则。

    • make的隐含规则数据库可以用make -p命令打印,也是Makefile的格式,包括很多变量和规则。如:

      1. #通过.c文件编译出.o文件的默认规则
      2. # default
      3. OUTPUT_OPTION = -o $@
      4. # default
      5. CC = cc
      6. # default
      7. COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
      8. %.o: %.c
      9. # commands to execute (built-in):
      10.        $(COMPILE.c) $(OUTPUT_OPTION) $<

      $@的取值为规则中的目标,$<的取值为规则中的第一个条件。

      %.o: %.c是一种特殊的规则,称为模式规则(Pattern Rule)。

    3.伪目标

    伪目标是一个标签,这个目标只执行命令,不创建目标,能避免目标与工作目录下的实际文件名冲突。

    PHONY:标签

    例如将 all 设置为伪目标后,尽管在当前目录下有同名的 all 文件,但是在终端输入 make 命令, all 的命令会被正确执行。

    4.变量

    1. foo = $(bar)
    2. bar = Huh?
    3. all:
    4.    @echo $(foo)
    5. #在调用变量是才会把变量$(bar) 展开

    1)自动变量(隐含规则变量)

    自动变量含义
    $@规则的目标文件名
    $<规则的目标的第一个依赖文件名
    $^规则的目标所对应的所有依赖文件的列表,以空格分隔
    $?规则的目标所对应的依赖文件新于目标文件的文件列表,以空格分隔
    $(@D)规则的目标文件的目录部分(如果目标在子目录中)
    $(@F)规则的目标文件的文件名部分(如果目标在子目录中)

    2)预定义变量(隐含规则变量)

    预定义变量含义
    AR归档维护程序,默认值为 ar
    AS汇编程序,默认值为 as
    CCC 语言编译程序,默认值为 cc
    CPPC 语言预处理程序,默认值为 cpp
    RM文件删除程序,默认值为 rm -f
    ARFLAGS传递给 AR 程序的标志,默认为 rv
    ASFLAGS传递给 AS 程序的标志,默认值无
    CFLAGS传递给 CC 程序的标志,默认值无。编译选项,例如-O-g
    CPPFLAGS传递给 CPP 程序的标志,默认值无。预处理选项,例如-D-I
    LDFLAGS传递给链接程序的标志,默认值无

    5.常用make命令行选项

    1)-C

    • -C选项可以切换到另一个目录执行那个目录下的Makefile。

    • 一些规模较大的项目会把不同的模块或子系统的源代码放在不同的子目录中,然后在每个子目录下都写一个该目录的Makefile,然后在一个总的Makefile中用make -C命令执行每个子目录下的Makefile。如Linux内核源代码。

    1. ARCH ?=
    2. CROSS_COMPILE ?= mipsel-openwrt-linux-gnu-
    3. export
    4. ### general build targets
    5. all:
    6.    $(MAKE) all -e -C libloragw
    7.    $(MAKE) all -e -C util_pkt_logger
    8.    $(MAKE) all -e -C util_spi_stress
    9.    $(MAKE) all -e -C util_tx_test
    10.    $(MAKE) all -e -C util_lbt_test
    11.    $(MAKE) all -e -C util_tx_continuous
    12.    $(MAKE) all -e -C util_spectral_scan
    13. clean:
    14.    $(MAKE) clean -e -C libloragw
    15.    $(MAKE) clean -e -C util_pkt_logger
    16.    $(MAKE) clean -e -C util_spi_stress
    17.    $(MAKE) clean -e -C util_tx_test
    18.    $(MAKE) clean -e -C util_lbt_test
    19.    $(MAKE) clean -e -C util_tx_continuous
    20.    $(MAKE) clean -e -C util_spectral_scan
    21. ### EOF

    【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
    【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

      

    6.实例

    文件目录

    1. $ tree
    2. .
    3. ├── makefile
    4. ├── testadd
    5. │   ├── add.c
    6. │   └── add.h
    7. ├── test.c
    8. ├── test.h
    9. └── testsub
    10.   ├── sub.c
    11.   └── sub.h

    Makefile文件

    1. # 预定义变量 指令编译器和选项
    2. CC = gcc            #C 语言编译程序
    3. CFLAGS = -Wall -g   #传递给 CC 程序的标志
    4. LDFLAGS = -L -lFOO  #传递给链接程序的标志 库文件链接
    5. # 自定义变量,目标文件, 变量引用为$(变量)
    6. TARGET = test          
    7. SRC = test.c \
    8.   ./testadd/add.c \
    9.   ./testsub/sub.c
    10. #头文件路径
    11. INC = -I ./ -I ./testadd -I ./testsub
    12. # makefile规则,第一个目标文件为make默认的执行目标
    13. all:test.c ./testadd/add.c ./testsub/sub.c
    14.    gcc -I ./ -I ./testadd -I ./testsub -o test test.c ./testadd/add.c ./testsub/sub.c
    15.    
    16. exe1:$(SRC)         #输入make exe1执行特定的目标规则
    17.    $(CC) $(LDFLAGS) $(INC) -o $(TARGET) $(SRC)
    18.    
    19. $(TARGET):$(SRC)
    20.    $(CC) $(LDFLAGS) $(INC) -o $@ $^        # $@目标文件,$^包含所有的依赖文件
    21. .PHONY:clean        #将目标文件clean设置为伪目标,该目标的规则被执行后不产生文件
    22. clean:              #makefile规则
    23.    rm -f $(TARGET) *.o #*.o是指任意.o文件

  • 相关阅读:
    【机器学习】机器学习重要分支——强化学习:从理论到实践
    Q_PLUGIN_METADATA
    【力扣】买卖股票(121,122,123)
    Kconfig 和 Kbuild
    Teambition企业内部应用开发指南
    SAP SALV14 增强SALV使SALV支持列级别、行级别、单元格级别的编辑模式切换
    Java面试题(JVM篇)
    MySQL数据库操作(创建、修改、删除、查询)
    acl的构成-scheme与id、permissions
    【Vue3 源码解析】ref 全家桶
  • 原文地址:https://blog.csdn.net/irainsa/article/details/128019582