zoukankan      html  css  js  c++  java
  • makefile学习笔记(一):概述

    一、make

    make是一个命令工具,是一个解释makefile中指令的命令工具;

    makefile定 义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作;

    makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译;

    不同产商的make各不相同,也有不同的语法,但其本质都是在 “文件依赖性”上做文章。

    二、生成可执行文件的过程

    一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,

    在Windows下 也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)

    然后再把大量的 Object File合成执行文件,这个动作叫作链接(link)。

    编译时,编译器需要的是语法的正确,函数与变量的声明的正确;

    链接时,主要是链接函数和全局变量。

    若我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就 是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

    总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。

    在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未 被声明,编译器会给出一个警告,但可以生成Object File。

    而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不 到,那到就会报链接错误码(Linker Error),

    在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你 需要指定函数的Object File。

    三、makefile设计思路

    假设:我们的工程有x个C文件,和y个头文件

    那么,我们的规则是:
        1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接
        2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序
        3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序

    四、makefile的规则

         target ... : prerequisites ...
                command
                ...
                ...

    target也就是一个目标文件,可以是Object File,也可以是执行文件;
    prerequisites就是,要生成那个target所需要的文件或是目标。
    command也就是make需要执行的命令(任意的Shell命令)。

    这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在 command中。

    说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执 行。

    这就是Makefile的规则。也就是Makefile中最核心的内容。

     五、makefile里有什么?

    makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释

    1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

    2、隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。

    3、变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。

    4、文件指示。其包括了三个部分,

      一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;

      另一个是指根 据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;

      还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲 述。

    5、注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。

    最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。

     六、make的工作方式

    GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
        1、读入所有的Makefile
        2、读入被include的其它Makefile
        3、初始化文件中的变量
        4、推导隐晦规则,并分析所有规则
        5、为所有的目标文件创建依赖关系链
        6、根据依赖关系,决定哪些目标要重新生成
        7、执行生成命令

    1-5步为第一个阶段,6-7为第二个阶段。

    第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。但make并不会完 全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。

    一般来说,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。

    七、make的举例

    # 添加包含路径
    vpath %.S stlib
    vpath %.c stlib stlib/src 
    vpath %.h stlib stlib/cminc stlib/inc
    
    DEFS += -DUSE_STDPERIPH_DRIVER
    
    INCS += -Istlib -Istlib/cminc -Istlib/inc
    
    # 使用其他外设在这里添加
    OBJS += main.o
    OBJS += stlib/startup_stm32f40xx.o 
    OBJS += stlib/system_stm32f4xx.o
    OBJS += stlib/src/stm32f4xx_syscfg.o stlib/src/stm32f4xx_gpio.o 
    
    # 使用了编译优化和硬件浮点数
    CFLAGS += -mcpu=cortex-m4 -mthumb -Wall 
    CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
    CFLAGS += -Os
    CFLAGS += -ffunction-sections -fdata-sections
    
    LFLAGS += -mcpu=cortex-m4 -mthumb
    LFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
    LFLAGS += -Wl,--gc-sections 
    
    # 最后生成的bin文件
    all:blink.bin
    
    clean:
        @rm -f $(OBJS) $(OBJ_FLASH) $(OBJ_SRAM)  
        @rm -f blink.bin blink.elf blinks.bin blinks.elf
        
    blink.bin:blink.elf
        @arm-none-eabi-objcopy -O binary -S $< $@
    blinks.bin:blinks.elf
        @arm-none-eabi-objcopy -O binary -S $< $@
        
    blink.elf:$(OBJS) $(OBJ_FLASH)
        @arm-none-eabi-gcc $(LFLAGS) $^ -Tstlib/STM32F407ZET6_FLASH.ld -o $@
        @arm-none-eabi-size $@
        
    burn:blink.bin
        @st-flash write $< 0x08000000
        
    %.o:%.S
        @echo cc: $<
        @arm-none-eabi-gcc $(CFLAGS) -c $< -o $@
    %.o:%.c
        @echo cc: $<
        @arm-none-eabi-gcc $(CFLAGS) $(DEFS) $(INCS) -c $< -o $@
  • 相关阅读:
    修改服务器时间及时区
    风情万种awk
    追忆似水流年sed
    lvm笔记
    正则不怎么会用
    在CentOS7.5的虚拟环境下新建你的django项目
    Django学习过程中的排错总结
    我一直记不住的vim用法
    关于自建yum源拾遗
    Djangp2.x版本报错找不到模版目录下的文件
  • 原文地址:https://www.cnblogs.com/tjy1805099/p/12612489.html
Copyright © 2011-2022 走看看