Makefile伪目标

合集下载

makefile all用法

makefile all用法

makefile all用法Makefile是一种类似于脚本的文件,可以用来自动化构建、编译和整合代码。

Makefile中常常会用到all指令,可以一次性执行多个任务。

本篇文章将详细说明Makefile中all指令的用法。

一、all指令的用途在Makefile中使用all指令的语法非常简单,只需要在文件中添加如下代码即可:all:<command1><command2><command3>...<command_n>其中,<command>表示需要执行的命令,可以是编译、构建、安装等一系列操作。

在语法中,all指令后面紧跟着“:”,表示all指令执行的是“伪目标”,而不是一个真正的文件。

也就是说,all指令并不会生成任何东西,它只是用来方便执行多个任务的一个指令。

1. all指令必须放在Makefile文件的开头。

这是因为,Makefile文件中的第一个目标就是Makefile默认的目标,也就是all指令。

2. all指令的语句必须以制表符(Tab)开头,否则会出现错误。

这是因为Makefile中使用了缩进,而不是空格,来标识命令与目标之间的关系。

因此,必须使用制表符来开头。

3. 如果在执行all指令的时候,其中的某个命令失败了,则后续的命令将不再执行。

这是因为Makefile中使用的是顺序执行的方式,即一个任务执行完成后才会进行下一个任务的执行。

下面是一个简单的Makefile文件,其中包含了几个常用的构建命令:说明:4. 使用make命令时,可以通过传递参数来指定执行的目标。

比如make clean,就只会执行clean目标下的所有命令。

总结:Makefile中使用all指令能够一次性执行多个命令,方便快捷。

在Makefile文件中添加all指令时,需要注意语法和文件位置等问题,避免出现错误。

在实际开发过程中,建议在Makefile文件中添加clean等指令,用于清理生成的目标文件和可执行文件。

Makefile 语法分析

Makefile 语法分析

Makefile 语法分析第一部分VERSION = 2# 给变量VERSION赋值PATCHLEVEL = 6# 给变量PATCHLEVEL赋值SUBLEVEL = 22# 给变量SUBLEVEL赋值EXTRAVERSION = .6# 给变量EXTRAVERSION赋值NAME = Holy Dancing Manatees, Batman!# 给变量NAME赋值# *DOCUMENTATION*# To see a list of typical targets execute "make help"# More info can be located in ./README# Comments in this file are targeted only to the developer, do not# expect to learn how to build the kernel reading this file.# Do not:# o use make's built-in rules and variables# (this increases performance and avoid hard-to-debug behavour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory# 操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。

# 如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”;# 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;# 如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符# 在执行make时的命令行选项参数被通过变量“MAKEFLAGS”传递给子目录下的make程序。

Windows 下的 Makefile 编写(一)Makefile的基本规则

Windows 下的 Makefile 编写(一)Makefile的基本规则

下的编写(一)的基本规则作者:对于很多人来说是陌生的,特别是习惯于使用的人来说,似乎没有听说过,因为的工作都由代劳了。

但是的地位是不可忽略的,从诞生到现在这个实用程序就一直伴随着编译器一起发行。

很多大的工程都是基于编译和维护的,对于开源项目来说,大多数都使用进行编译,使用来编译大型工程是不可想象的。

是什么?它是一个文本文件,里面记录着项目由哪些目标构成,以及各个目标的生成方式等信息,的核心任务是定义一系列的规则,然后由来解释执行,任何一个文本编辑器都可以用来编写。

先来大概看一下的基本规则:是目标,目标可以是一个文件,也可以是一个标签,如果用作标签,则称之为伪目标。

至少要有一个目标。

是依赖项目,指明目标所依赖的具体项目。

依赖项目和目标之间用号分隔。

是命令,如果命令和依赖项目在同一行,则需要使用号与之相隔,各个命令之间使用空格或键分开,如果命令是单独一行,则需要使用缩进。

命令由来执行。

上述内容简单地表明了一个依赖关系,生成目标依赖中指定的文件,而生成的规则由来定义,负责执行这些命令。

默认情况下,会查找当前目录下任何名称为的文件(名称不区分大小写,并且没有后缀),如果你的文件名称是其他的,则需要使用参数指定。

以上就是的核心内容,任何系统的都是这样执行的。

但是要写好一个,仅仅这些还不够。

对于一个新知识,我更喜欢从做中学。

下面举一个例子来说明上面的规则在实际应用中如何操作:在中注释使用号开头,且仅有这一种注释方式。

它的作用和语法中的注释是一样的。

所不同的是号必须放在行首。

上面的文件指定了两个目标,分别是和,生成需要依赖文件,而生成文件依赖。

在目标下方指明了生成该目标方法。

将和放置于同一目录下,在的命令提示符窗口中执行命令,就会自动生成和两个文件。

再运行生成后的测试一下:在中定义了两个目标,默认只生成中的第一个目标,由于是的依赖项,所以目标也得以执行。

是不是每执行一次命令就会重新生成一次目标文件呢?答案:不是。

makefile编译c++工程示例

makefile编译c++工程示例

以下是一个简单的Makefile示例,用于编译C++工程。

```makefile
CC = g++
CFLAGS = -Wall -g
all: main
main: main.o helper.o
$(CC) $(CFLAGS) main.o helper.o -o main
main.o: main.cpp helper.h
$(CC) $(CFLAGS) -c main.cpp
helper.o: helper.cpp helper.h
$(CC) $(CFLAGS) -c helper.cpp
clean:
rm -f *.o main
```
Makefile包含四个主要部分:
1. 变量定义:定义编译器CC和编译选项CFLAGS。

2. 规则定义:定义如何从源文件编译为目标文件。

规则使用“模式规则”的形式,即“目标: 依赖项”,以及一条命令来指定如何生成目标。

例如,main规则指定了如何从main.o和helper.o编译得到可执行文件main。

3. 依赖项定义:指定每个目标文件所依赖的源文件和头文件。

例如,main.o依赖于main.cpp和helper.h。

4. 伪目标定义:定义一个特殊的伪目标“clean”,它没有任何依赖项,但是用于清理生成的目标文件。

要使用此Makefile编译工程,只需在终端中运行“make”命令即可。

make的主要用法

make的主要用法

make的主要用法Make是一个常用的构建工具,它可以自动化地编译程序、生成文档、打包发布等操作。

Make最初是Unix系统下的一个工具,现在已经被广泛地应用于各种平台和语言中。

一、Make的基本概念1.1 MakefileMakefile是Make的配置文件,它描述了如何构建目标文件。

Make会根据Makefile中的规则来判断哪些文件需要重新编译,以及如何编译它们。

1.2 目标文件目标文件是指要生成的文件,可以是可执行程序、静态库、动态库等。

在Makefile中,每个目标都有一个对应的规则来描述如何生成它。

1.3 依赖关系依赖关系指的是目标文件与源文件之间的关系。

如果一个目标文件依赖于另外一个文件,那么在生成这个目标文件之前必须先生成它所依赖的那个文件。

1.4 规则规则描述了如何从源代码生成目标代码。

规则由三部分组成:目标、依赖和命令。

其中,目标表示要生成的文件,依赖表示该目标所依赖的其他文件,命令表示如何从依赖中生成目标。

二、Makefile语法2.1 变量定义变量可以用来存储一些常用的值,比如编译器、编译选项等。

变量的定义格式为:变量名=变量值。

2.2 目标规则目标规则描述了如何生成一个目标文件。

目标规则的格式为:目标: 依赖命令其中,目标表示要生成的文件,依赖表示该目标所依赖的其他文件,命令表示如何从依赖中生成目标。

2.3 伪目标伪目标是指不对应任何实际文件的目标,它们通常用来描述一些特殊的操作,比如清空临时文件、打包发布等。

伪目标的名称前面要加上一个“.”号。

2.4 函数Make提供了一些内置函数来方便我们编写Makefile。

常用的函数有:$(wildcard pattern)、$(patsubst pattern,replacement,text)、$(subst from,to,text)等。

三、Makefile实例下面是一个简单的Makefile示例:CC=gccCFLAGS=-Wall -gLDFLAGS=-lmall: hello_world.exehello_world.exe: hello_world.o$(CC) $(LDFLAGS) $< -o $@hello_world.o: hello_world.c$(CC) $(CFLAGS) -c $< -o $@clean:rm -f *.o *.exe这个Makefile定义了三个变量:CC表示编译器,CFLAGS表示编译选项,LDFLAGS表示链接选项。

python makefile编写规则

python makefile编写规则

Python Makefile编写规则随着Python语言的流行和应用范围的不断扩大,开发人员在日常工作中经常会用到Makefile来管理代码的编译和部署过程。

Makefile 是一个用于组织代码编译和部署流程的工具,它可以帮助开发人员自动化代码构建的过程,提高工作效率。

在Python项目中,编写规范的Makefile可以帮助开发人员管理项目中繁杂的编译和部署过程,本文将介绍Python Makefile编写的规则和技巧。

一、Makefile简介Makefile是一个包含一系列规则的文件,用于指定代码的编译和部署过程。

它通常由一系列规则、依赖关系和命令组成,它告诉make命令如何编译和信息代码。

Makefile通常用于C/C++项目的编译,但在Python项目中同样有着广泛的应用。

二、Python Makefile编写规则1. 定义变量在编写Python Makefile时,首先需要定义一些变量,这些变量可以用于存储编译器、编译选项、源文件目录、目标文件目录等。

下面是一个简单的Python Makefile示例:```MakefileCC = pythonCFLAGS = -O2SRC_DIR = srcOBJ_DIR = obj```2. 定义规则在Makefile中,可以定义一系列规则来指定如何编译和信息代码。

在Python项目中,通常会定义编译规则、信息规则和清理规则。

下面是一个简单的Python Makefile示例:```Makefileall: $(OBJ_DIR)/m本人n.o$(CC) $(CFLAGS) $(OBJ_DIR)/m本人n.o -o app$(OBJ_DIR)/m本人n.o: $(SRC_DIR)/m本人n.py$(CC) $(CFLAGS) -c $(SRC_DIR)/m本人n.py -o $(OBJ_DIR)/m本人n.oclean:rm -f $(OBJ_DIR)/*.o app```在上面的示例中,定义了三个规则:all规则用于编译信息代码生成可执行文件,$(OBJ_DIR)/m本人n.o规则用于编译源文件生成目标文件,clean规则用于清理生成的目标文件和可执行文件。

linux中make函数作用

linux中make函数作用

linux中make函数作用make函数是Linux系统中常用的命令之一,它的作用是根据源文件的依赖关系,自动化地管理程序的编译、链接和安装过程。

在Linux系统中,make函数被广泛应用于软件开发、系统维护和自动化脚本编写等领域。

一、make函数的基本概念和用法make函数是一个构建工具,它通过读取名为Makefile的文件来执行相应的操作。

Makefile是一个文本文件,其中包含了一系列规则和指令,用于描述源文件之间的依赖关系和构建过程。

通过执行make命令,系统会根据Makefile中的规则来判断需要重新编译哪些文件,并自动执行编译、链接等操作。

make函数的基本用法如下:1. 创建Makefile文件:在项目目录下创建名为Makefile的文件,并使用文本编辑器打开。

2. 编写规则和指令:在Makefile中编写一系列规则和指令,用于描述源文件之间的依赖关系和构建过程。

每个规则由一个目标(target)、依赖(dependencies)和指令(commands)组成。

3. 执行make命令:在命令行终端中执行make命令,系统会读取Makefile文件,并根据规则和指令执行相应的操作。

二、Makefile文件的基本结构Makefile文件由一系列规则和指令组成,每个规则描述了一个或多个源文件的依赖关系和构建过程。

一个基本的Makefile文件包含以下几个部分:1. 声明变量:可以使用变量来定义一些常用的路径、编译选项等信息,使Makefile更加灵活和可维护。

2. 定义规则:通过规则来描述源文件之间的依赖关系和构建过程。

每个规则由一个目标(target)、依赖(dependencies)和指令(commands)组成。

3. 定义伪目标:伪目标是一种特殊的目标,它不表示真实的文件,而是用于执行一些特定的操作,比如清理临时文件、生成文档等。

4. 定义默认目标:默认目标是在执行make命令时,如果没有指定目标,则系统会执行的第一个目标。

Makefile编写规则(三)条件判断和伪目标

Makefile编写规则(三)条件判断和伪目标

Makefile编写规则(三)条件判断和伪⽬标Makefile编写规则(三)条件判断和伪⽬标Makefile条件判断使⽤ Makefile 编译⽂件时,可能会遇到需要分条件执⾏的情况,⽐如在⼀个⼯程⽂件中,可编译的源⽂件很多,但是它们的类型是不相同的,所以编译⽂件使⽤的编译器也是不同的。

⼿动编译去操作⽂件显然是不可⾏的(每个⽂件编译时需要注意的事项很多),所以 make 为我们提供了条件判断来解决这样的问题。

条件语句可以根据⼀个变量的值来控制 make 执⾏或者时忽略 Makefile 的特定部分,条件语句可以是两个不同的变量或者是常量和变量之间的⽐较。

注意:条件语句只能⽤于控制 make 实际执⾏的 Makefile ⽂件部分,不能控制规则的 shell 命令执⾏的过程。

下⾯是条件判断中使⽤到的⼀些关键字:关键字功能ifeq判断参数是否不相等,相等为 true,不相等为 false。

ifneq判断参数是否不相等,不相等为 true,相等为 false。

ifdef判断是否有值,有值为 true,没有值为 false。

ifndef判断是否有值,没有值为 true,有值为 false1)ideq和ifneq条件判断的使⽤⽅式如下:ifeq (ARG1, ARG2)ifeq 'ARG1' 'ARG2'ifeq "ARG1" "ARG2"ifeq "ARG1" 'ARG2'ifeq 'ARG1' "ARG2"实例:libs_for_gcc= -lgnunormal_libs=foo:$(objects)ifeq($(CC),gcc)$(CC) -o foo $(objects) $(libs_for_gcc)else$(CC) -o foo $(objects) $(noemal_libs)endif条件语句中使⽤到三个关键字“ifeq”、“else”、“endif”。

Makefile使用总结

Makefile使用总结

Makefile使⽤总结1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.本篇博客是基于⽽整理的, 有些删减, 追加了⼀些⽰例.⾮常感谢 gunguymadman_cu 提供如此详尽的Makefile介绍, 这正是我⼀直寻找的Makefile中⽂⽂档.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量VPATH就是完成这个功能的.指定了VPATH之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到VPATH指定的路径中再去查找.. VPATH使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o2.2.2 变量替换# Makefile内容SRCS := programA.c programB.c programC.cOBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.cOBJS: programA.o programB.o programC.o2.2.3 变量追加值 +=# Makefile内容SRCS := programA.c programB.c programC.cSRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.c programD.c2.2.4 变量覆盖 override作⽤是使 Makefile中定义的变量能够覆盖 make 命令参数中指定的变量语法:override <variable> = <value>override <variable> := <value>override <variable> += <value>下⾯通过⼀个例⼦体会 override 的作⽤:# Makefile内容 (没有⽤override)SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: nothing################################################## Makefile内容 (⽤override)override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: programA.c programB.c programC.c2.2.5 ⽬标变量作⽤是使变量的作⽤域仅限于这个⽬标(target), ⽽不像之前例⼦中定义的变量, 对整个Makefile都有效.语法:<target ...> :: <variable-assignment><target ...> :: override <variable-assignment> (override作⽤参见变量覆盖的介绍)⽰例:# Makefile 内容SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.ctarget1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中执⾏make$ make target1SRCS: programA.c programB.c programC.cSRCS: programD.c$ make target2 <-- target2中显⽰不了 $(TARGET1-SRCS)SRCS: programA.c programB.c programC.cSRCS:2.3 Makefile 命令前缀Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不⽤前缀.3种格式的shell命令区别如下:不⽤前缀 :: 输出执⾏的命令以及命令执⾏的结果, 出错的话停⽌执⾏前缀 @ :: 只输出命令执⾏的结果, 出错的话停⽌执⾏前缀 - :: 命令执⾏有错的话, 忽略错误, 继续执⾏⽰例:# Makefile 内容 (不⽤前缀)all:echo"没有前缀"cat this_file_not_existecho"错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 @)all:@echo "没有前缀"@cat this_file_not_exist@echo "错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ make没有前缀 <-- 只有命令执⾏的结果, 不显⽰命令本⾝cat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 -)all:-echo"没有前缀"-cat this_file_not_exist-echo"错误之后的命令" <-- 这条命令会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: [all] Error 1 (ignored)echo"错误之后的命令" <-- 出错之后的命令也会显⽰错误之后的命令 <-- 出错之后的命令也会执⾏2.4 伪⽬标伪⽬标并不是⼀个"⽬标(target)", 不像真正的⽬标那样会⽣成⼀个⽬标⽂件.典型的伪⽬标是 Makefile 中⽤来清理编译过程中中间⽂件的 clean 伪⽬标, ⼀般格式如下: .PHONY: clean <-- 这句没有也⾏, 但是最好加上clean:-rm -f *.o2.5 引⽤其他的 Makefile语法: include <filename> (filename 可以包含通配符和路径)⽰例:# Makefile 内容all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 20K-rw-r--r-- 1 wangyubin wangyubin 125 Sep 2316:13 Makefile-rw-r--r-- 1 wangyubin wangyubin 11K Sep 2316:15 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2316:11 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile'主 Makefile end2.6 查看C⽂件的依赖关系写 Makefile 的时候, 需要确定每个⽬标的依赖关系.GNU提供⼀个机制可以查看C代码⽂件依赖那些⽂件, 这样我们在写 Makefile ⽬标的时候就不⽤打开C源码来看其依赖那些⽂件了.⽐如, 下⾯命令显⽰内核源码中 virt/kvm/kvm_main.c 中的依赖关系$ cd virt/kvm/$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2.7 make 退出码Makefile的退出码有以下3种:0 :: 表⽰成功执⾏1 :: 表⽰make命令出现了错误2 :: 使⽤了 "-q" 选项, 并且make使得⼀些⽬标不需要更新2.8 指定 Makefile,指定特定⽬标默认执⾏ make 命令时, GNU make在当前⽬录下依次搜索下⾯3个⽂件 "GNUmakefile", "makefile", "Makefile",找到对应⽂件之后, 就开始执⾏此⽂件中的第⼀个⽬标(target). 如果找不到这3个⽂件就报错.⾮默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的⽬标.⽰例:# Makefile⽂件名改为 MyMake, 内容target1:@echo "target [1] begin"@echo "target [1] end"target2:@echo "target [2] begin"@echo "target [2] end"# bash 中执⾏make$ lsMakefile$ mv Makefile MyMake$ lsMyMake$ make <-- 找不到默认的 Makefilemake: *** No targets specified and no makefile found. Stop.$ make -f MyMake <-- 指定特定的Makefiletarget [1] begintarget [1] end$ make -f MyMake target2 <-- 指定特定的⽬标(target)target [2] begintarget [2] end2.9 make 参数介绍make 的参数有很多, 可以通过 make -h 去查看, 下⾯只介绍⼏个我认为⽐较有⽤的.参数含义--debug[=<options>]输出make的调试信息, options 可以是 a, b, v-j --jobs同时运⾏的命令的个数, 也就是多线程执⾏ Makefile-r --no-builtin-rules禁⽌使⽤任何隐含规则-R --no-builtin-variabes禁⽌使⽤任何作⽤于变量上的隐含规则-B --always-make假设所有⽬标都有更新, 即强制重编译2.10 Makefile 隐含规则这⾥只列⼀个和编译C相关的.编译C时,<n>.o 的⽬标会⾃动推导为 <n>.c# Makefile 中main : main.ogcc -o main main.o#会⾃动变为:main : main.ogcc -o main main.omain.o: main.c <-- main.o 这个⽬标是隐含⽣成的gcc -c main.c2.11 隐含规则中的命令变量和命令参数变量2.11.1 命令变量, 书写Makefile可以直接写 shell时⽤这些变量.下⾯只列出⼀些C相关的变量名含义RM rm -fAR arCC ccCXX g++⽰例:# Makefile 内容all:@echo $(RM)@echo $(AR)@echo $(CC)@echo $(CXX)# bash 中执⾏make, 显⽰各个变量的值$ makerm -farccg++2.11.2 命令参数变量变量名含义ARFLAGS AR命令的参数CFLAGS C语⾔编译器的参数CXXFLAGS C++语⾔编译器的参数⽰例: 下⾯以 CFLAGS 为例演⽰# test.c 内容#include <stdio.h>int main(int argc, char *argv[]){printf ("Hello Makefile\n");return 0;}# Makefile 内容test: test.o$(CC) -o test test.o# bash 中⽤make来测试$ lltotal 24K-rw-r--r-- 1 wangyubin wangyubin 69 Sep 2317:31 Makefile-rw-r--r-- 1 wangyubin wangyubin 14K Sep 2319:51 <-- 请忽略这个⽂件-rw-r--r-- 1 wangyubin wangyubin 392 Sep 2317:31 test.c$ makecc -c -o test.o test.ccc -o test test.o <-- 这个是⾃动推导的$ rm -f test test.o$ make CFLAGS=-Wall <-- 命令中加的编译器参数⾃动追加⼊下⾯的编译中了cc -Wall -c -o test.o test.ccc -o test test.o2.12 ⾃动变量Makefile 中很多时候通过⾃动变量来简化书写, 各个⾃动变量的含义如下:⾃动变量含义$@⽬标集合$%当⽬标是函数库⽂件时, 表⽰其中的⽬标⽂件名$<第⼀个依赖⽬标. 如果依赖⽬标是多个, 逐个表⽰依赖⽬标$?⽐⽬标新的依赖⽬标的集合$^所有依赖⽬标的集合, 会去除重复的依赖⽬标$+所有依赖⽬标的集合, 不会去除重复的依赖⽬标$*这个是GNU make特有的, 其它的make不⼀定⽀持3. Makefile ⾼级语法3.1 嵌套Makefile在 Makefile 初级语法中已经提到过引⽤其它 Makefile的⽅法. 这⾥有另⼀种写法, 并且可以向引⽤的其它 Makefile 传递参数.⽰例: (不传递参数, 只是调⽤⼦⽂件夹 other 中的Makefile)# Makefile 内容all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 28K-rw-r--r-- 1 wangyubin wangyubin 104 Sep 2320:43 Makefile-rw-r--r-- 1 wangyubin wangyubin 17K Sep 2320:44 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2320:42 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end⽰例: (⽤export传递参数)# Makefile 内容export VALUE1 := export.c <-- ⽤了 export, 此变量能够传递到 ./other/Makefile 中VALUE2 := no-export.c <-- 此变量不能传递到 ./other/Makefile 中all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "VALUE1: " $(VALUE1)@echo "VALUE2: " $(VALUE2)@echo "other makefile end"# bash中执⾏make$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginVALUE1: export.c <-- VALUE1 传递成功VALUE2: <-- VALUE2 传递失败other makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end*补充* export 语法格式如下:export variable = valueexport variable := valueexport variable += value3.2 定义命令包命令包有点像是个函数, 将连续的相同的命令合成⼀条, 减少 Makefile 中的代码量, 便于以后维护.语法:define <command-name>command...endef⽰例:# Makefile 内容define run-hello-makefile@echo -n "Hello"@echo " Makefile!"@echo "这⾥可以执⾏多条 Shell 命令!"endefall:$(run-hello-makefile)# bash 中运⾏make$ makeHello Makefile!这⾥可以执⾏多条 Shell 命令!3.3 条件判断条件判断的关键字主要有 ifeq ifneq ifdef ifndef语法:<conditional-directive><text-if-true>endif# 或者<conditional-directive><text-if-true>else<text-if-false>endif⽰例: ifeq的例⼦, ifneq和ifeq的使⽤⽅法类似, 就是取反# Makefile 内容all:ifeq ("aa", "bb")@echo "equal"else@echo "not equal"endif# bash 中执⾏make$ makenot equal⽰例: ifdef的例⼦, ifndef和ifdef的使⽤⽅法类似, 就是取反# Makefile 内容SRCS := program.call:ifdef SRCS@echo $(SRCS)else@echo "no SRCS"# bash 中执⾏make$ makeprogram.c3.4 Makefile 中的函数Makefile 中⾃带了⼀些函数, 利⽤这些函数可以简化 Makefile 的编写.函数调⽤语法如下:$(<function> <arguments>)# 或者${<function> <arguments>}<function> 是函数名<arguments> 是函数参数3.4.1 字符串函数字符串替换函数: $(subst <from>,<to>,<text>)功能: 把字符串<text> 中的 <from> 替换为 <to>返回: 替换过的字符串# Makefile 内容all:@echo $(subst t,e,maktfilt) <-- 将t替换为e# bash 中执⾏make$ makemakefile模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)功能: 查找<text>中的单词(单词以"空格", "tab", "换⾏"来分割) 是否符合 <pattern>, 符合的话, ⽤ <replacement> 替代.返回: 替换过的字符串# Makefile 内容all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执⾏make$ makeprogramA.o programB.o去空格函数: $(strip <string>)功能: 去掉 <string> 字符串中开头和结尾的空字符返回: 被去掉空格的字符串值# Makefile 内容VAL := " aa bb cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执⾏make去除空格前: aa bb cc去除空格后: aa bb cc查找字符串函数: $(findstring <find>,<in>)功能: 在字符串 <in> 中查找 <find> 字符串返回: 如果找到, 返回 <find> 字符串, 否则返回空字符串# Makefile 内容VAL := " aa bb cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执⾏make$ makeaa过滤函数: $(filter <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式 <pattern> 的单词, 可以有多个模式返回: 符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.o program.a反过滤函数: $(filter-out <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式 <pattern> 的单词, 可以有多个模式返回: 不符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.c排序函数: $(sort <list>)功能: 给字符串 <list> 中的单词排序 (升序)返回: 排序后的字符串# Makefile 内容all:@echo $(sort bac abc acb cab)# bash 中执⾏make$ makeabc acb bac cab取单词函数: $(word <n>,<text>)功能: 取字符串 <text> 中的第<n>个单词 (n从1开始)返回: <text> 中的第<n>个单词, 如果<n> ⽐ <text> 中单词个数要⼤, 则返回空字符串# Makefile 内容all:@echo $(word 1,aa bb cc dd)@echo $(word 5,aa bb cc dd)@echo $(word 4,aa bb cc dd)# bash 中执⾏make$ makeaadd取单词串函数: $(wordlist <s>,<e>,<text>)功能: 从字符串<text>中取从<s>开始到<e>的单词串. <s>和<e>是⼀个数字.返回: 从<s>到<e>的字符串# Makefile 内容all:@echo $(wordlist 1,3,aa bb cc dd)@echo $(word 5,6,aa bb cc dd)@echo $(word 2,5,aa bb cc dd)# bash 中执⾏make$ makeaa bb ccbb单词个数统计函数: $(words <text>)功能: 统计字符串 <text> 中单词的个数返回: 单词个数# Makefile 内容all:@echo $(words aa bb cc dd)@echo $(words aabbccdd)@echo $(words )# bash 中执⾏make$ make41⾸单词函数: $(firstword <text>)功能: 取字符串 <text> 中的第⼀个单词返回: 字符串 <text> 中的第⼀个单词# Makefile 内容all:@echo $(firstword aa bb cc dd)@echo $(firstword aabbccdd)@echo $(firstword )# bash 中执⾏make$ makeaaaabbccdd3.4.2 ⽂件名函数取⽬录函数: $(dir <names...>)功能: 从⽂件名序列 <names> 中取出⽬录部分返回: ⽂件名序列 <names> 中的⽬录部分# Makefile 内容all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ make/home/ ./ ../ ./取⽂件函数: $(notdir <names...>)功能: 从⽂件名序列 <names> 中取出⾮⽬录部分返回: ⽂件名序列 <names> 中的⾮⽬录部分# Makefile 内容all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ makea.c bb.cc.cd.c取后缀函数: $(suffix <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的后缀返回: ⽂件名序列 <names> 中各个⽂件名的后缀, 没有后缀则返回空字符串# Makefile 内容all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执⾏make$ make.c .o .a取前缀函数: $(basename <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的前缀返回: ⽂件名序列 <names> 中各个⽂件名的前缀, 没有前缀则返回空字符串# Makefile 内容all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执⾏make$ make/home/a ./b ../c /home/加后缀函数: $(addsuffix <suffix>,<names...>)功能: 把后缀 <suffix> 加到 <names> 中的每个单词后⾯返回: 加过后缀的⽂件名序列# Makefile 内容all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执⾏make$ make/home/a.c b.c ./c.o.c ../d.c.c加前缀函数: $(addprefix <prefix>,<names...>)功能: 把前缀 <prefix> 加到 <names> 中的每个单词前⾯返回: 加过前缀的⽂件名序列# Makefile 内容all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执⾏make$ maketest_/home/a.c test_b.c test_./d.c连接函数: $(join <list1>,<list2>)功能: <list2> 中对应的单词加到 <list1> 后⾯返回: 连接后的字符串# Makefile 内容all:@echo $(join a b c d,1234)@echo $(join a b c d,12345)@echo $(join a b c d e,1234)# bash 中执⾏make$ makea1 b2 c3 d4a1 b2 c3 d4 5a1 b2 c3 d4 e3.4.3 foreach语法:$(foreach <var>,<list>,<text>)⽰例:# Makefile 内容targets := a b c dobjects := $(foreach i,$(targets),$(i).o)all:@echo $(targets)@echo $(objects)# bash 中执⾏make$ makea b c da.ob.oc.od.o3.4.4 if这⾥的if是个函数, 和前⾯的条件判断不⼀样, 前⾯的条件判断属于Makefile的关键字语法:$(if <condition>,<then-part>)$(if <condition>,<then-part>,<else-part>)⽰例:# Makefile 内容val := aobjects := $(if $(val),$(val).o,nothing)no-objects := $(if $(no-val),$(val).o,nothing)all:@echo $(objects)@echo $(no-objects)# bash 中执⾏make$ makea.onothing3.4.5 call - 创建新的参数化函数语法:$(call <expression>,<parm1>,<parm2>,<parm3>...)⽰例:# Makefile 内容log = "====debug====" $(1) "====end===="all:@echo $(call log,"正在 Make")# bash 中执⾏make$ make====debug==== 正在 Make ====end====3.4.6 origin - 判断变量的来源语法:$(origin <variable>)返回值有如下类型:类型含义undefined<variable> 没有定义过default<variable> 是个默认的定义, ⽐如 CC 变量environment<variable> 是个环境变量, 并且 make时没有使⽤ -e 参数file<variable> 定义在Makefile中command line<variable> 定义在命令⾏中override<variable> 被 override 重新定义过automatic<variable> 是⾃动化变量⽰例:# Makefile 内容val-in-file := test-fileoverride val-override := test-overrideall:@echo $(origin not-define) # not-define 没有定义@echo $(origin CC) # CC 是Makefile默认定义的变量@echo $(origin PATH) # PATH 是 bash 环境变量@echo $(origin val-in-file) # 此Makefile中定义的变量@echo $(origin val-in-cmd) # 这个变量会加在make的参数中@echo $(origin val-override) # 此Makefile中定义的override变量@echo $(origin @) # ⾃动变量, 具体前⾯的介绍# bash 中执⾏make$ make val-in-cmd=val-cmdundefineddefaultenvironmentfilecommand lineoverrideautomatic3.4.7 shell语法:$(shell <shell command>)它的作⽤就是执⾏⼀个shell命令, 并将shell命令的结果作为函数的返回.作⽤和 `<shell command>` ⼀样, ` 是反引号3.4.8 make 控制函数产⽣⼀个致命错误: $(error <text ...>)功能: 输出错误信息, 停⽌Makefile的运⾏# Makefile 内容all:$(error there is an error!)@echo "这⾥不会执⾏!"# bash 中执⾏make$ makeMakefile:2: *** there is an error!. Stop.输出警告: $(warning <text ...>)功能: 输出警告信息, Makefile继续运⾏# Makefile 内容all:$(warning there is an warning!)@echo "这⾥会执⾏!"# bash 中执⾏make$ makeMakefile:2: there is an warning!这⾥会执⾏!3.5 Makefile中⼀些GNU约定俗成的伪⽬标如果有过在Linux上, 从源码安装软件的经历的话, 就会对 make clean, make install ⽐较熟悉.像 clean, install 这些伪⽬标, ⼴为⼈知, 不⽤解释就⼤家知道是什么意思了.下⾯列举⼀些常⽤的伪⽬标, 如果在⾃⼰项⽬的Makefile合理使⽤这些伪⽬标的话, 可以让我们⾃⼰的Makefile看起来更专业, 呵呵 :)伪⽬标含义all所有⽬标的⽬标,其功能⼀般是编译所有的⽬标clean删除所有被make创建的⽂件install安装已编译好的程序,其实就是把⽬标可执⾏⽂件拷贝到指定的⽬录中去print列出改变过的源⽂件tar把源程序打包备份. 也就是⼀个tar⽂件dist创建⼀个压缩⽂件, ⼀般是把tar⽂件压成Z⽂件. 或是gz⽂件TAGS更新所有的⽬标, 以备完整地重编译使⽤check 或 test⼀般⽤来测试makefile的流程。

make用法

make用法

make用法make是一个非常强大的工具,用于构建和管理软件项目。

它以命令行方式工作,可以自动地根据源代码和Makefile中的规则来编译、链接和打包代码。

在这篇文章中,我们将讨论make的用法,包括使用规则、变量和函数,以及构建多个目标、生成库和调试makefile。

一、makefile和规则Makefile是用于描述如何构建目标(通常是二进制文件或库文件)以及如何管理依赖关系的文本文件。

Makefile中的每个规则都指定了一个目标、依赖关系以及如何构建目标。

规则的格式如下:target: dependenciescommands其中,target是要构建的目标文件(可以是中间目标或最终目标),dependencies是构建目标所需的源文件或其他目标文件,commands是构建目标的命令。

下面是一个简单的Makefile示例:hello: main.o greeting.ogcc -o hello main.o greeting.omain.o: main.c greeting.hgcc -c main.cgreeting.o: greeting.c greeting.hgcc -c greeting.c这个Makefile包含了三个规则,分别用于构建hello可执行文件、main.o目标文件和greeting.o目标文件。

其中,hello的依赖是main.o和greeting.o,main.o的依赖是main.c和greeting.h,greeting.o的依赖是greeting.c和greeting.h。

如果执行make命令,则make将根据上述规则构建hello可执行文件,首先编译main.c和greeting.c生成main.o和greeting.o,然后链接这两个目标生成hello。

如果运行make clean,则make将删除所有生成的目标文件和可执行文件,该规则的格式如下:clean:rm -f hello main.o greeting.o二、变量和函数在Makefile中,可以使用变量和函数来简化和重复使用相同的命令和选项。

makefile的基本用法以及yolov3的makefile解析

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 文件,可以告诉计算机如何编译源代码,生成可执行文件。

海思makefile结构解析主要包括以下几个部分:1. 定义变量:在makefile中定义变量是非常重要的,可以方便地管理项目的路径、编译参数等信息。

海思makefile中通常会定义一些常用的变量,比如CC表示编译器的路径,CXX表示C++编译器的路径,CFLAGS表示编译参数等。

通过定义这些变量,可以在整个makefile中直接引用,减少了代码的冗余,提高了代码的可维护性。

2. 设置编译规则:在makefile中,通常会定义一些编译规则,告诉make工具如何编译源文件和生成可执行文件。

海思makefile中的编译规则通常使用模式匹配的方式,比如"%.c:%.o"表示将所有的.c文件编译为.o文件,而"%.o:%.c"则表示将所有的.o文件根据对应的.c文件进行重新编译。

通过这些编译规则,make工具可以根据需要自动化地完成整个项目的编译过程。

3. 定义目标:在makefile中通常会定义一些目标,这些目标可以是编译生成可执行文件的命令,也可以是清理生成的临时文件的命令。

海思makefile中的目标通常包括all、clean、install等,通过定义这些目标,可以方便地管理整个项目的编译和部署过程。

4. 调用外部工具:在海思makefile中,通常会调用一些外部工具来完成一些特定的任务,比如编译器、链接器、打包工具等。

Makefile目标汇总和变量的高级用法

Makefile目标汇总和变量的高级用法

Makefile⽬标汇总和变量的⾼级⽤法Makefile⽬标汇总和变量的⾼级⽤法规则中的⽬标形式是多种多样的,它可以是⼀个或多个的⽂件、可以是⼀个伪⽬标,这是我们之前讲到过的,也是经常使⽤的。

其实规则⽬标还可以是其他的类型,下⾯是对这些类型的详细的说明。

强制⽬标如果⼀个⽬标中没有命令或者是依赖,并且它的⽬标不是⼀个存在的⽂件名,在执⾏此规则时,⽬标总会被认为是最新的。

就是说:这个规则⼀旦被执⾏,make 就认为它的⽬标已经被更新过。

这样的⽬标在作为⼀个规则的依赖时,因为依赖总被认为更新过,因此作为依赖在的规则中定义的命令总会被执⾏。

看⼀个例⼦:clean:FORCErm $(OBJECTS)FORCE:这个例⼦中,⽬标 "FORCE" 符合上边的条件。

它作为⽬标 "clean" 的依赖,在执⾏ make 的时候,总被认为更新过。

因此 "clean" 所在的规则⽽在被执⾏其所定义的那个命令总会被执⾏。

这样的⼀个⽬标通常我们将其命名为 "FORCE"。

例⼦中使⽤ "FORCE" ⽬标的效果和将 "clean" 声明为伪⽬标的效果相同。

空⽬标⽂件空⽬标⽂件是伪⽬标的⼀个变种,此⽬标所在的规则执⾏的⽬的和伪⽬标相同——通过 make 命令⾏指定将其作为终极⽬标来执⾏此规则所定义的命令。

和伪⽬标不同的是:这个⽬标可以是⼀个存在的⽂件,但⽂件的具体内容我们并不关⼼,通常此⽂件是⼀个空⽂件。

空⽬标⽂件只是⽤来记录上⼀次执⾏的此规则的命令的时间。

在这样的规则中,命令部分都会使⽤ "touch" 在完成所有的命令之后来更新⽬标⽂件的时间戳,记录此规则命令的最后执⾏时间。

make 时通过命令⾏将此⽬标作为终极⽬标,当前⽬标下如果不存在这个⽂件,"touch"会在第⼀次执⾏时创建⼀个的⽂件。

makefile 结束语句

makefile 结束语句

makefile 结束语句
Makefile中的结束语句通常是以“.PHONY”来定义伪目标,以
及一个名为“clean”的目标来清理生成的文件。

在Makefile中,“.PHONY”用于声明一个伪目标,它告诉make工具,这个目标不是
一个真正的文件名,而是一个操作的名称。

在这种情况下,我们可
以使用“.PHONY”来定义一些特殊的目标,比如“clean”或者“all”。

下面是一个示例:
.PHONY: clean.
clean:
rm -f .o program_name.
在这个示例中,我们使用“.PHONY”来声明“clean”是一个伪
目标,然后在下面的行中定义了清理操作,即删除所有生成的“.o”文件和可执行文件“program_name”。

另外,有些人也会在Makefile的最后加上一个空的规则,以确
保Makefile的完整性。

这样做可以避免一些潜在的问题,比如最后
一行没有换行符等情况。

总的来说,Makefile的结束语句通常是以“.PHONY”来定义伪目标,并在其中包含清理操作或者空的规则,以确保Makefile的完整性和正确性。

makefile中dummy的用法 -回复

makefile中dummy的用法 -回复

makefile中dummy的用法-回复在makefile中,dummy(虚拟)的用法是指一个伪目标,它不代表实际的文件,而是在执行make命令时执行一系列指定的命令。

为了更好地理解dummy的用法,让我们逐步来回答以下问题:一、dummy目标的作用是什么?dummy目标在makefile中是一个特殊的目标,用于执行一系列需要的操作,例如编译代码、生成目标文件、运行测试等。

虽然它本身并不代表任何实际的文件,但它可以触发其他目标的构建和执行。

dummy目标的存在可以方便地组织和管理代码构建过程。

二、如何定义dummy目标?在makefile中,dummy目标的定义格式为:.PHONY: target_name。

其中,target_name是自定义的目标名称,可以根据实际需求进行命名。

三、为什么要使用.PHONY?为了告诉make工具,target_name是一个虚拟的目标,而不是代表一个真实的文件。

这是因为make工具在执行时会根据文件的时间戳来判断是否需要重新构建目标文件,如果目标是一个虚拟的目标,则无法判断其时间戳,因此需要使用.PHONY显式地声明。

四、dummy目标如何使用?1. 定义dummy目标:.PHONY: target_name2. 指定dummy目标的依赖关系:target_name: dependency1 dependency2 ...command1command2在上述示例中,.PHONY指示target_name是一个虚拟目标。

接着,指定了target_name目标的依赖关系,即所需的其他目标或文件。

紧接着的command1和command2是用于执行的命令。

五、dummy目标的实际应用场景是什么?1. 构建和清理:dummy目标经常用于构建和清理代码。

例如,可以定义一个dummy目标"build"用于编译代码文件,另一个dummy目标"clean"用于清理生成的目标文件。

makefile 依赖项 判断

makefile 依赖项 判断

makefile 依赖项判断
Makefile 中的依赖项判断是一个关键的过程,它决定了哪些目标文件需要被重新构建(即重新编译或链接)。

这个过程基于依赖关系和时间戳的比较。

以下是Makefile 依赖项判断的基本步骤:
1.规则与目标:Makefile 中的规则定义了如何从一个或多个依赖项构建一个目
标。

规则通常包括目标文件、依赖文件和一个命令,用于从依赖项构建目标。

2.时间戳检查:当Makefile 被执行时,它会检查目标文件的时间戳与依赖项的
时间戳。

如果任何一个依赖项的时间戳晚于目标文件的时间戳,那么目标文件就被认为是“过期”的,需要重新构建。

3.隐式和显式依赖:依赖可以是显式的(在规则中明确指出)或隐式的(通过其
他规则推断)。

Makefile 工具(如make)会尝试自动推断隐式依赖,但这并不总是可靠的。

4.命令执行:如果目标文件过期,那么相应的命令将被执行,以重新构建目标。

这通常包括编译源代码、链接库等。

5.伪目标:有时,你可能想要执行一个不对应实际文件的命令。

这种情况下,你
可以使用.PHONY目标来声明一个伪目标。

伪目标总是被认为是过期的,因此相应的命令总是会被执行。

6.循环依赖:如果规则之间存在循环依赖,即A 依赖于B,B 依赖于C,而C
又依赖于A,这将导致问题。

Makefile 应该避免这种循环依赖。

总的来说,Makefile 的依赖项判断是一个基于时间戳和规则的过程,用于确定哪些目标需要重新构建。

正确地设置和管理依赖项是确保项目能够正确、高效地构建的关键。

makefile 中的语法和bat语法

makefile 中的语法和bat语法

makefile 中的语法和bat语法makefile是一种用于自动化构建程序的工具,常用于编译、链接和打包项目。

它的语法相对复杂,以下是一些常用的语法元素:1. 定义变量:VAR_NAME = value2. 定义规则:target: dependenciesaction3. 规则目标可以是文件或伪目标(即不对应任何文件),例如: clean:rm -rf $(OBJ_DIR)/*4. 使用变量:$(VAR_NAME)5. 使用命令:@command -option arg6. 依赖关系:target: dependency1 dependency2action7. 通配符:*.c 代表所有以.c为扩展名的文件bat是Windows平台上的批处理脚本语言,用于批量执行一系列Windows命令。

以下是一些常用的bat语法元素:1. 命令:command arg1 arg22. 注释:REM comment3. 变量:set VAR_NAME=value4. 变量使用:%VAR_NAME%5. 读取用户输入:set /p VAR_NAME=Prompt6. 条件语句:if condition (command1) else (command2)7. 循环语句:for %%var in (set) do (command)8. 调用其他bat文件:call other_file.bat以上是makefile和bat语法的简要说明,更详细的语法规则和用法可以参考相关的文档或教程。

makefile pushd用法 -回复

makefile pushd用法 -回复

makefile pushd用法-回复Makefile和pushd的用法Makefile是一种用于构建软件项目的工具,它可以自动化编译、链接和安装过程。

它使用一种特殊的语法来描述工程的结构和依赖关系,从而使得代码的构建过程变得更加简单和高效。

而pushd是一个shell命令,可以在命令行中保存当前工作目录并进入一个新的目录,而不会丢失之前的路径。

它的功能类似于cd命令,但是通过使用pushd和popd命令可以方便地在不同的目录之间进行切换。

在本文中,我将详细介绍Makefile和pushd的用法,并演示如何结合使用它们来构建和管理一个软件项目。

第一部分:Makefile入门首先,我们需要了解Makefile的基本结构和语法。

一个简单的Makefile 文件通常包含以下几个部分:1. 变量定义:在Makefile中,我们可以定义一些变量来存储路径、编译器选项等信息。

例如,我们可以定义一个变量来存储编译器的路径:CC = gcc2. 目标规则:Makefile中的目标规则描述了构建一个或多个目标的过程。

每个目标规则由一个目标、依赖文件和构建命令组成。

例如,我们可以定义一个构建可执行文件的目标规则:main: main.o(CC) main.o -o mainmain.o: main.c(CC) -c main.c在上面的例子中,我们定义了一个名为main的目标规则,它依赖于main.o文件,并通过调用gcc编译器将main.o文件链接为一个可执行文件。

3. 伪目标:伪目标是一类特殊的目标,它们不对应实际的文件,而是用于定义一些特殊的操作。

例如,我们可以定义一个伪目标用于清除编译产生的文件:clean:rm -f main main.o在上面的例子中,我们定义了一个名为clean的伪目标,通过调用rm命令删除生成的main和main.o文件。

第二部分:Makefile中的pushd用法现在让我们来看看如何在Makefile中使用pushd命令。

Makefile中的目标

Makefile中的目标

Makefile中的⽬标Makefile中的⽬标⼀般⽬标⽬标就是我们需要的最终⽂件,也是make的最终输出 Makefile的运⾏机制是:先将⽬标当成⽂件,查看⽂件是否存在,如果存在且是最新,那么直接结束,如果⽂件不存在,那么根据依赖和命令⽣成⽬标。

伪⽬标伪⽬标也是⽬标伪⽬标是⼀种特殊的⽬标,有其特殊性伪⽬标的特殊性:伪⽬标不会当成⽂件来判断,只是⼀个标签伪⽬标同样可以有依赖,这样make伪⽬标时就是先make依赖,然后运⾏规则作⽤:伪⽬标每次都会更新格式:.PHONY : xxx例⼦:.PHONY : clean#只要有这个声明,不管是否有“clean”⽂件,要运⾏“clean”这个⽬标,只有“make clean”多⽬标Makefile 的规则中的⽬标可以不⽌⼀个,其⽀持多⽬标,有可能我们的多个⽬标同时依赖于⼀个⽂件,并且其⽣成的命令⼤体类似bigoutput littleoutput : text.ggenerate text.g -$(subst output,,$@) > $@#等价于bigoutput : text.ggenerate text.g -big > bigoutputlittleoutput : text.ggenerate text.g -little > littleoutput相同⽬标多条规则⽬标相同,称为相同⽬标Makefile的处理规则:如果多条规则中只有⼀条规则有命令,那么直接合并成⼀条规则,⽬标不变,依赖叠加;如果有多条规则有命令,那么后⾯的规则会覆盖前⾯的规则,且会爆告警Makefile中的⾃动头⽂件依赖就是利⽤⽬标相同时,规则合并的技术实现target1: dep1target1: dep2cmd2#合并后target1: dep1 dep2cmd2target1: dep1cmd1target1: dep2cmd2#合并后target1: dep2cmd2。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Makefile伪目标
本节我们讨论一个Makefile中的一个重要的特殊目标:伪目标。

伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签。

使用伪目标有两点原因:
1. 避免在我们的Makefile中定义的只执行命令的的目标(此目标的目的为了执行执行一系列命
令,而不需要创建这个目标)和工作目录下的实际文件出现名字冲突。

2. 提高执行make时的效率,特别是对于一个大型的工程来说,编译的效率也许你同样关心。


下就这两个问题我们进行分析讨论:
如果我们需要书写这样一个规则:规则所定义的命令不是去创建目标文件,而是使用make指定具体的目标来执一些特定的命令。

像下边那样:
1.clean:
2.rm *.o temp
规则中rm不是创建文件clean的命令,只是删除当前目录下的所有.o文件和temp文件。

在工作目录下不存在clean这个文件时,我们输入make clean后,rm *.o temp总会被执行。

这是我们的初衷。

但当前工作目录下存在文件clean时情况就不一样了,在我们输入make clean时。

规则没有依赖文件,所以目标被认为是最新的而不去执行规则作定义的命令,命令rm将不会被执行。

这并不是我们的初衷。

为了避免这个问题,我们可以将目标clean明确的声明为伪目标。

将一个目标声明为伪目标需要将它作为特殊目标.PHONY的依赖。

如下:
1..PHONY : clean
这样目标clean就是一个伪目标,无论当前目录下是否存在clean这个文件。

我们输入make clean 之后。

rm命令都会被执行。

而且,当一个目标被声明为伪目标后,make在执行此规则时不会试图去查找隐含规则来创建这个目标。

这样也提高了make的执行效率,同时我们也不用担心由于目标和文件名重名而使我们的期望失败。

在书写伪目标规则时,首先需要声明目标是一个伪目标,之后才是伪目标的规则定义。

目标clean书写格式应该如下:
1..PHONY: clean
2.clean:
3.rm *.o temp
伪目标的另外一使用场合在make的并行和递归执行过程中。

此情况下一般存在一个变量,其定义为所有需要make的子目录。

对多个目录进行make的实现方式可以在一个规则中可以使用shell的循环来完成。

如下:
1.SUBDIRS = foo bar baz
2.subdirs:
3.for dir in $(SUBDIRS);do \
4.$(MAKE)-C $$dir; \
5.done
但这种实现方法存在以下几个问题。

∙当子目录执行make出现错误时,make不会退出。

就是说,在对某一个目录执行make失败以后,会继续对其他的目录进行make。

在最终执行失败的情况下,我们很难根据错误的提示定位出具体是是那个目录下的Makefile出现错误。

这给问题定位造成了很大的困难。

为了避免这样的问题,我们可以在命令行部分加入错误的监测,在命令执行错误后make退出。

不幸的是,如果在执行make时使用了-k选项,此方式将失效。

∙另外一个问题就是使用这种shell的循环方式时,没有用到make对目录的并行处理功能,因为规则的命令是一条完整的shell命令,不能被并行的执行。

我们可以通过伪目标方式来克服以上实现方式所存在的两个问题。

1.SUBDIRS = foo bar baz
2..PHONY: subdirs $(SUBDIRS)
3.subdirs: $(SUBDIRS)
4.$(SUBDIRS):
5.$(MAKE)-C $@
6.foo: baz
上边的实现中使用了一个没有命令行的规则foo: baz,用来限制子目录的make顺序。

此规则
的含义时在处理foo目录之前,需要等待baz目录处理完成。

在书写一个并行执行make的Makefile时,目录的处理顺序是需要特别注意的。

一般情况下,一个伪目标不作为一个另外一个目标文件的依赖。

这是因为当一个目标文件的依赖包含伪目标时,每一次在执行这个规则时伪目标所定义的命令都会被执行(因为它是规则的依赖,重建规则目标文件时需要首先重建它的依赖)。

当伪目标没有作为任何目标(此目标是一个可被创建或者已存在的文件)的依赖时,我们只能通过make的命令行选项明确指定这个伪目标,来执行它所定义的命令。

例如我们的make clean。

Makefile中,伪目标可以有自己的依赖。

在一个目录下如果需要创建多个可执行程序,我们可
以将所有程序的重建规则在一个Makefile中描述。

因为Makefile中第一个目标是终极目标,约定的做法是使用一个称为all的伪目标来作为终极目标,它的依赖文件就是那些需要创建的程序。

下边就是一个例子:
1.#sample Makefile
2.all : prog1 prog2 prog3
3..PHONY : all
4.prog1 : prog1.o utils.o
-o prog1 prog1.o utils.o
6.prog2 : prog2.o
-o prog2 prog2.o
8.prog3 : prog3.o sort.o utils.o
-o prog3 prog3.o sort.o utils.o
执行make时,目标all被作为终极目标。

为了完成对它的更新,make会创建(不存在)或者重建(已存在)目标all的所有依赖文件(prog1、prog2和prog3)。

当需要单独更新某一个程序时,我们可以通过make的命令行选项来明确指定需要重建的程序。

(例如:make prog1)。

当一个伪目标作为另外一个伪目标依赖时,make将其作为另外一个伪目标的子例程来处理(可以这样理解:其作为另外一个伪目标的必须执行的部分,就行C语言中的函数调用一样)。

下边的例子就是这种用法:
1..PHONY: cleanall cleanobj cleandiff
2.cleanall : cleanobj cleandiff
3.rm program
4.cleanobj :
5.rm *.o
6.cleandiff :
7.rm *.diff
cleanobj和cleandiff这两个伪目标有点像子程序的意思(执行目标clearall时会触发它们所定义的命令被执行)。

我们可以输入make cleanall和make cleanobj和make cleandiff命令来达到清除不同种类文件的目的。

例子首先通过特殊目标.PHONY声明了多个伪目标,它们之间使用空各分割,之后才是各个伪目标的规则定义。

说明:
通常在清除文件的伪目标所定义的命令中rm使用选项–f(--force)来防止在缺少删除文件时出错并退出,使make clean过程失败。

也可以在rm之前加上-来防止rm错误退出,这种方式时make会提示错误信息但不会退出。

为了不看到这些讨厌的信息,需要使用上述的第一种方式。

另外make存在一个内嵌隐含变量RM,它被定义为:RM = rm –f。

因此在书写clean规则的命令行时可以使用变量$(RM)来代替rm,这样可以免出现一些不必要的麻烦!这是我们推荐的用法。

相关文档
最新文档