首页 > 其他分享 >makefile基础知识

makefile基础知识

时间:2024-08-27 16:26:04浏览次数:6  
标签:文件 bar makefile 基础知识 单词 字符串 var foo

makefile知识 

1、 Makefile五大内容(显示规则、隐晦规则、变量定义、文件指示、注释)

1.1、显示规则:如何生成一个或多个目标文件(要生成的文件,文件依赖的文件,生成命令);stm32: main.o hello.o

  gcc -o stm32 main.o hello.o

1.2、隐晦规则:Makefile的自动推导功能,所以隐晦规则可以编写更加粗简的Makefile文件。main.o: includes.h

1.3、变量定义:定义一系列字符串变量,类似C语言中的宏定义,变量扩展到对应引用位置 objs = main.o led.o... 引用  -rm stm32 $(objs)

1.4、文件指示:①在一个Makefile中应用另一个Makefile,类似C语言的include一样。②根据某些情况指定Makefile中的有效部分,类似C语言中的预编译#if。

  include  <filename>,其中filename是当前操作系统Shell的文件模式(可以保含路径和通配符); include  foo.make  *.mk  $(bar)

1.5、注释:行注释(#)

 

2、 make 的工作执行步骤

    1.1、读入所有的Makefile

    1.2、读入被include的其它Makefile

    1.3、初始化文件中的变量

    1.4、推导隐晦规则,并分析所有规则

    1.5、为所有的目标文件创建依赖关系链

    1.6、根据依赖关系,决定哪些目标要重新生成

    1.7、执行生成命令

 

3、 编译(compile)--中间目标文件Object File

1.1、每个源文件编译成一个对应的中间目标文件;

1.2、Windows:编译生成.obj文件;

1.3、UNIX: 编译生成.o文件,使用cc;

1.4、Linux:编译生成.o文件,使用gcc;

 

4、 链接(Link)—链接对应文件

1.1、把大量的object file 合成执行文件的动作叫链接;

1.2、打包中间目标文件,Windows系统就是打包库文件(Library File),也就是.lib文件;在Unix系统就是Archive File,也就是 .a 文件。

 

5、 语法规则

Targets ... : prerequisites ...

command

...

...

1.1、target 可以是中间目标文件(Object File),也可以是执行文件,更可以为标签(Label);

1.2、prerequisites 是要生成target所需要的文件或者目标;

1.3、command 是make需要执行的命令(任意的shell命令,必须[Tab]键开始

1.3.1、-c : 编译产生中间目标文件(object file),而不是链接可执行文件;

  $gcc -c led.c --->led.o

1.3.2、-o: 用户指定输出文件名;

  $gcc led.c -o led.o

1.3.3、-g: 指明编译程序在编译的输出中应产生调试信息;

1.3.4、-O: 优化选项,-O0~3,其中0是不优化,3级优化

  $gcc -c O3 led.c

1.3.5、-L: 指定连接库的搜索目录,-l指定连接库名称,-L与-l一般成对出现;

  $gcc main.o -L/usr/lib -lqt -o hello

1.3.6、-Wall :打印出编译时所有的错误或者警告信息

1.4、通过make命令执行;

1.5、通过make clean 执行清除所以目标文件,以便重新编译。

 

6、 使用变量

1.0、变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等),变量是大小写敏感的,建议大小写混合使用 Objects。

1.1、如我们的中间目标文件使用objs变量代替

  objs := main.o kbd.o display.o (“:=”操作符可以避免变量无限展开,建议使用“:=”)

1.2、引用变量 $(objs)

1.3、操作符“?=” (FOO ?= bar 如果FOO没有被定义过,那么变量FOO的值就是“bar”,如果FOO先前被定义过,那么这条语将什么也不做)

 

7、 make自动推导能力

1.1、make看到[.o]文件,会自动把[.c]文件加入依赖关系中

  如找到led.o文件,那么led.c就会变为依赖文件,同时会推导出 gcc -c led.c

  原先:led.o: led.c led.h include.h

  gcc -c led.c

  自动推导:led.o: led.h include.h

 

8、 另类风格Makefile(根据自动推导能力,收拢[.o]和[.h]文件),不建议使用。

1.1、$(objs) : include.h #目标文件变量都引用了include.h

  Kdb.o files.o : defs.h #部分目标文件引用了defs.h

 

9、 清空目标文件的规则:伪目标

.PHONY : clean

Clean :

-rm edit $(objs)  #在命令行前加一个减号“-”(在Tab键之后),标记为不管命令出不出错都认为是成功的

 

10、 引用其他的Makefile

Include  <filename>,其中filename是当前操作系统Shell的文件模式(可以保含路径和通配符)

 

11、 通配符*  ~ ... ?

*代表系列文件;如*.c表示所有后缀.c文件。(用”/”转义符“/*”来表示真实的*)

 rm -f  *.o

~在文件名中也有比较特殊的用途,如~/test表示/home目录下的test目录。

?表示一个自动化变量。

 

12、 文件搜寻

1.1、 使用特殊变量“VPATH”,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件。VPATH = src : ../bps (指定了src 和../bps 两个目录,多个目录用分号隔开)

1.2、 使用关键字“vpath”,更为灵活,可以指定不同的文件在不同的搜索目录中。

① vpath <pattern> <directories> #为符合模式<pattern>的文件指定搜索目录<directories> 如vpath %.h ../includes “%”的意思是匹配零或若干字符

② Vpath <pattern> #清除符合模式<pattern>的文件的搜索目录

③ Vpath #清除所有已被设置好了的文件搜索目录

 

13、 变量高级用法

1.1、变量值的替换 “$(var:a=b)”或${var:a=b}意思是把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。

foo := a.o b.o #定义变量

bar := $(foo:.o = .c)  #把a.o b.o 替换为a.c b.c

  或者bar := $(foo:%.o = %.c) #这依赖于被替换字串中的有相同的模式,模式中必须包含一个“%”字符。

1.2、 把变量的值再当成变量

x = y #$(x)的值为y

y = z #$(y)的值为z

a := $($(x)) #$(a)的值为z

 

14、 追加变量值

1.1、使用“+=”操作符给变量追加值

  objects = main.o led.o

  objects +=  key.o #objects的值变为“main.o led.o key.o”

 

15、 多行变量

1.1、使用define关键字设置变量的值可以有换行,以endef关键字结束。

define two-lines

echo foo

echo $(bar)

endef

 

16、 调用函数 $(<function> <arguments>)

1.1、字符串替代函数--subst

  $(subst <from>,<to>,<text>) #把字串<text>中的<from>字符串替换成<to>

  $(subst ee,EE, free of street)#把“ee”替换成“EE”,返回“frEE of strEEt”

1.2、模式字符串替换函数--patsubst

  $(patsubst <pattern>,<replacement>,<text>) #查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换.

  $(patsubst %.c,%.o,x.c.c a.c) #把“x.c.c a.c”符合模式[%.c]的单词替换成[%.o].返回“x.c.o a.o”

1.3、去空格函数--strip

  $(strip <string>) #去掉<string>字串中开头和结尾的空字符

  $(strip a b c )#把“a b c ”字符串的空格去掉返回“a b c”

1.4、 查找字符串函数--findstring

  $(findstring <find>,<in>)#在字串<in>中查找<find>字串,找到返回<find>,没找到返回空字符串

  $(findstring a, a b c)#返回“a”

  $(findstring a, b c)#返回“”空字符串

1.5、过滤函数--filter

  $(filter <pattern...>,<text>) #以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词,支持多个模式,返回符合<pattren...>模式的字符串

  source := foo.c bar.c baz.s key.h

  foo: $(source)

  cc $(filter %.c %.s, $(source)) -o foo

  #$(filter %.c %.s, $(source)) 返回的值“foo.c bar.c baz.s”

1.6、 反过滤函数--filter-out

  $(filter-out <pattern...>,<text>)#以<pattern>模式过滤<text>字符串中的单词,去除符合模式<pattern>的单词。可以有多个模式,返回不符合模式<pattern>的字符串。

1.7、 排序函数--sort

  $(sort <list>)#给字符串<list>中的单词排序(升序),返回排序后的字符串。

  $(sort foo bar lose)#返回“bar foo lose”,该函数会弃掉<list>中的相同单词。 

1.8、 取单词函数--word

  $(word <n>,<text>)#取字符串<text>中第<n>个单词,返回字符串<text>中第<n>个单词。如果<n>比<text>中的单词数要大,那么返回空字符串。

  $(word 2, foo bar baz)返回值是“bar”.

1.9、 取单词串函数--wordlist

  $(wordlist <s>,<e>,<text>)#从字符串<text>中取从<s>开始到<e>的单词串。<s>和<e>是一个数字.

  $(wordlist 2, 3, foo bar baz)返回值是“bar baz”

1.10、 单词个数统计函数--words

  $(words <text>)#统计<text>中字符串中的单词个数

  $(words, foo bar baz)返回值是“3”

1.11、 首单词函数——firstword

  $(firstword <text>)#取字符串<text>中的第一个单词

  $(firstword foo bar)返回值是“foo”

1.12、 取目录函数——dir

  $(dir <name...>)#从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。

  $(dir src/foo.c hacks)返回值是“src/ ./”。

1.13、 取文件函数——notdir

  $(notdir <names...>)#从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“/”)之后的部分。

  $(notdir src/foo.c hacks)返回值是“foo.c hacks”。

1.14、 取后缀函数——suffix

  $(suffix <names...>)#从文件名序列<names>中取出各个文件名的后缀

  $(suffix src/foo.c src-1.0/bar.c hacks)返回值是“.c .c”。

1.15、 取前缀函数——basename

  $(basename <names...>)#从文件名序列<names>中取出各个文件名的前缀部分

  $(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar hacks”。

1.16、 加后缀函数——addsuffix

  $(addsuffix <suffix>,<names...>)#把后缀<suffix>加到<names>中的每个单词后面。

  $(addsuffix .c,foo bar)返回值是“foo.c bar.c”。

1.17、 加前缀函数——addprefix

  $(addprefix <prefix>,<names...>)#把前缀<prefix>加到<names>中的每个单词后面

  $(addprefix src/,foo bar)返回值是“src/foo src/bar”。

1.18、 连接函数——join

   $(join <list1>,<list2>)#把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中

  $(join aaa bbb , 111 222 333)返回值是“aaa111 bbb222 333”。

1.19、循环函数--foreach

   $(foreach <var>,<list>,<text>)#把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。

  name := a b c d

  files = $(foreach n,$(name),$(n).o) #$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

1.20、 

 

17、 make 的退出码:0 (执行成功返回0)、1(任何错误返回1)、2 (使用“-q”选项,不更新返回2)。

 

18、 模式规则(模式规则中,至少在规则的目标定义中要包含"%")

%.o:%.c,<command...>

%.o:%.c

$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@  #所有的[.c]文件都编译成[.o]文件

 

19、 自动化变量

$@ #表示模式规则中的目标文件集。

$% #仅当目标是函数库文件中,表示规则中的目标成员名。

$< #依赖目标中的第一个目标名字。

$? #所有比目标新的依赖目标的集合,以空格分隔。

$^ #所有的依赖目标的集合,以空格分隔。

 

20、 “=”、“:=”、“?=”、“+=”的差异

1.1、“=”是进行赋值,变量值等于Makefile最后赋的值。例如:var_a = A,var_b = $(var_a) BB  var_a = AA 最终var_b 的值为AA BB

1.2、“:=”是直接赋值,赋予当前位置的值。例如:var_a := A,var_b := $(var_a) BB  var_a := AA 最终var_b 的值为A BB .这个才是意义上的赋值。

1.3、 “?=”是如果该变量没有被赋值,则赋予等号后的值。例如:var := old  var ?= new那么此时var的值仍为old。

1.4、“+=”是将等号后面的值添加到前面的变量上。例如:var = a.c b.c  var += c.c 那么此时var的值为a.c b.c c.c。

 

21、 

 

22、  

 

23、   

 

标签:文件,bar,makefile,基础知识,单词,字符串,var,foo
From: https://www.cnblogs.com/zblblog/p/18382949

相关文章

  • IEC61850教程,第一章:IEC 61850 基础知识介绍
    第一章:IEC61850基础知识介绍平时学习标准或调试IEC61850设备,需要IEC61850模拟器,推荐一款:客户端下载地址:IEC61850客户端模拟器服务端下载地址:IEC61850服务端模拟器什么是IEC61850?IEC61850是定义变电站自动化系统内的设备及其相互作用方式的国际标准。IEC61850的目......
  • JavaSE基础知识分享(十五)
    写在前面今天继续讲Java中的枚举和正则表达式的的知识!这部分说完,JavaSE部分的知识就结束了!枚举概述枚举类用于描述有限个对象的类。自JDK1.5起引入了对枚举类型的原生支持,简化了枚举的定义和使用。下面是JDK1.5之前和之后的枚举类定义方式的比较。JDK1.5之前的写法......
  • 芯片、GPU、CPU、显卡、显存、x86、ARM、AMD等基础知识
    1.芯片芯片指的是半导体材料制成的集成电路,可以包含一个或多个电子元件、电路或系统。芯片可以是任何电子设备的组成部分,不仅限于CPU,还包括GPU、内存芯片、存储控制器、网络接口等。GPU和CPU是两种最常见的特定的芯片。它们分别针对图形处理和通用计算任务进行了优化。2.CPU......
  • 大话C语言:第46篇 C语言项目工程化之Makefile详解
    1Makefile概述Makefile是一种用于自动化构建和管理程序的工具,以文本文件的形式存在。它主要记录了程序的编译规则、依赖关系和操作指令,使得在开发过程中能够轻松地进行代码的编译、链接和部署。Makefile文件中的命令有一定规范,一旦该文件编写好以后在Linux命令行中执行一条......
  • 【网络安全】基础知识详解(非常详细)零基础入门到精通,收藏这一篇就够了
    一、什么是网络安全?百度上对“网络安全”是这么介绍的:“网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露、系统连续可靠正常地运行,网络服务不中断。”嗯…是不是感觉有点抽象。那么我们再换一种表述:网......
  • Linux项目自动化构建工具-make/makefile
    ......
  • JavaSE基础知识分享(十四)
    写在前面今天继续讲Java中的类加载器和lambda表达式的知识!类加载器和反射类的加载当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三步来实现对这个类进行初始化。加载将.class文件读入内存,并为之创建一个Class对象。任何类被使用时系......
  • 金融基础知识-投资相关业务基本概念
    1.金融及金融机构金融〔Finance〕货币资金的融通。我们通常说的都是广义的金融,是指有关货币、信用的所有经济关系和交易行为的总称。金融机构〔FinancialInstitutes〕专门从事货币、信用活动的中介组织。目前,我国金融机构按其地位和功能可分为三大类:中央银行,金融监管......
  • 如何在Windows下使用make编译Makefile
    最近有小伙伴咨询我去编译运行一个程序。我一开始以为是CMakeLists,结果发现是makefile。 什么是Makefile‌Makefile是一种用于自动化构建和管理程序的工具‌,它定义了项目中文件的依赖关系和构建步骤,帮助程序员自动化编译、链接和打包程序,从而提高软件开发效率。Makefile的主......
  • C++入门基础知识29
    成长路上不孤单......