Makefile学习宝典
c语言makefile编写规则(一)
c语言makefile编写规则(一)C语言Makefile编写规则1. Makefile介绍Makefile是一种文件,其中包含了一组规则(rules)用于编译和构建项目。
它的作用是告诉系统如何编译代码,生成可执行文件。
2. Makefile规则基本结构Makefile规则由以下几部分组成:目标(Target)目标是一个文件,可以是源代码文件、中间文件或最终生成的可执行文件。
依赖(Dependencies)依赖指的是生成目标所需要的文件或其他目标。
当某个依赖文件发生变化时,目标就需要重新生成。
命令(Commands)命令是指执行编译、链接等操作的具体命令。
当目标需要重新生成时,Makefile会执行相应的命令。
规则示例以下是一个简单的示例,展示了一个C语言源文件的编译过程:target: dependenciescommand其中, - target表示目标文件; - dependencies表示生成目标所需要的文件或其他目标; - command表示具体的编译命令。
例如,假设有一个名为`的C语言源文件,我们想要生成一个名为hello`的可执行文件。
那么对应的Makefile规则可以定义如下:hello:gcc -o hello3. Makefile变量Makefile中还可以定义变量,以提高代码的可读性和重用性。
变量可以存储命令、文件名、路径等信息。
变量定义变量的定义采用变量名 = 值的方式进行,例如:CC = gcc其中,CC是变量名,gcc是变量的值。
变量引用使用变量时,需要在变量名前加$符号进行引用。
例如,使用上述定义的CC变量可以这样写:$(CC) -o hello4. Makefile示例以下是一个完整的Makefile示例,展示了多个目标之间的依赖关系和命令定义:CC = gccall: hellohello:$(CC) -o hello:$(CC) -cclean:rm -f hello在上述示例中,共定义了3个目标:all、hello和。
Makefile 语法学习
Makefile 语法学习有稍稍在Linux 下碰过程序设计的开发者应该会知道,make 是用来将程序代码、函式库、头文件及其它资源文件build 成最终成果(即:最终的应用程序)的超强力辅助工具。
当然了,并不是非得动用到make 才能build 程序,或许有什么程序设计魔人喜欢什么都自己手动进行;但利用make 及其参考档(输入档案)Makefile 将会让整个编译工作轻松许多。
若您曾经打包过Debian Package,那么应该会发现debuan/rule 这个档案的语法和Makefile 几乎是一模一样,所以学习Makefile 的语法对于Debian Package Maintainer 而言也是一门必要的功课。
Makefile语法:以下为Makefile 的基本语法,批注:以# 开头的即为批注。
变量宣告:(有人称之为宏)语法:MACRO = value注意到,在=前后必须加上空白,而变量名称为大小写相异。
利用MACRO = 来取消该变数。
在惯例上,Makefile 内部使用的变量名称使用小写;而使用者很可能从命令行自行另外指定数值的变量,像是CFLAGS,则是使用大写。
在Makefile 中,可利用$(MACRO) 或${MACRO} 来存取已定义的变量。
例:tragets = foo$(targets): common.hgcc -o $(targets) foo.c效果等同:foo: common.hgcc -o foo foo.c:=语法注意到,make 会将整个Makefile 展开后,再决定变数的值。
也就是说,变量的值将会是整个Mackfile 中最后被指定的值。
例:x = fooy = $(x) barx = xyz# y 的值为xyz bar在上例中,y 的值将会是xyz bar,而不是foo bar。
您可以利用:= 来避开这个问题。
:= 表示变量的值决定于它在Makefile 中的位置,而不是整个Makefile 展开后最终的值。
makefile详解
makefile详解makefile⼀、初识makefile想要掌握makefile,⾸先需要了解两个概念,⼀个是⽬标(target),另⼀个就是依赖(dependency)。
⽬标就是指要⼲什么,或说运⾏ make 后⽣成什么,⽽依赖是告诉 make 如何去做以实现⽬标。
在 Makefile 中,⽬标和依赖是通过规则(rule)来表达的。
(⼀)、⽬标⾸次编写makefileall:echo "Hello world"上⾯Makefile 中的 all 就是我们的⽬标,⽬标放在‘:’的前⾯,其名字可以是由字⺟和下划线‘_’组成。
echo “Hello World”就是⽣成⽬标的命令,这些命令可以是任何你可以在你的环境中运⾏的命令以及 make 所定义的函数等等。
all ⽬标的定义,其实是定义了如何⽣成 all ⽬标,这我们也称之为规则.makefile定义多个⽬标all:echo "Hello world"test:echo "test game"下⾯是运⾏的结果由此可见,⼀个 Makefile 中可以定义多个⽬标。
调⽤ make 命令时,我们得告诉它我们的⽬标是什么,即要它⼲什么。
当没有指明具体的⽬标是什么时,那么 make 以 Makefile ⽂件中定义的第⼀个⽬标作为这次运⾏的⽬标。
这“第⼀个”⽬标也称之为默认⽬标(和是不是all没有关系)。
当 make 得到⽬标后,先找到定义⽬标的规则,然后运⾏规则中的命令来达到构建⽬标的⽬的。
makefile中取消多余的命令⾏显⽰在上⾯的指令中,多了很多的echo "......"的内容,这部分不是我们所期望的,如果要去掉,需要对上⾯的makefile进⾏⼀个改动,也就是在命令前加上⼀个@,这个符号就是告诉make,在运⾏的时候这⼀⾏命令不显⽰出来。
all:@echo "Hello world"test:@echo "test game"运⾏结果:紧接着对makefile进⾏如下的改动,在all的后⾯加上testall: test@echo "Hello world"test:@echo "test game"运⾏结果如下:如上图所⽰,此时test也被构建了。
makefile 语法
makefile 语法makefile是一种常用的自动化构建工具,它可以帮助我们将源代码编译、链接、打包等一系列操作自动化完成。
在软件开发中,makefile 已经成为了不可或缺的工具之一。
本文将介绍 makefile的语法及其用法,希望能够帮助读者更好地理解和使用 makefile。
一、makefile 的基本语法makefile 的基本语法包括目标、依赖、命令三个要素。
下面我们来逐一介绍。
1. 目标目标是指要生成的文件,也就是 makefile 的最终输出。
目标通常是一个可执行文件、一个库文件或者一个归档文件。
在 makefile 中,目标通常以文件名的形式出现。
例如:```app: main.c func.c```这里的“app”就是目标。
2. 依赖依赖是指生成目标所需要的文件或者其他目标。
在 makefile 中,依赖通常以文件名的形式出现。
例如:```app: main.c func.c```这里的“main.c”和“func.c”就是依赖。
3. 命令命令是指生成目标所需要执行的命令。
在 makefile 中,命令通常以“TAB”键开头,并且必须与目标或者依赖之间有一个空格。
例如:```app: main.c func.cgcc main.c func.c -o app```这里的命令是“gcc main.c func.c -o app”。
二、makefile 的实例了解了 makefile 的基本语法后,我们来看一个简单的makefile 实例:```app: main.c func.cgcc main.c func.c -o app```这个 makefile 的作用是将“main.c”和“func.c”编译成一个可执行文件“app”。
如果我们在命令行中执行“make”命令,make 就会自动根据 makefile 中的规则来生成目标文件“app”。
三、makefile 的高级语法除了基本语法之外,makefile 还有一些高级语法,如变量、函数、条件语句等。
makefile 中文手册 第四章 _ Makefile的规则
第四章:Makefile的规则本章我们将讨论Makefile的一个重要内容,规则。
熟悉规则对于书写Makefile至关重要。
Makefile中,规则描述了在何种情况下使用什么命令来重建一个特定的文件,此文件被称为规则“目标”(通常规则中的目标只有一个)。
规则中出目标之外的罗列的其它文件称为“目标”的依赖,而规则的命令是用来更新或者创建此规则的目标。
除了makefile的“终极目标”所在的规则以外,其它规则的顺序在makefile文件中没有意义。
“终极目标”就是当没有使用make 命令行指定具体目标时,make默认的更新的哪一个目标。
它是makefile文件中第一个规则的目标。
如果在makefile中第一个规则有多个目标的话,那么多个目标中的第一个将会被作为make的“终极目标”。
有两种情况的例外:1. 目标名以点号“.”开始的并且其后不存在斜线“/”(“./”被认为是当前目录;“../”被认为是上一级目录);2. 模式规则的目标。
当这两种目标所在的规则是Makefile的第一个规则时,它们并不会被作为“终极目标”。
“终极目标”是执行make的唯一目的,其所在的规则作为第一个被执行的规则。
而其它的规则是在完成重建“终极目标”的过程中被连带出来的。
所以这些目标所在规则在Makefile中的顺序无关紧要。
因此,我们书写的makefile的第一个规则应该就是重建整个程序或者多个程序的依赖关系和执行命令的描述。
4.1 一个例子我们来看一个规则的例子:foo.o : foo.c defs.h # module for twiddling the frobscc -c -g foo.c这是一个典型的规则。
看到这个例子,大家应该能够说出这个规则的各个部分之间的关系。
不过我们还是要把这个例子拿出来讨论。
目的是让我们更加明确地理解Makefile的规则。
本例第一行中,文件“foo.o”是规则需要重建的文件,而“foo.c”和“defs.h”是重建“foo.o”所要使用的文件。
Makefile学习
Makefile学习Makefile ⽂件描述了 Linux 系统下 C/C++ ⼯程的编译规则,它⽤来⾃动化编译 C/C++ 项⽬。
⼀旦写编写好 Makefile ⽂件,只需要⼀个 make 命令,整个⼯程就开始⾃动编译,不再需要⼿动执⾏ GCC 命令。
⼀个中⼤型 C/C++ ⼯程的源⽂件有成百上千个,它们按照功能、模块、类型分别放在不同的⽬录中,Makefile ⽂件定义了⼀系列规则,指明了源⽂件的编译顺序、依赖关系、是否需要重新编译等。
参考:1. Makefile⽂件是什么?Windows环境:如果你是在 Windows 下作开发的话不需要去考虑这个问题,因为 Windows 下的集成开发环境(IDE)已经内置了 Makefile,或者说会⾃动⽣成 Makefile,我们不⽤去⼿动编写。
Linux环境:Linux 中却不能这样,需要我们去⼿动的完成这项⼯作。
不懂 Makefile,就操作不了多⽂件编程,就完成不了相对于⼤的⼯程项⽬的操作。
Makefile 可以简单的认为是⼀个⼯程⽂件的编译规则,描述了整个⼯程的编译和链接等规则。
其中包含了那些⽂件需要编译,那些⽂件不需要编译,那些⽂件需要先编译,那些⽂件需要后编译,那些⽂件需要重建等等。
编译整个⼯程需要涉及到的,在 Makefile 中都可以进⾏描述。
换句话说,Makefile 可以使得我们的项⽬⼯程的编译变得⾃动化,不需要每次都⼿动输⼊⼀堆源⽂件和参数。
以 Linux 下的C语⾔开发为例来具体说明⼀下,多⽂件编译⽣成⼀个⽂件,编译的命令如下所⽰:gcc -o outfile name1.c name2.c ...outfile 要⽣成的可执⾏程序的名字,nameN.c 是源⽂件的名字。
这是我们在 Linux 下使⽤ gcc 编译器编译 C ⽂件的例⼦。
如果我们遇到的源⽂件的数量不是很多的话,可以选择这样的编译⽅式。
如果源⽂件⾮常的多的话,就会遇到下⾯的这些问题:1) 编译的时候需要链接库的的问题。
makefile入门 PPT课件
makefile:编译使用的文件二 • :=和=的区别:
Q&A
谢谢!
隐式规则 • 看如下的一个编译规则: %.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ %.o(目标,target) : %.c(依赖, prerequisites ) 是表示把所有的[.c]文件都编译成[.o]文件; $< 是每次匹配到的那个依赖文件 $@ 是每次匹配到的那个目标文件
• 什么是makefile
• 分析一个简单的makefile
makefile的基本结构 helloworld的makefile
• Makefile中经常用到的知识 • 我们常用的makefile是如何组成的
• 什么是makefile • 分析一个简单的makefile
• Makefile中经常用到的知识
• 什么是makefile • 分析一个简单的makefile • Makefile中经常用到的知识
• 我们常用的makefile是如何组成的
m:通用库调用路径 makefile:编译使用的文件
m:通用库调用路径 • “-I” :定义了你自己的头文件的存储目录。 • “-L”:定义了你自己的库文件存放目录。 • Make中可以定义变量,直接赋值就可以了: ARPS_ROOT = /home/yedeng/arps • 引用变量使用$(APRS_ROOT),make会自动进行替 换。将$(APRS_ROOT)用“/home/yedeng/arps”来代 替。 实际看我们用的一个m:打开文件
makefile笔记
makefile笔记Makefile是一个用来组织和管理程序编译和链接的工具。
通过定义一系列规则和命令,我们可以使用Makefile来自动化构建和管理大型项目的编译过程。
本文将介绍Makefile的基本语法和常用命令,以及如何编写一个简单的Makefile文件。
一、Makefile基本语法1. 标准格式Makefile由一系列规则组成,每个规则包含了一个目标(target)、我们想要生成的文件名,以及生成目标所需要的依赖关系(prerequisites)和命令(recipe)。
通常一个规则的基本格式如下:```makefiletarget: prerequisitesrecipes```其中,target是需要生成的文件名,prerequisites是依赖文件,recipes是生成目标所需要执行的命令。
2. 规则的执行原则- 如果target不存在或者target的依赖文件比target更新,那么执行recipes中的命令。
- 如果target的依赖文件有更新,那么也会执行recipes中的命令。
3. 空格和Tab键缩进在Makefile中,空格和Tab键具有不同的含义。
空格用来分隔目标、依赖和命令,而Tab键则用来标识命令行。
因此,在Makefile中,必须使用Tab键来缩进每条命令。
二、Makefile常用命令1. makemake命令是用来执行Makefile中的规则的。
通过运行make命令,可以自动编译和链接项目。
```shellmake target```2. make cleanclean是一个常用的命令,用于清除编译生成的文件。
在Makefile中,我们可以定义一个clean规则,然后通过运行make clean命令来执行清除操作。
```makefileclean:rm -f target```3. make allall是另一个常用的命令,在Makefile中可以定义一个all规则,用于执行整个项目的编译和生成。
makefile学习笔记
1,以#开头的行为注释行,相当于C语言的// ,在makefile中是区分大小写的,make和MAKE是不一样的。
如果需要在makefile中使用#的符号,就要用反斜杠\#转义成#本身的意义2,makefile格式目标:依赖文件1,依赖文件2命令–依赖文件后缀依赖文件1,依赖文件2,目标注意:命令行必须以单个的TAB字符进行缩进,不能是空格当然也可以跟目标和依赖文件在一行,不过要以;隔开3,宏定义在linux中其实就是变量定义,在引用宏时必须在宏前加上$符号,而且如果变量名的长度超过一个字符,在引用时必须加圆括号()。
注意:$Z=$(Z),$(2),$(CFLAGS)都是有效的变量4,$*,$@,$?,$<四个特殊的宏的值在执行命令的过程中会发生相应的变化(自动化变量)5,宏的定义很简单,格式为:变量=变量值6,反斜杠(\)有时在makefile中是换行符的意思。
7,隐晦规则指的就是.o文件自己推导出同名的依赖文件.c.8,伪目标的格式可以为:.PHONY: cleanclean:rm edit $(obiect)―.PHONY‖表示,clean是个伪目标文件。
9,有些是在命令的前面加上减号如:如上句的:-rm edit $(obiect)也许某些文件出现问题,但不要管,继续做后面的事,这个减号的作用就是加强保障,还有一个全局的办法就是给make加上“-I‖或是“ignore-errors‖参数,那么makefile中所有的命令都会忽略错误。
还有一个就是make的参数是”-k‖或是“-keep-going‖,这个参数的意思是如果规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。
10,makefile 工作执行的步骤:1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
makefile 速成
分享一篇前短时间总结的makefile速成,教你一天搞定makefile,略加实践掌握其最核心部分。
可以从下面的几个维度来学习和理解makefile:∙规则∙变量∙函数∙命令∙make的命令选项∙一个大型项目的makefile例子∙make –p的输出概览在正式介绍makefile的以上四个方面之前,首先一句话概括一下makefile 是什么:makefile是用来描述文件依赖关系,并告诉make命令如何根据这种依赖关系,调用shell完成目标文件建立的文件。
makefile的执行时通过两步来完成的,第一步是扫描文件中的依赖关系,并藉此建立依赖关系树,然后从最底层想上来执行。
1.规则(rule)Makefile从本质上说就是描述项目中文件依赖关系的文件。
这种依赖关系的描述就是规则。
Makefile的编写中的一切都是围绕规则来展开的,上面提到的四个方面:规则、变量、函数、命令都是为了规则能够方便快捷的发挥作用才引入的。
一个简单规则可以表述为:目标文件:依赖文件(不同文件以空格分隔)<tab>得到目标文件需要的命令规则的常见种类有:●∙Explicit Rule最简单的rule,明确指出了目标和依赖,以及如何有依赖得到目标。
举例:Hello.o:hello.cppg++ -c hello.cpp●∙Pattern Rule使用了wildcard(通配符)的规则。
makefile中的通配符是百分号%,相当于bash中的*,在描述规则的时候使用的都是%。
makefile中也可以看到通配符*,这个一般是出现在命令之中,命令是要放到shell中运行的,所以要使用*作为通配符。
举例:prog:*.cg++ -o prog $^●∙Suffix Rule顾名思义,是只使用后缀来描述的rule,描述的时候不使用pattern,举例:.c.o:$(COMPILE.C) $(OUTPUT_OPTION) $<这个suffix rule的作用和下面这个pattern rule的作用是完全一样的。
makefile的基本用法以及yolov3的makefile解析
makefile的基本用法以及yolov3的makefile解析Makefile的基本用法以及YOLOv3的Makefile解析Makefile是一种用于自动化构建的文件,它定义了一系列规则和依赖关系,用于编译、链接和生成可执行文件等操作。
Makefile通常用于C/C++项目中,但它也可以用于其他编程语言。
一、Makefile的基本用法1. 规则(Rule)Makefile中的规则定义了如何生成目标文件和如何根据依赖关系重新生成目标文件。
一个规则通常由以下几部分组成:target: prerequisites[tab] command- target:目标文件,即要生成的文件。
- prerequisites:目标文件的依赖文件。
- command:生成目标文件的命令。
2. 变量(Variable)Makefile中的变量用于存储值,可以在规则中引用。
常见的变量有以下几种:- CC:C/C++编译器。
- CFLAGS:编译选项。
- LDFLAGS:链接选项。
- RM:删除文件的命令。
可以通过在Makefile中定义变量来方便地修改编译和链接参数,使构建过程更加灵活。
3. 默认规则(Default Rule)Makefile中可以定义一个默认规则,当使用make命令时,会自动执行默认规则中定义的命令。
默认规则的语法如下:.PHONY: allall: target- .PHONY:伪目标,表示该规则是一个伪目标。
- all:默认规则的名字。
- target:默认规则要生成的目标文件。
4. 命令行变量在执行make命令时,可以通过命令行参数传递变量的值。
例如,make CC=gcc可以将CC变量的值设置为gcc。
5. clean规则clean规则用于删除生成的目标文件和其他中间文件,以便重新构建项目。
通常的写法是:clean:[tab] (RM) target这里的(RM)是一个预定义变量,表示删除文件的命令(通常为rm -f)。
makefile语法详解
makefile语法详解Makefile 是一种构建自动化工具,它用于管理源代码的编译顺序和依赖关系。
Makefile 使得程序员能够简化构建过程、自动处理依赖关系、并增强项目的可读性和可理解性。
Makefile 使用一些特定语法来实现这些功能,这篇文章将带领大家逐步学习 Makefile 的语法。
1. 行尾分隔符在 Makefile 中,行尾的分隔符是一个反斜杠( \ )。
这个符号可以将一行的内容分成多行,在下一行继续编写。
这样做不会改变命令的含义,但会使命令更易读。
2. 变量定义Makefile 中的变量可以定义用于存储字符串。
这些变量可以在整个 Makefile 中使用,方便地重用代码。
定义变量的语法是使用美元符号( $)和括号( ())包含变量的名字。
例如:``` CFLAGS = -Wall -g CC = gcc ```在这个例子中,我们定义了两个变量,一个用于存储编译器选项(CFLAGS),另一个用于存储编译器名称(CC)。
3. 条件语句Makefile 支持条件语句来控制项目的编译方式。
条件语句的语法基于 ifeq、ifdef、ifndef、endif 等关键字。
例如,下面的代码段将根据目标平台指定编译器选项:``` ifndef PLATFORM $(error "You must define PLATFORM") endififeq ($(PLATFORM), WINDOWS) CFLAGS += -DWIN32 endif ```4. 函数Makefile 中的函数是一个有用的工具,可以实现在Makefile 中执行某些任务。
这些函数在规则和命令中使用,语法主要是通过 $() 实现的。
例如,$(wildcard) 函数,可以用于扩展通配符,例如:``` SOURCE_FILES = $(wildcard *.c) ```5. 模式规则Makefile 中的模式规则是一种将一类文件与另一类文件匹配的规则。
Makefile培训
联通系统集成公司山东分公司 技术部 王鹏
目录
Makefile概述 Makefile规则 Makefile条件 Makefile隐式规则 Makefile
1、Makefile概述: Makefile概述: 概述
1.1、Make工具: 1.1、Make工具: 工具
make是一种命令工具,它解释Makefile中的指令,Makefile描述了工 程中所有文件的编译顺序、规则。 Linux下make是 GNU make(gmake),对于其他操作系统有自带的 make,他们使用的Makefile基本相似,但有些语法不兼容。所以,在安装编 译某些软件的时候,需要先安装gmake,然后才能安装编译。
2.5、 2.5、自动化变量
[示例] test.o : test.cpp xlC -c $(CFLAGS) $^ -o $@ (其中,$^和$@为自动化变量。) 自动化变量列表以及定义: $^ :代表规则中所有的依赖文件列表。(一次性引用,去掉重复的依赖文件。) $@ :代表规则中的目标文件名。 $? :更新的依赖文件列表。 $< :规则中第一个依赖文件名。
【注释】 -g 带调试信息。 -w (小写)忽略一些警告。 -c 编译成中间文件,以文件名命名。 -o 编译成可执行文件。
或者 testmain:testmain.o libfile_search.a g++ -g –w –o –L./ testmain testmain.o -lfile_search testmain.o:testmain.cpp g++ -g –w –c testmain.cpp libfile_search.a:file.o search.o ar –r libfile_search.a file.o search.o file.o:file.cpp g++ -g –w –c file.cpp search.o:search.cpp g++ -g –w –c search.cpp
跟我一起学makefile
Makefile学习教程: 跟我一起写Makefile o0 Makefile概述▪0.1 关于程序的编译和链接o 1 Makefile 介绍▪1.1 Makefile的规则▪1.2 一个示例▪1.3 make是如何工作的▪1.4 makefile中使用变量▪1.5 让make自动推导▪1.6 另类风格的makefile▪1.7 清空目标文件的规则o 2 Makefile 总述▪2.1 Makefile里有什么?▪2.2Makefile的文件名▪2.3 引用其它的Makefile▪2.4 环境变量MAKEFILES▪2.5 make的工作方式o 3 Makefile书写规则▪3.1 规则举例▪3.2 规则的语法▪3.3 在规则中使用通配符▪3.4 文件搜寻▪3.5 伪目标▪3.6 多目标▪3.7 静态模式▪3.8 自动生成依赖性o 4 Makefile 书写命令▪4.1 显示命令▪4.2 命令执行▪4.3 命令出错▪4.4 嵌套执行make▪4.5 定义命令包什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional 的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。
特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
C++学习进阶之Makefile基础用法详解
$(TARGET):$(TESTOBJ) $(LIB) $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS)
$(LIB):$(OBJS) $(CXX) -shared $^ -o $@
$(TESTOBJ) $(OBJS):%.o:%.cpp $(CXX) $(CXXFLAGS) $< -o $@
makefile 文件可改为:
TARGET = simpletest OBJS = simple.o simpletest.o
$(TARGET):$(OBJS) g++ $(OBJS) -o $(TARGET)
simple.o:simple.cpp simpletest.o:simpletest.cpp clean:
绝大多数的 IDE 开发环境都会为用户自动编写 Makefile。
Make 是怎么工作的?
Make 工作的原则就是:
一个目标文件当且仅当在其依赖文件(dependencies)的更改时间戳比该目标文件的创建时间戳新时,这个目标文件才需要 被重新编译。
Make 工具会遍历所有的依赖文件,并且把它们对应的目标文件进行更新。编译的命令和这些目标文件及它们对应的依赖文件 的关系则全部储存在 Makefile 中。
Makefile 中也指定了应该如何创建,创建出怎么样的目标文件和可执行文件等信息。
除此之外,你甚至还可以在 Makefile 中储存一些你想调用的系统终端的命令,像一个 Shell 脚本一样使用它。
作用:
Makefile 文件告诉 Make 怎样编译和连接成一个程序
可用命令 dnf install make 安装make功能
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
x : y.o z.o
当“x.c”、“y.c”和“z.c”都存在时,规则执行如下命令:
cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o
1. 编译C程序
“N.o”自动由“N.c” 生成,执行命令为“$(CC) -c $(CPPFLAGS) $(CFLAGS)”。
2. 编译C++程序
“N.o”自动由“”或者“N.C” 生成,执行命令为“$(CXX) -c $(CPPFLAGS) $(CFLAGS)”。建议使用“.cc”作为C++源文件的后缀,而不是“.C”
10.2 make的隐含规则一览
本节罗列出了GUN make常见的一些内嵌隐含规则,除非在Makefile有名确定义、或者使用命令行“-r”或者“-R”参数取消隐含规则,否则这些隐含规则将有效。
需要说明的是:即使我们没有使用命令行参数“-r”,在make中也并不是所有的这些隐含规则都被定义了。其实,很多的这些看似预定义的隐含规则在make执行时,实际是用后缀规则来实现的;因此,它们依赖于make中的“后缀列表”(也就是目标.SUFFIXES的后缀列表)。make的默认后缀列表为:“.out”、“.a”、“.ln”、“.o”、“.c”、“.cc”、“.C”、“.p”、“.f”、“.F”、“.r”、“.y”、“.l”、“.s”、“.S”、“.mod”、“.sym”、“.def”、“.h”、“.info”、“.dvi”、“.tex”、“.texinfo”、“.texi”、“txinfo”、“.w”、“.ch”、“.web”、“.sh”、“.elc”、“el”。所有我们下边将提到的隐含规则,如果其依赖文件中某一个满足列表中列出的后缀,则是后缀规则。如果修改了可识别后缀列表,那么可能会是许多默认预定义的规则无效(因为一些后缀可能不会别识别)。以下是常用的一些隐含规则(对于不常见的隐含规则这里没有描述):
这里并没有给出重建文件“foo.o”的规则,make执行这条规则时,无论文件“foo.o”存在与否,都会试图根据隐含规则来重建这个文件(就是试图重新编译文件“foo.c”或者其它类型的源文件)。
make执行过程中找到的隐含规则,提供了此目标的基本依赖关系,确定了目标的依赖文件(通常是源文件,不包含对应的头文件依赖)和重建目标需要使用的命令行。隐含规则所提供的依赖文件只是一个最基本的(通常它们之间的对应关系为:“EXENAME.o”对应“EXENAME.c”、“EXENAME”对应于“EXENAME.o”)。当需要增加这个目标的依赖文件时,要在Makefile中使用没有命令行的规则给出。
内嵌的“隐含规则”在其所定义的命令行中,会使用到一些变量(通常也是内嵌变量)。我们可以通过改变这些变量的值来控制隐含规则命令的执行情况。例如:内嵌变量“CFLAGS”代表了gcc编译器编译源文件的编译选项,我们就可以在Makefile中重新定义它,来改变编译源文件所要使用的参数。
尽管我们不能改变make内嵌的隐含规则,但是我们可以使用模式规则重新定义自己的隐含规则,也可以使用后追规则来重新定义隐含规则。后缀规则存在某些限制(目前版本make保存它的原因是为了兼容以前版本)。使用模式规则更加清晰明了。
make会根据默认的约定,使用“COMPILE.x”来编译一个“.x”的文件。类似地使用“LINK.x”来连接“.x”文件;使用“PREPROCESS.x”对“.x”文件进行预处理。
Makefile中重建一类目标的标准规则在很多场合需要用到。例如:根据.c源文件创建对应的.o文件,传统方式是使用GNU 的C编译器。
“隐含规则”为make提供了重建一类目标文件通用方法,不需要在Makefile中明确地给出重建特定目标文件所需要的细节描述。例如:典型地;make对C文件的编译过程是由.c源文件编译生成.o目标文件。当Makefile中出现一个.o文件目标时,make会使用这个通用的方式将后缀为.c的文件编译称为目标的.o文件。
通常,make会对那些没有命令行的规则、双冒号规则寻找一个隐含规则来执行。作为一个规则的依赖文件,在没有一个规则明确描述它的依赖关系的情况下;make会将其作为一个目标并为它搜索一个隐含规则,试图重建它。
注意:给目标文件指定明确的依赖文件并不会影响隐含规则的搜索。我们来看一个例子:
foo.o: foo.p
3. 编译Pascal程序
“N.o”自动由“N.p”创建,执行命令时“$(PC) -c $(PFLAGS)”。
4. 编译Fortran/Ratfor程序
“N.o”自动由“N.r”、“N.F”或者“N.f” 生成,根据源文件后缀执行对应的命令:
.f — “$(FC) –c $(FFLAGS)”
上边提到,make会自动根据已存在(或者可以被创建)的源文件类型来启动相应的隐含规则。这里的“可被创建”文件是指:这个文件在Makefile中被作为目标或者依赖明确的提及,或者可以根据已存在的文件使用其它的隐含规则来创建它。当一个隐含规则的目标是另外一个隐含规则的依赖时,我们称它们是一个隐含规则链。
Hale Waihona Puke 这里没有列出所有的隐含规则,仅列出我个人在实际工作中涉及到的。没有涉及的很难对英文文档进行深入地说明和理解。如果那些没有提到的各位有所使用,或者能够详细的描述可以添加到这个文档中!
在隐含规则中,命令行中的实际命令是使用一个变量计算得到,诸如:“COMPILE.c”、“LINK.o”(这个在前面也看到过)和“PREPROCESS.S”等。这些变量被展开之后就是对应的命令(包括了命令行选项),例如:变量“COMPILE.c”的定义为 “cc -c”(如果Makefile中存在“CFLAGS”的定义,它的值会存在于这个变量中)。
8. 链接单一的object文件
“N”自动由“N.o”生成,通过C编译器使用链接器(GUN ld),执行命令是:“$(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS)”。
此规则仅适用:由一个源文件直接产生可执行文件的情况。当需要有多个源文件共同来创建一个可执行文件时,需要在Makefile中增加隐含规则的依赖文件。例如:
.F — “$(FC) –F $(CPPFLAGS) $(FFLAGS)”
.r — “$(FC) –F $(FFLAGS) $(RFLAGS)”
6. 编译Modula-2程序
“N.sym”自动由“N.def” 生成,执行的命令是:“$(M2C) $(M2FLAGS) $(DEFFLAGS)”。“N.o”自动由“N.mod”生成,执行的命令是:“$(M2C) $(M2FLAGS) $(MODFLAGS)”。
在复杂的场合,目标文件和源文件之间不存在向上边那样的名字对应关系时(“x”和“x.c”对应,因此隐含规则在进行链接时,自动将“x.c”作为其依赖文件)。这时,需要在Makefile中明确给出描述目标依赖关系的规则。
通常,gcc在编译源文件时(根据源文件的后缀名来启动相应的编译器),如果没有指定“-c”选项,gcc会在编译完成之后调用“ld”连接成为可执行文件。
例子中没有出现任何关于源文件的描述。所有剩余工作全部交给了make去处理,它会自动寻找到相应规则并执行、最终完成目标文件的重建。
隐含规则为我们提供了一个编译整个工程非常高效的手段,一个大的工程中毫无例外的会用到隐含规则。实际工作中,灵活运用GNU make所提供的隐含规则功能,可以大大提供效率。
7. 汇编和需要预处理的汇编程序
“N.s”是不需要预处理的汇编源文件,“N.S”是需要预处理的汇编源文件。汇编器为“as”。
“N.o” 可自动由“N.s”生成,执行命令是:“$(AS) $(ASFLAGS)”。
“N.s” 可由“N.S”生成,C预编译器“cpp”,执行命令是:“$(CPP) $(CPPFLAGS)”。
每一个内嵌的隐含规则中都存在一个目标模式和依赖模式,而且同一个目标模式可以对应多个依赖模式。例如:一个.o文件的目标可以由c编译器编译对应的.c源文件得到、Pascal编译器编译.p的源文件得到,等等。make会根据不同的源文件来使用不同的编译器。对于“foo.c”就是用c编译,对于“foo.p”就使用Pascal编译器编译。
另外:当我们不想让make为一个没有命令行的规则中的目标搜索隐含规则时,我们需要使用空命令来实现。
最后让我们来看一个简单的例子,之前在目标指定变量 一节的例子我们就可以简化为:
# sample Makefile
CUR_DIR = $(shell pwd)
INCS := $(CUR_DIR)/include
这个规则指定了“foo”的依赖文件是“foo.p”。但是如果在工作目录下存在同名.c源文件“foo.c”。执行make的结果就不是用“pc”编译“foo.p”来生成“foo”,而是用“cc”编译“foo.c”来生成目标文件。这是因为在隐含规则列表中对.c文件的隐含规则处于.p文件隐含规则之前。
9. Yacc C程序
“N.c”自动由“N.y”,执行的命令:“$(YACC) $(YFALGS)”。(“Yacc”是一个语法分析工具)
10. Lex C程序时的隐含规则。
“N.c”自动由“N.l”,执行的命令是:“$(LEX) $(LFALGS)”。(关于“Lex”的细节请查看相关资料)
另外,在make执行时根据需要也可能是用多个隐含规则。比如:make将从一个.y文件生成对应的.c文件,最后再生成最终的.o文件。就是说,只要目标文件名中除后缀以外其它部分相同,make都能够使用若干个隐含规则来最终产生这个目标文件(当然最原始的那个文件必须存在)。例如;可以在Makefile中这样来实现一个规则:“foo : foo.h”,只要在当前目录下存在“foo.c”这个文件,就可以生成“foo”可执行文件。本文前边的很多例子中已经使用到了隐含规则。