• Makefile文件详解


    目录

    1、介绍

    2、常用函数详解

    2.1 patsubst函数

    2.2 foreach函数

    2.3 wildcard函数

    2.4 notdir函数


    1、介绍

            通过makefile的编写来管理工程文件,对工程下不同目录中的文件的编译、链接的方式、顺序进行描述。在编写makefile后,编译工程只要求输入make命令,极大的提高了编译效率。

    2、常用函数详解

            (实例:正点原子imx6ul开发板,裸机开发bsp章节的makefile文件)

    1. CROSS_COMPILE ?= arm-linux-gnueabihf-
    2. TARGET ?= bsp
    3. CC := $(CROSS_COMPILE)gcc
    4. LD := $(CROSS_COMPILE)ld
    5. OBJCOPY := $(CROSS_COMPILE)objcopy
    6. OBJDUMP := $(CROSS_COMPILE)objdump
    7. INCDIRS := imx6ul \
    8. bsp/clk \
    9. bsp/led \
    10. bsp/delay
    11. SRCDIRS := project \
    12. bsp/clk \
    13. bsp/led \
    14. bsp/delay
    15. INCLUDE := $(patsubst %, -I %, $(INCDIRS))
    16. SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
    17. CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
    1. SFILENDIR := $(notdir $(SFILES))
    2. CFILENDIR := $(notdir $(CFILES))
    3. SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
    4. COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
    5. OBJS := $(SOBJS) $(COBJS)
    6. VPATH := $(SRCDIRS)
    7. .PHONY: clean
    8. $(TARGET).bin : $(OBJS)
    9. $(LD) -Timx6ul.lds -o $(TARGET).elf $^
    10. $(OBJCOPY) -O binary -S $(TARGET).elf $@
    11. $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
    12. $(SOBJS) : obj/%.o : %.S
    13. $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
    14. $(COBJS) : obj/%.o : %.c
    15. $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
    16. clean:
    17. rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

            第 1~7行定义了一些变量,除了第 2行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第 1行即可。第 2行的变量 TARGET目标名字,不同的例程肯定名字不一样。


            第 9行的变量 INCDIRS包含整个工程的 .h头文件目录,文件中的所有头文件目录都要添加到变量 INCDIRS中。比如本例程中包含 .h头文件的目录有 imx6ul、 bsp/clk、 bsp/delay和 bsp/led所以就需要在变量 INCDIRS中添加这些目录,即:

            INCDIRS := imx6ul bsp/clk bsp/led bsp/delay

            仔细观察的话会发现第 9~11行后面都会有一个符号“ “\”,这个相当于“换行符”。


            第 14行是变量 SRCDIRS,和变量 INCDIRS一样,只是 SRCDIRS包含的是整个工程的所
    有 .c 和 .S 文件目录。


            第 19行的变量 INCLUDE使用 到了函数 patsubst,通过函数 patsubst给变量 INCDIRS添加
    一个“ “-I”,即

    INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay

    加“ “-I”的目的是因为 Makefile语法要求指明头文件目录的时候需要加上“ “-I”。

    2.1 patsubst函数

    函数patsubst:

            作用:用于将文件模式进行替换。

            格式:$(patsubst 原模式, 目标模式, 文件列表)


            第 21行变量 SFILES保存工程中所有的 .s汇编文件 (包含绝对路径 ),变量 SRCDIRS已经存放了工程中所有的 .c和 .S文件,所以我们只需要从里面挑出所有的 .S汇编文件即可,这里借助了函数 foreach和函数 wildcard,最终 SFILES如下:

    SFILES := project/start.S

     foreach 函数_微尘hjx的博客-CSDN博客_foreach函数

    2.2 foreach函数

    foreach函数的语法

    格式:

            $(foreach VAR,LIST,TEXT)
    函数功能:

            这个函数的工作过程是这样的:如果需要(存在变量或者函数的引用),首先展开变量“VAR”和“LIST”的引用;而表达式“TEXT”中的变量引用不展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量“VAR”,然后执行“TEXT”表达式。重复直到“LIST”的最后一个单词(为空时结束)。“TEXT”中的变量或者函数引用在执行时才被展开,因此如果在“TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到的不同的值。
    返回值:

            空格分割的多次表达式“TEXT”的计算的结果。


            我们来看一个例子,定义变量“files”,它的值为四个目录(变量“dirs”代表的a、b、c、d四个目录)下的文件列表:


            dirs := a b c d
            files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))


            例子中,“TEXT”的表达式为“$(wildcard $(dir)/*)”。表达式第一次执行时将展开为“$(wildcard a/*)”;第二次执行时将展开为“$(wildcard b/*)”;第三次展开为“$(wildcard c/*)”;….;以此类推。所以此函数所实现的功能就和一下语句等价:
            files := $(wildcard a/* b/* c/* d/*)

     wildcard函数_微尘hjx的博客-CSDN博客_wildcard函数

    2.3 wildcard函数

    wildcard函数的语法

    作用: 

            扩展通配符,一般我们可以使用$(wildcard *.c)来获取工作目录下的所有的.c文件列表。

    格式:

            $(wildcard PATTERN...) 

            

    举例:

            $(patsubst %.c,%.o,$(wildcard *.c))

            首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。


            第 22行变量 CFILES和变量 SFILES一样,只是 CFILES保存工程中所有的 .c文件 (包含绝
    对路径 ),最终 CFILES如下:

    CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c


            第 24和 25行的变量 SFILENDIR和 CFILENDIR包含所有的 .S汇编文件和 .c文件,相比变
    量 SFILES和 CFILES SFILENDIR和 CFILNDIR只是文件名,不包含文件的绝对路径。使用
    函数 notdir将 SFILES和 CFILES中的路径去掉即可, SFILENDIR和 CFILENDIR如下:

    SFILENDIR = start.S

    CFILENDIR = main.c bsp_clk.c bsp_led.c bsp_delay.c

     Makefile中notdir函数使用方法_yanlaifan的博客-CSDN博客_makefile notdir

    2.4 notdir函数

    notdir函数的语法

    作用:

            notdir用于去掉文件的绝对路径,只保留文件名。

    格式:

            $(notdir 文件列表)


            第 27和 28行的变量 SOBJS和 COBJS是 .S和 .c文件编译以后对应的 .o文件目录,默认所
    有的文件编译出来的 .o文件和源文件在同一个目录中,这里我们将所有的 .o文件都放到 obj文
    件夹下, SOBJS和 COBJS内容如下:

    SOBJS = obj/start.o

    COBJS = obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o


            第 29行变量 OBJS是变量 SOBJS和 COBJS的集合,编译完成以后所有的 .o文件就全部存放到了 obj目录下,如下:

    OBJS = obj/start.o obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o

            33-46行是.elf和.o文件的生成,就不细说了,详细看正点原子官方手册资料。


    待更新...

  • 相关阅读:
    Spring Boot 2.x系列【9】功能篇之SpringApplication启动参数使用详解
    【kali-漏洞利用】(3.4)免杀Payload 生成工具(下):Veil后门使用、监听失败原因
    【Codeforces Round #811 (Div. 3)】【题目解析+AK代码】
    ARM TrustZone技术介绍
    【EhCache: 一款Java的进程内缓存框架】EhCache 是什么、代码实战 Demo
    计算机毕业设计Java文档资料管理系统(源码+系统+mysql数据库+Lw文档)
    常见凭证获取方法
    .net8 blazor auto模式很爽(三)用.net8的Blazor自动模式测试,到底在运行server还是WebAssembly
    07查询表达式 及 page分页、order 排序《ThinkPHP6 入门到电商实战》
    SpringCloud-OAuth2(一):基础篇
  • 原文地址:https://blog.csdn.net/qq_40528849/article/details/126279450