首页 > 其他分享 >Makefile学习(一)

Makefile学习(一)

时间:2024-03-17 22:33:51浏览次数:13  
标签:foo bar 变量 make Makefile 学习 main

参看文档:《跟我一起写 Makefile》

Makefile的基本规则:

target ... : prerequisites ... 
    command 
...
    ...
target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。 prerequisites 就是,要生成那个 target 所需要的文件或是目标。 command 也就是 make 需要执行的命令。(任意的 Shell 命令)  

举一个例子:

*表示通配符
main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
main.o: main.c
    gcc -c main.c
input.o: input.c
    gcc -c input.c
calcu.o: calcu.c
    gcc -c calcu.c

clean:
    rm *.o
    rm main
make编译如下: 0 make clean如下: 0   下面说明一个一个规则,将上面的Makefile代码进行简化:

1、Makefile中使用变量:

objects = main.o input.o calcu.o

main: $(objects)
    gcc -o main $(objects)
main.o: main.c
    gcc -c main.c
input.o: input.c
    gcc -c input.c
calcu.o: calcu.c
    gcc -c calcu.c

clean:
    rm $(objects)
    rm main

2、让Makefile自动推导:

objects = main.o input.o calcu.o

main: $(objects)

main.o: main.c

input.o: input.c

calcu.o: calcu.c


clean:
    rm $(objects)
    rm main

3、清空目标文件的规则:

.PHONY表示一个“伪目标”,也是一种Makefile编写规范
objects = main.o input.o calcu.o

main: $(objects)

main.o: main.c

input.o: input.c

calcu.o: calcu.c


.PHONY : clean   
clean:
    rm $(objects)
    rm main
 

Makefile总述:

1、显式规则: 显式规则说明了,如何生成一个或多的的目标文件。   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]键开始。  

引入其他的Makefile:

在 Makefile 使用 include 关键字可以把别的 Makefile 包含进来,这很像 C 语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。include 的语法是: include filename 可以是当前操作系统 Shell 的文件模式(可以保含路径和通配符) 在 include前面可以有一些空字符,但是绝不能是[Tab]键开始。include 和可以用一个或多个空格隔开。举个例子, 有这样几个 Makefile:a.mk、b.mk、c.mk,还有一个文件叫foo.make,以及一个变量$(bar),其包含了 e.mk 和 f.mk,那么,下面的语句: include foo.make *.mk $(bar) 等价于: include foo.make a.mk b.mk c.mk e.mk f.mk   make 命令开始时,会把找寻 include 所指出的其它 Makefile,并把其内容安置在当前的位。就好像 C/C++的#include 指令一样。如果文件都没有指定绝对路径或是相对路径的话,make 会在当前目录下首先寻找,如果当前目录下没有找到,那么,make 还会在下面的几个目录下找: 1、如果 make 执行时,有“-I”或“--include-dir”参数,那么 make 就会在这个参数 所指定的目录下去寻找。 2、如果目录/include(一般是:/usr/local/bin 或/usr/include)存在的话,make 也会去找。如果有文件没有找到的话,make 会生成一条警告信息,但不会马上出现致命错误。它会继续载入其它的文件,一旦完成 makefile 的读取,make 会再重试这些没有找到,或是不能读取的文件,如果还是不行,make 才会出现一条致命信息。如果你想让 make不理那些无法读取的文件,而继续执行,你可以在 include 前加一个减号“-”。 如: -include 其表示,无论 include 过程中出现什么错误,都不要报错继续执行。和其它版本 make兼 容的相关命令是 sinclude,其作用和这一个是一样的。  

文件搜索:

在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当 make 需要去找寻文件的依赖关系时,你可以在文件前加上路 径,但最好的方法是把一个路径告诉 make,让 make 在自动去找。 Makefile 文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make 只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make 就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。   VPATH = src:../headers 上面的的定义指定两个目录,“src”和“../headers”,make 会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)   例如: vpath %.h ../headers 该语句表示,要求 make 在“../headers”目录下搜索所有以“.h”结尾的文件。(如果某文件在当前目录没有找到的话)    

使用变量:

1、变量:$

2、可使用变量中的变量:

先看第一种方式,也就是简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值, 其也可以使用后面定义的值。如:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
 
all:
    echo $(foo)
  我们执行“make all”将会打出变量$(foo)的值是“Huh?”( $(foo)的值是$(bar),$(bar)的值是$(ugh),$(ugh)的值是“Huh?”)可见,变量是可以使用后面的变量来定义的。 为了避免上面的这种方法,我们可以使用 make 中的另一种用变量来定义变量的方法。 这种方法使用的是“:=”操作符,如:
x := foo
y := $(x) bar
x := later
其等价于:
y := foo bar
x := later
  值得一提的是,这种方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。如果是这样:
y := $(x) bar
x := foo
那么,y 的值是“bar”,而不是“foo bar”。  

3、?=

FOO ?= bar
其含义是,如果 FOO 没有被定义过,那么变量 FOO 的值就是“bar”,如果 FOO 先前被定义过,那么这条语将什么也不做  

4、变量值的替换

我们可以替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。 看一个示例吧:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
这个示例中,我们先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有以“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c b.c c.c”。 另外一种变量替换的技术是以“静态模式”(参见前面章节)定义的,如:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
这依赖于被替换字串中的有相同的模式,模式中必须包含一个“%”字符,这个例子同样让$(bar)变量的值为“a.c b.c c.c”。  

5、合成使用

再来看看结合第一种技术的例子:
a_objects := a.o b.o c.o
1_objects := 1.o 2.o 3.o

sources := $($(a1)_objects:.o=.c) 
这个例子中,如果$(a1)的值是“a”的话,那么,$(sources)的值就是“a.c b.c c.c”;如果$(a1)的值是“1”,那么$(sources)的值是“1.c 2.c 3.c”。  

6、追加变量值

可以使用“+=”操作符给变量追加值,如:
objects = main.o foo.o bar.o utils.o
objects += another.o
于是,$(objects)值变成:“main.o foo.o bar.o utils.o another.o”(another.o被追加进去了)  

7、override指示符

如果有变量是通常 make的命令行参数设置的,那么 Makefile中对这个变量的赋值会被忽略。如果你想在 Makefile 中设置这类参数的值,那么,你可以使用“override”指示符。其语法是:
override =
override :=
override +=
 

8、环境变量

make 运行时的系统环境变量可以在 make 开始运行时被载入到 Makefile 文件中  

判断语句

libs_for_gcc = -lgnu
normal_libs =
 
foo: $(objects)
ifeq ($(CC),gcc)
  $(CC) -o foo $(objects) $(libs_for_gcc)
else
  $(CC) -o foo $(objects) $(normal_libs)
endif
可见,在上面示例的这个规则中,目标“foo”可以根据变量“$(CC)”值来选取不同的函数库来编译程序。   从上面的示例中看到三个关键字:ifeq、else 和 endif。ifeq 的意思表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起。else 表示条件表达式为假的情况。endif 表示一个条件语句的结束,任何一个条件表达式都应该以 endif 结束。 ifeq:if equal

标签:foo,bar,变量,make,Makefile,学习,main
From: https://www.cnblogs.com/lethe1203/p/18079327

相关文章

  • Word2vec 学习笔记
    word2vec学习笔记0.引言1.Word2vec简介1-1.CBOW1-2.SG2.实战0.引言最近研究向量检索,看到有同事使用MeCab、Doc2Vec,所以把Word2vec这块知识学习一下。1.Word2vec简介Word2vec即wordtovector,顾名思义,就是把词转换成向量,该方法在2013年由谷歌公司......
  • vim,gcc,gdb与Makefile的使用
    一、Linux编辑器-vim使用1.vim的基本概念vim的三种模式(其实有好多模式,目前掌握这3种即可),分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下(1)正常/普通/命令模式(Normalmode)控制屏幕光标的移动,字符、字或行的删除,移动复制......
  • 079基于深度学习的香蕉成熟度检测小程序版_含10多种模型
    代码下载和视频演示地址:079基于深度学习的香蕉成熟度检测小程序版_含10多种模型_哔哩哔哩_bilibili效果展示图如下:​代码文件展示如下: ​运行01数据集文本生成制作.py可以读取图片路径保存再txt文本中,运行02train.py可以对txt文本中的图片路径读取并训练模型,在02......
  • 综合架构学习笔记-3---
    综合架构学习笔记-3---rsync-扩展脚本虚拟机测试环境ip10.0.1.0网关10.0.1.2子网掩码255.255.255.0知识回顾rsync如何部署?1.安装软件rsync2.编写配置文件虚拟用户备份目录密码文件具体流程演示linux系统安装部署服务流程:a下载安装软件yumb编写配置......
  • 综合架构学习笔记-2
    综合架构学习笔记-2---rsync-实战实战1rsync守护进程部署测试环境--虚拟机环境ip10.0.1.0网关10.0.1.2子网掩码255.255.255.0步骤服务端第一步:下载安装软件 [root@localhost~]#yuminstall-yrsync 第二步:编写配置文件把原来的配置文件删除 [roo......
  • 综合架构学习笔记-3---rsync-扩展脚本
    综合架构学习笔记-3---rsync-扩展脚本虚拟机测试环境ip10.0.1.0网关10.0.1.2子网掩码255.255.255.0知识回顾rsync如何部署?1.安装软件rsync2.编写配置文件虚拟用户备份目录密码文件具体流程演示linux系统安装部署服务流程:a下载安装软件yumb编写配置......
  • 综合架构学习笔记-2---rsync-实战
    综合架构学习笔记-2---rsync-实战实战1rsync守护进程部署测试环境--虚拟机环境ip10.0.1.0网关10.0.1.2子网掩码255.255.255.0步骤服务端第一步:下载安装软件 [root@localhost~]#yuminstall-yrsync 第二步:编写配置文件把原来的配置文件删除 [roo......
  • AI大型语言模型的微调与迁移学习
    1.背景介绍在过去的几年里,人工智能(AI)和机器学习(ML)领域取得了显著的进步。特别是在自然语言处理(NLP)领域,大型预训练语言模型如BERT、GPT-3等的出现,使得机器对人类语言的理解和生成能力达到了前所未有的高度。然而,这些模型在特定任务上的表现往往需要通过微调(Fine-tuning)和迁......
  • Sass学习记录
    1.变量声明$demo-color:red;$demo-border:1pxsolid$demo-color;.a{border:$demo-border;}2.嵌套#a{.a{width:1px}}3.符号&,伪类选择.bbca{color:red;&:hover{color:blue}}4.群组嵌套#content{h1,h2......
  • 信息安全认证 CISSP 官方学习指南 第9版 中文版 学习记录
    刚考完CISSP考试,顺利通过,因此记录一下相关内容,希望对大家有帮助CISSP介绍CISSP(CertifiedInformationSystemsSecurityProfessional)是全球范围内最受尊敬的信息安全认证之一,由国际信息系统安全认证联盟(ISC)²(InternationalInformationSystemSecurityCertification......