• Makefile基础


    一、Makefile最基本的规则

    规则

    目标文件 :依赖文件

    TAB 命令

    当依赖文件比目标文件新或者目标文件不存在时,才会执行命令。如下所示,当a.o或者b.o比test新,
    则下面重新链接test的命令,但是a.o和b.o还要根据a.c和b.c来比较是否需要重新生成a.o或者b.o。
    
    • 1
    • 2
    test:a.o b.o
    	gcc -o test a.o b.o
    a.o:a.c
    	gcc -c -o a.o a.c
    b.o:b.c
    	gcc -c -o b.o b.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    二、通配符(%)和假想目标(.PHONY)

    当执行make clean的时候,如果当前目录下有一个clean的文件的时候,并且又没有依赖文件,所以不能执行这条命令,当把clean定于为假想目标的时候就不会去判断这个文件是否存在。
    
    $@表示目标文件
    
    $<表示第一个依赖文件
    
    $^表示所有的依赖文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    test:a.o b.o c.o
    	gcc -o test $^
    %.o:%.c
      gcc -c -o $@ $<
    clean:
    	rm *.o test
    .PHONY:clean
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、即时变量,延时变量

    A := xxx //即时变量,A的值即刻确定,在定义时即确定

    B = xxx //延时变量,B的值使用时才确定

    ?= //延时变量,如果是第一次定义才起效,如果在前面该变量已定义则忽略这句

    += //附加,它是延时变量还是即时变量取决于前面的定义

    四、函数功能

    A = a b c
    B = $(foreach f,$(A),$(f).o)                #从A里面取出每个元素换成.o赋给B
    C = a b c d/
    D = $(filter %/,$(C))                       #从C里面找出符合条件的元素赋给D
    E = $(filter-out %/,$(C))                   #从C里面找出不符合条件的元素赋给E
    files = $(wildcard *.c)                     #找出当前目录下的所有.c文件
    files2 = a.c b.c c.c d.c e.c
    files3 = $(wildcard $(files2))              #从files2里面找出当前目录下有的.c文件
    dep_files = $(patsubst %.c,%.d,$(files2))   #将files2里面的所有.c文件替换成.d文件赋给dep_files
    all:
      @echo B = $(B)
      @echo D = $(D) 
      @echo E = $(E)  
      @echo files = $(files)
      @echo files3 = $(files3)
      @echo dep_files = $(dep_files)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    五、Makefile实例

    gcc -M c.c                    #打印出依赖文件
    gcc -M -MF c.d c.c            #把依赖写进文件c.d
    gcc -c -o c.o c.c -MD -MF c.d #编译c.o,把依赖写进文件c.d
    
    • 1
    • 2
    • 3
    objs = a.o b.o c.o                         #变量objs等于后面的.o元素
    
    dep_files := $(patsubst %,.%.d, $(objs))   #将objs里面的所有.o元素替换成.a.o.d等类似,%是通配符,表示所有的.o
    dep_files := $(wildcard $(dep_files))      #将当前目录下的文件和dep_files的所有元素匹配,有的话才赋给dep_files
    
    CFLAGS = -Werror -Iinclude                 #将警告换成错误,并且会去include文件下查找对应的头文件
    
    test: $(objs)
    	gcc -o test $^
    
    ifneq ($(dep_files),)                      #判断dep_files文件是否为空,不为空的话就包含这些文件
    include $(dep_files)
    endif
    
    %.o : %.c
    	gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d  #将警告替换成错误报错
    
    clean:
    	rm *.o test
    
    distclean:
    	rm $(dep_files)
    	
    .PHONY: clean	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    SpringBoot Starter 分析及编写自己的Starter
    RabbitMq的最终一致性分布式事务
    springboot毕设项目成都市景区管理系统f1hy6(java+VUE+Mybatis+Maven+Mysql)
    首购2元起!CDN与加速特惠专场来啦~
    农业气象站的工作原理
    APP应用加固实战案例:贪玩蓝月
    【面试HOT100】哈希&&双指针&&滑动窗口
    c++的priority_queue各种使用方法
    替代netstat的命令之一【ss】 使用实例
    4个技巧告诉你,如何使用SMS促进业务销售?
  • 原文地址:https://blog.csdn.net/qq_42772967/article/details/133238084