当前位置: 首页 > news >正文

Makefile语法详解

目录

  • 1 Makefile基本常识
    • 1.1 基本格式
    • 1.2 makefile规则
    • 1.3 伪目标
    • 1.4 变量的使用
    • 1.5 赋值方式
    • 1.6 常用函数
  • 2 Makefile整体编译
    • 2.1 编译选项
    • 2.2三个.c整体编译
    • 2.3 静态库编译
    • 2.4 动态库编译

1 Makefile基本常识

1.1 基本格式

如下所示为Makefile的基本格式,特别需要注意的是不能随意加空格等符号,比如tab键前后
在这里插入图片描述
以下makefile语句执行make debug即可,我们通常使用这个方式进行查看某个变量是否与预期一致,比如$echo $(HOST_ARCH)。

#方法一
debug :echo hello		#打印hello,同时也会打印echo hello这句话的执行过程
#方法二
debug :&echo hello		#加入&之后不打印执行过程

1.2 makefile规则

在这里插入图片描述

1.3 伪目标

为了避免与文件名重名,如下所示,我们常采用伪目标的形式将clean修饰一下,目的是即使有一个同名的文件名,他也会执行makefile中的clean命令。

clean :@rm -rf *.o.PHONY :clean bebug #可以同时声明多个伪目标文件

1.4 变量的使用

变量使用 := 来定义,符号两边要留一个空格,变量的引用使用 {} 或者 () ,前面加一个符合$,具体使用方法如下图所示,通过make compile命令可以生成main.o文件。
在这里插入图片描述

  • $@:目标target的完整名称
  • $<:第一个依赖文件的名称
  • $^:所有依赖文件的名称

除上面这种表达方式外,我们还可以使用预定义变量,来替换对于的文件名,具体使用方法如下。
在这里插入图片描述

1.5 赋值方式

  • = 直接赋值给变量,但是后面再次对它进行赋值时该变量会改变为新的值,该方法一般用于在同一个项目上需要不同的架构上进行编译。
    在这里插入图片描述
  • := 立即赋值运算符,第一次设置完之后以后再次赋值也不会发生改变。
    在这里插入图片描述
  • ?= 如果前面已经定义了,则不重新赋值,如果前面还没有定义,则将此变量定义为新值。
    在这里插入图片描述
  • += 在该变量的后面继续赋值
    在这里插入图片描述
  • \ 将同一行换成多行,跟C语言用法一样,仅仅是提高观感
    在这里插入图片描述

1.6 常用函数

  • shell 利用linux中的shell脚本来得到对应的信息
    在这里插入图片描述
  • subst 将字符串中的某个字串换成另外一个字串
    在这里插入图片描述
  • patsubst 是subst的升级版,可以直接使用%通配符更换自己想更换的某个字串。
    在这里插入图片描述
    以下是两个函数的对比,比如我们想把./src/ ***.cpp更改为./objs/ ***.o
#方法一
cpp_srcs := $(shell find src -name *cpp)
cpp_objs := $(subst src/,objs/,$(cpp_srcs))
cpp_objs := $(subst .cpp,.o,$(cpp_objs))  #此处不太理解为啥可以用:=,不应该该一个变量名么
#方法二
cpp_srcs := $(shell find src -name *cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))
  • wildcard 扩展通配符,获取工作目录下的所有符合规则的文件列表,
#在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
src=$(wildcard *.c ./sub/*.c)
@echo $(src)
#输出为a.c b.c ./sub/sa.c ./sub/sb.c
  • foreach 用循环把list中每个元素取出来放在var中,之后执行text表达式
    在这里插入图片描述
    以下是两种具体的实现方法
dir :=	/111/111 \/222/222
#方法一:
dir := $(foreach a ,$(dir), -I $(a))
#方法二:
dir := $(dir:%=-I %)
debug :@echo $(dir)
  • dir 从文件名序列中提取出文件夹的路径,可以通过以下函数执行
@mkdir -p $(dir src/foo.c)  #此处-p最好加上,不加上的话如果文件已经存在就会报错。

在这里插入图片描述

  • notdir 将文件路径的路径给去掉,只留下文件名
    在这里插入图片描述
  • filter 在notdir的基础上,在筛选一次,只留下后缀为自己设置的文件的文件名
    在这里插入图片描述
  • filter-out 去除掉某一项,如下所示,去掉src中的mian.cpp,其他的cpp保留。
libs := $(filer-out src/main.cpp,$(sheel find src -name *.cpp))
  • basename 去掉对应文件名的后缀
    在这里插入图片描述

2 Makefile整体编译

2.1 编译选项

常见的编译选项主要是以下几种,我们在使用-c编译成.o文件是需要指定其中的某些信息,特别是在包含头文件的时候需要导入头文件的库位置信息。
在这里插入图片描述

2.2三个.c整体编译

cpp.srcs是源文件目录
include_paths是头文件目录
cpp_objs是要生成的.o文件目录
workspace是可执行文件目录
compile_options是添加编译条件
在这里插入图片描述
在这里插入图片描述

2.3 静态库编译

下面是一个例程,第一个图是对应的文件信息,我们需要在main.cpp中调用另外两个文件里面的函数。在下面这个历程中,我们需要先编译出对应的.a文件静态库,然后在去编译生成可执行文件。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

2.4 动态库编译

动态库与静态库的区别,静态库是直接生成所有的.c文件的库文件,占用内存大,而动态库是需要什么编译什么
在这里插入图片描述
下面这个是对应的文件情况:
在这里插入图片描述
下面这个是对应的makefile动态编译文件,直接执行run即可动态编译出最终的可执行文件。最后一个run直接依赖前面两个过程.o文件的生成和.so动态库的生成。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


http://www.mrgr.cn/news/28867.html

相关文章:

  • 为什么你亏几十个点都可以扛,才赚几个点却想逃
  • 【Android】sendevent和getevent
  • day21JS-axios数据通信
  • osg中显示3dtiles和cesiumIon
  • 一键更换软件源的工具——chsrc
  • fiddler抓包02_安装
  • Chainlit集成LlamaIndex并使用通义千问模型实现AI知识库检索网页对话应用增强版
  • 经典sql题(七)查找直播间最大在线人数
  • 【算法】差分思想:强大的算法技巧
  • 【补充篇】Davinci工具要求的dbc格式
  • 访谈心脑血管名医黄力医生:医术精湛,心系患者
  • 如何提高网站搜索排名
  • AI大模型
  • 98-策略模式的理解
  • 240. 搜索二维矩阵 II
  • 【OJ刷题】双指针问题6
  • 从0-1 用AI做一个赚钱的小红书账号(不是广告不是广告)
  • PowerShell脚本编写:自动化Windows开发工作流程
  • 网络安全笔试进阶练习题,来测测你能答对几个?
  • 正版138JAVA部署mysql5.5.JDK环境