• 编写通用的Makefile


    一个应用程序的形成是少不了一下几个步骤的。

    1. 预处理    #检查语法错误、包含头文件、展开#if、#define等宏定义

    2. 编译     #把.c文件转换为汇编文件.s

    3. 汇编     #把.s汇编转换为机器码.o

    4. 链接     #和库文件等组合在一起

    只有经过了上面几个步骤才能形成一个可执行的应用程序

     用gcc -o test test.c这个命令就可以将上面的四个步骤全部完成。加上编译指令-v可以看到详细的编译过程。

    介绍一下Makefile中常用的函数。

    wildcard 

    用法是:

      $(wildcard PATTERN...)

    在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。

    一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。

    foreach

    $(foreach VAR,LIST,TEXT)

    函数功能:

      如果需要(存在变量或者函数的引 用) ,首先展开变量“VAR”和“LIST”的引用;

      而表达式“TEXT”中的变量 引用不展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量 “VAR” ,然后执行“TEXT”表达式。

      重复直到“LIST”的最后一个单词(为 空时结束) 。

      “TEXT”中的变量或者函数引用在执行时才被展开,因此如果在 “TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到 的不同的值。

    patsubst

      格式:$(patsubst <pattern>,<replacement>,<text> )

      名称:模式字符串替换函数——patsubst。

      功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“”来转义,以“\%”来表示真实含义的“%”字符)

      返回:函数返回被替换过后的字符串。 

    filter

     $(filter PATTERN…,TEXT)

      函数名称:过滤函数—filter。

      函数功能:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所 有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字 符“%”。存在多个模式时,模式表达式之间使用空格分割。

      返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。

       函数说明:“filter”函数可以用来去除一个变量中的某些字符串.

     在编译的时候加上-Wp,-MD即可自动生成依赖文件。

    如果需要编译子目录下的源文件则在Makefile中加上obj-y += 子目录的名称

    在子目录的makef中写上obj-y += 子目录中的源文件.o

    示例:

    #
    #    Makefile  topdir
    #
    CROSS_COMPILE     :=     arm-linux-          #指定交叉工具链
    AS                :=    $(CROSS_COMPILE)as
    LD                :=    $(CROSS_COMPILE)ld
    CC              :=    $(CROSS_COMPILE)gcc
    CPP                :=    $(CC) -E
    AR                 :=    $(CROSS_COMPILE)ar
    NM                :=    $(CROSS_COMPILE)nm
    
    STRIP             :=    $(CROSS_COMPILE)strip
    OBJCOPY            :=    $(CROSS_COMPILE)objcopy
    OBJDUMP            :=    $(CROSS_COMPILE)objdump
    
    export AS LD CC CPP AR NM                #导出变量  用于子目录中的Makefile
    export STRIP OBJDUMP OBJCOPY
    
    
    CFLAGS            :=    -Wall -o2
    CFLAGS            +=    -I $(shell pwd)/include  
    LDFLAGS            :=    -lm    -lfreetype      #编译选项
    
    export CFLAGS LDFLAGS
    
    TOPDIR            :=    $(shell pwd)
    export TOPDIR
    
    TARGET    :=    show_file                #生成的目标文件
    
    obj-y    += main.o                    #当前目录下的源文件
    obj-y    += sub/                     #当前目录下的子目录 
    
    all:
        make -C ./  -f $(TOPDIR)/Makefile.build      
        $(CC) $(LDFLAGS) -o $(TARGET) built-in.o     #编译为目标文件
    
    
    
    clean:
        rm -f $(shell find -name "*.o")
        rm -f $(TARGET)
    
    distclean:
        rm -f $(shell find -name "*.o")
        rm -f $(shell find -name "*.d")
        rm -f $(shell find -name "*~")
        rm -f $(TARGET)
    #
    #    Makefile.build
    #
    PHONY := __build
    __build:
    
    obj-y :=
    subdir-y :=
    
    include Makefile          #包含本目录下的Makefile
    
    __subdir-y := $(patsubst %/, %, $(filter %/,$(obj-y)))
    
    subdir-y +=    $(__subdir-y)
    
    subdir_objs    :=    $(foreach f,$(subdir-y),$(f)/built-in.o)
    
    cur_objs    :=    $(filter-out %/, $(obj-y))
    dep_files    :=    $(foreach f,$(cur_objs),.$(f).d)
    dep_files    :=    $(wildcard $(dep_files))
    
    ifneq ($(dep_files),)
        include $(dep_files)
    endif
    
    PHONY += $(subdir-y)
    
    __build:$(subdir-y) built-in.o
    
    $(subdir-y) :
        make -C $@ -f $(TOPDIR)/Makefile.build
    
    built-in.o : $(cur_objs) $(subdir_objs)
        $(LD) -r -o $@ $^
    
    %.o : %.c
        $(CC) $(CFLAGS) -Wp,-MD,.$@.d -c -o $@ $<
    .PHONY : $(PHONY)
    #
    #    Makefile  subdir
    #
    obj-y := test1.o

    下面的一个是编译当前目录下所有的.c文件 不包含子目录

    #
    #    Makefile  topdir
    #
    #
    TARGET    :=    show_file    #生成的目标文件
    
    
    CROSS_COMPILE     :=     /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
    AS                :=    $(CROSS_COMPILE)as
    LD                :=    $(CROSS_COMPILE)ld
    CC                :=    $(CROSS_COMPILE)gcc
    CPP               :=    $(CC) -E
    AR                :=    $(CROSS_COMPILE)ar
    NM                :=    $(CROSS_COMPILE)nm
    
    STRIP             :=    $(CROSS_COMPILE)strip
    OBJCOPY           :=    $(CROSS_COMPILE)objcopy
    OBJDUMP           :=    $(CROSS_COMPILE)objdump
    
    export AS LD CC CPP AR NM
    export STRIP OBJDUMP OBJCOPY
    
    
    CFLAGS            :=    -Wall -o2
    CFLAGS            +=    -I $(shell pwd)/include  
    LDFLAGS           :=    -lm  -lfreetype
    
    export CFLAGS LDFLAGS
    
    cur_file = $(wildcard *.c)
    cur_objs    :=    $(cur_file:.c=.o)
    
    
    all: $(cur_objs)
        $(CC) $(CFLAGS) -o $(TARGET) $^
    
    clean:
        rm -f $(shell find -name "*.o")
        rm -f $(TARGET)
    
    distclean:
        rm -f $(shell find -name "*.o")
        rm -f $(shell find -name "*~")
        rm -f $(TARGET)

    sd

  • 相关阅读:
    映射dll到r0的高维注入
    winrar 去广告的姿势
    利用Hook的方式监控powershell的命令行参数
    读取QQ ClientKey失败分析
    Java——集合——泛型——泛型的概念&使用泛型的好处
    Java——集合——Collection集合——Iterator接口介绍&迭代器的代码实现&迭代器的实现原理&增强for循环
    Java——包装类详解
    Java——集合——泛型——定义和使用含有泛型的方法
    Java——Object类详解
    Java——集合——泛型——定义和使用含有泛型的类
  • 原文地址:https://www.cnblogs.com/ynxf/p/6343438.html
Copyright © 2020-2023  润新知