• Linux进阶-Makefile


    目录

    Makefile

    Makefile格式

    例程

    Makefile变量:系统变量、自定义变量、自动化变量。

    Makefile模式匹配

    例程改进

    Makefile条件分支

    Makefile常用函数

    patsubst:模式替换函数。pattern:模式,substitute:替换。

    notdir:去目录取文件名函数。

    wildcard:获取匹配模式文件名函数。

    foreach:循环函数

    Makefile解决头文件依赖


    Makefile

    Linux中使用make工具来编译程序(特别是大程序),而make工具所执行的动作依赖于Makefile文件。

    当工程复杂度再上一个高度时,会觉得手写Makefile很麻烦时就需要用CMake、autotools等工具生成Makefile,实际上Windows系统下很多IDE工具内部也是使用类似Makefile的方式组织工程文件的,只不过被封装成图形界面,对用户不可见。

    make命令根据文件更新的时间戳来决定哪些文件需要重新编译,这使得可以避免编译已经编译过的、没有变化的程序,可以大大提高编译效率。

    注意:要想完整地了解Makefile的规则,请参考《GNU Make使用手册》。

    Makefile本质:无论多么复杂的语法,都是为了更好地解决项目文件之间的依赖关系。

    Makefile格式

    Makefile三要素:目标、依赖、命令。 格式如下:

    目标:依赖

    命令

    目标通常是要生成的文件名称,可以是可执行文件或OBJ文件,也可以是一个执行的动作名称(伪目标,比如clean)。

    依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。

    命令是生成目标时所执行的动作。一个规则可以含有几个命令,每个命令占一行。 

    注意:每个命令行前面必须是一个Tab字符。

    命令被执行的条件依赖文件比目标文件新 或 目标文件还没生成

    通常,如果一个依赖发生了变化,就需要规则调用命令以更新或创建目标。但是并非所有的目标都有依赖,例如目标clean的作用只是清除文件,并没有依赖。

    1. targeta:targetb targetc
    2. echo "targeta"
    3. targetb:
    4. echo "targetb"
    5. targetc:
    6. echo "targetc"

    例程

    main.c

    1. #include
    2. int main()
    3. {
    4. play();
    5. stop();
    6. return 0;
    7. }

    mp3.c

    1. #include
    2. void play()
    3. {
    4. printf("play music!\r\n");
    5. }
    6. void stop()
    7. {
    8. printf("stop music!\r\n");
    9. }

     

    Makefile变量:系统变量、自定义变量、自动化变量。

    注意:=延迟赋值是指在调用时才会被赋值。 即图中的echo "$(B)"时才把A的值赋给B。

    Makefile模式匹配

    %:匹配任意多个非空字符,相当于shell的*通配符。

    .o文件默认使用.c文件进行编译。

    例程改进

    学习了Makefile变量,对先前的mp3进行加深。 

    Makefile条件分支

    1. ifeq (var1,var2)
    2. ... //如果var1和var2相等,执行条件
    3. else
    4. ... //如果var1和var2不相等,执行条件
    5. endif
    1. ifneq (var1,var2)
    2. ... //如果var1和var2不相等,执行条件
    3. else
    4. ... //如果var1和var2相等,执行条件
    5. endif

    Makefile常用函数

    Makefile官方手册:https://www.gnu.org/software/make/manual

    patsubst:模式替换函数。pattern:模式,substitute:替换。

    格式:$(patsubst PATTERN,REPLACEMENT,TEXT)。PATTERN为模式,REPLACEMENT为新模式,TEXT为文本。

    示例:$(patsubst %.c,%.o,x.c.c bar.c)

    TEXT中有两个单词,分别为x.c.c和bar.c,将单词去匹配模式,即%.c。

    可知,x.c.c和bar.c都是.c结尾,所以能匹配模式。能匹配模式的话,就把单词去匹配新模式,即x.c.o和bar.o。

    简单来说,把字符串“x.c.c bar.c”中以.c结尾的单词替换成以.o结尾的字符。函数的返回结果是“x.c.o bar.o”。

    notdir:去目录取文件名函数。

    格式:$(notdir NAMES...)

    示例:$(notdir src/foo.c hacks),返回值为“foo.c hacks”。

    wildcard:获取匹配模式文件名函数。

    格式:$(wildcard PATTERN)

    示例:$(wildcard *.c),返回值为当前目录下所有.c源文件列表。

    foreach:循环函数

    格式:$(foreach VAR,LIST,TEXT)

    示例:

    dirs:=a b c d

    $(foreach dir,$(dirs),$(wildcard $(dir)/*))

    首先dir=a,执行$(wildcard $(dir)/*)),即找a目录下的所有文件。然后dir=b,执行$(wildcard $(dir)/*)),即找b目录下的所有文件。

    以此类推,等同于files:=$(wildcard a/* b/* c/* d/*)        

    Makefile解决头文件依赖

    写一个头文件,并把头文件添加到编译器的头文件路径中。gcc -l +"头文件"。

    实时检查头文件的更新情况,一旦头文件发生变化,应该要重新编译所有相关文件。

    1. ARCH?=x86
    2. ifeq ($(ARCH),x86)
    3. CC=gcc
    4. else
    5. CC=arm-linux-guneabihf-gcc
    6. endif
    7. TARGET=shm
    8. BUILD_DIR=build
    9. SRC_DIR=module
    10. INC_DIR=include
    11. CFLAGS=$(patsubst %,-I %,$(INC_DIR))
    12. INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h))
    13. SOURCE=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
    14. OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCE)))
    15. VPATH=$(SRC_DIR)
    16. $(BUILD_DIR)/$(TARGET):$(OBJS)
    17. $(CC) $(^) -o $(@)
    18. $(BUILD_DIR)/%.o:%.c $(INCLUDE) | create_build
    19. $(CC) -c $< -o $@ $(CFLAGS)
    20. .PHONY:clean create_build
    21. clean:
    22. rm -r $(BUILD_DIR)
    23. create_build:
    24. mkdir -p $(BUILD_DIR)

    注意:Makefile的内容OBJS中SOURCES少了个S

  • 相关阅读:
    从虚拟电厂在上海的实践探索看企业微电网数字化的意义
    如何在`Pycharm`中配置基于WSL的`Python Interpreters`,以及配置基于WSL的`Terminal`
    什么是特洛伊木马病毒?
    【 java 面向对象】类的继承和方法重写
    学习react的getSnapshotBeforeUpdate和其他生命周期
    机器学习/人工智能的笔试面试题目——NLP相关面试
    Java面对对象的特征之二:继承性 :why?
    图形像素的逻辑操作&通道分离与合并&图像色彩空间转换
    C++ 系统标准的输入输出流
    分享一个springboot+uniapp基于微信小程序的校医务室健康服务系统源码 lw 调试
  • 原文地址:https://blog.csdn.net/weixin_47077788/article/details/127973834