• makefile备忘


    结构描述

    目标 … : 依赖 …
    命令1
    命令2
    . . .

    标记符

    CFLAGS

    $^ 表示所有的依赖文件
    $@ 表示生成的目标文件
    $< 代表第一个依赖文件

    • 调试信息选项:-g
    • 优化选项:-O
    • 编译警告选项:-Wall
    • 指定包含目录选项:-I
    • 指定库目录选项:-L
    • 指定库文件选项:-l
    gcc -lSoTest -L./ main.c -o main
    
    • 1
    • fPIC: 产生位置无关的代码
    • shared: 共享
    gcc -shared -fPIC SoTest.c -o libSoTest.so
    
    • 1

    wildcard

    1、wildcard : 扩展通配符
    2、notdir : 去除路径
    3、patsubst :替换通配符
    例子:
    建立一个测试目录,在测试目录下建立一个名为sub的子目录
    $ mkdir test
    $ cd test
    $ mkdir sub
    在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
    建立一个简单的Makefile

    src=$(wildcard *.c ./sub/*.c)
    dir=$(notdir $(src))
    obj=$(patsubst %.c,%.o,$(dir) )
    all:
    @echo $(src)
    @echo $(dir)
    @echo $(obj)
    @echo "end"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    执行结果分析:
    第一行输出:
    a.c b.c ./sub/sa.c ./sub/sb.c
    wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。
    第二行输出:
    a.c b.c sa.c sb.c
    notdir把展开的文件去除掉路径信息
    第三行输出:
    a.o b.o sa.o sb.o
    $(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
    任何输出。
    或者可以使用

    obj=$(dir:%.c=%.o)
    
    • 1

    效果也是一样的。
    这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
    它的标准格式是

    $(var:a=b)${var:a=b}
    
    • 1

    它的含义是把变量var中的每一个值结尾用b替换掉a
    SRC = $(wildcard *.c)
    等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:
    SRC = $(wildcard *.c) $(wildcard inc/*.c)
    也可以指定汇编源程序:
    ASRC = $(wildcard *.S)

    变量赋值

    1、"="延迟赋值 是最普通的等号在Makefile中容易搞错赋值等号使用 “=”进行赋值变量的值是整个Makefile中最后被指定的值。

    VIR_A = A
    VIR_B = $(VIR_A) B
    VIR_A = AA
    
    • 1
    • 2
    • 3

    经过上面的赋值后最后VIR_B的值是AA B而不是A B在make时会把整个Makefile展开来决定变量的值
      2、":="立即赋值 表示直接赋值赋予当前位置的值。

    VIR_A := A
    VIR_B := $(VIR_A) B
    VIR_A := AA
    
    • 1
    • 2
    • 3

    最后BIR_B的值是A B即根据当前位置进行赋值。因此相当于“=”“=”才是真正意义上的直接赋值
      3、"?="空赋值 表示如果该变量没有被赋值赋值予等号后面的值。

    VIR ?= new_value
    
    • 1

    如果VIR在之前没有被赋值那么VIR的值就为new_value。

    VIR := old_value
    VIR ?= new_value
    
    • 1
    • 2

    这种情况下VIR的值就是old_value
      4、"+="追加赋值 和平时写代码的理解是一样的表示将符号后面的值添加到前面的变量上

    指定头文件路径

    一般都是通过"-I"大写i来指定假设头文件在
    /home/develop/include
    则可以通过-I指定

    -I/home/develop/include
    
    • 1

    将该目录添加到头文件搜索路径中
    在Makefile中则可以这样写

    CFLAGS=-I/home/develop/include
    
    • 1

    然后在编译的时候引用CFLAGS即可如下

    yourapp:*.c
        gcc $(CFLAGS) -o yourapp
    
    • 1
    • 2

    指定库文件路径

    与上面指定头文件类似只不过使用的是"-L"来指定

    LDFLAGS=-L/usr/lib -L/path/to/your/lib
    
    • 1

    告诉链接器要链接哪些库文件使用"-l"小写L如下

    LIBS = -lpthread -liconv
    
    • 1
  • 相关阅读:
    你听说过苹果的搜索引擎吗?
    重生奇迹mu弓箭手加点详解
    [go学习笔记.第十一章.项目案例] 2.客户信息管理系统
    一文读懂LCD、OLED、LED屏的区别以及透明液晶屏原理
    linux 多重启动grub2详解
    【C++庖丁解牛】vector容器的简易模拟实现(C++实现)(最后附源码)
    出手即巅峰,14年入职阿里大咖出品“JVM&G1 GC深入学习手册”,入职腾讯阿里,升职加薪,必学笔记
    针对遗留系统采取的不同演化策略
    【问题记录】audio标签变更currentTime属性值无效,currentTime变为0
    居舍杂志居舍杂志社居舍编辑部2022年第27期目录
  • 原文地址:https://blog.csdn.net/fuhanga123/article/details/134526081