Makefile全解析

合集下载

make makefile 的参数

make makefile 的参数

make makefile 的参数make是一个常用的构建工具,用于自动化编译和构建软件项目。

makefile是make工具的配置文件,用于描述项目的构建规则和依赖关系。

本文将介绍makefile的参数,包括常用的参数及其用法。

一、常用参数及其用法1. -f 文件名:指定makefile的文件名,默认为"makefile"或"Makefile"。

通过该参数,可以使用其他名称的makefile文件。

2. -C 目录:指定make命令的工作目录。

在执行make命令时,会切换到指定的目录,并在该目录下查找makefile文件进行构建。

3. -n:显示执行make命令时的操作,但不实际执行。

通过该参数,可以预览make命令的执行过程,检查构建规则是否正确。

4. -p:显示make命令的内置变量和规则。

通过该参数,可以查看make命令的内部工作机制,了解makefile文件的编写规则和使用方法。

5. -B:强制重新构建目标文件。

通过该参数,可以忽略文件的时间戳,强制重新执行构建规则,生成新的目标文件。

6. -j 并发数:指定make命令的并发执行数。

通过该参数,可以提高构建速度,同时执行多个任务。

7. -s:静默模式,不显示执行的命令。

通过该参数,可以减少输出信息,使构建过程更加清晰。

二、makefile的构建规则makefile由一系列构建规则组成,每个规则定义了目标文件、依赖文件和构建命令。

make命令根据构建规则,自动判断需要更新的文件,并执行相应的构建命令。

构建规则的基本格式如下:目标文件: 依赖文件构建命令其中,目标文件是要生成的文件,依赖文件是目标文件依赖的文件,构建命令是生成目标文件的命令。

构建规则中的目标文件和依赖文件可以是文件名,也可以是变量。

通过使用变量,可以提高makefile的可维护性和灵活性。

构建命令可以是任意的Shell命令,包括编译、链接、拷贝等操作。

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中的⼏个常见的符号及其含义= 是最基本的赋值:= 是覆盖之前的值= 是如果没有被赋值过就赋予等号后⾯的值+= 是添加等号后⾯的值“=”和“:=”的区别:1、“=”make会将整个makefile展开后,再决定变量的值。

也就是说,变量的值将会是整个makefile中最后被指定的值。

看例⼦: x = fooy = $(x) barx = xyz在上例中,y的值将会是 xyz bar ,⽽不是 foo bar 。

2、“:=”“:=”表⽰变量的值决定于它在makefile中的位置,⽽不是整个makefile展开后的最终值。

x := fooy := $(x) barx := xyz在上例中,y的值将会是 foo bar ,⽽不是 xyz bar 了。

'@' 符号的使⽤通常makefile会将其执⾏的命令⾏在执⾏前输出到屏幕上。

如果将‘@’添加到命令⾏前,这个命令将不被make回显出来。

例如:@echo --compiling module----; // 屏幕输出 --compiling module----echo --compiling module----; // 没有@ 屏幕输出echo --compiling module----' - ' 符号的使⽤通常删除,创建⽂件如果碰到⽂件不存在或者已经创建,那么希望忽略掉这个错误,继续执⾏,就可以在命令前⾯添加 -, -rm dir;-mkdir aaadir;ref:https:///u012989012/article/details/80572043。

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程序。

makefile 中 .dep 用法 -回复

makefile 中 .dep 用法 -回复

makefile 中 .dep 用法-回复问题:makefile 中 .dep 用法一、什么是makefile?makefile 是一种用于自动化构建程序的工具,它告诉make 工具如何编译和链接程序的各个模块。

通过makefile,我们可以定义源代码的依赖关系,并且只重新编译发生改变的源代码文件,从而提高编译效率。

二、makefile 的作用makefile 的主要作用有以下几个方面:1. 定义源代码文件之间的依赖关系。

2. 定义编译和链接的规则。

3. 自动化构建程序,只重新编译发生改变的源代码文件。

4. 管理程序的版本控制,使得程序的构建过程可重复性和可扩展性更高。

三、makefile 的基本结构makefile 由一系列规则组成,每个规则由一个目标、依赖文件和命令组成。

其中,目标指的是要生成的文件,依赖文件指的是生成目标文件所依赖的其他文件,命令指的是执行生成目标文件的具体操作。

四、.dep 文件的作用.dep 文件是makefile 中一个重要的文件,它用于记录源代码文件之间的依赖关系。

在makefile 构建程序时,会根据 .dep 文件中的内容判断哪些源代码文件需要重新编译。

五、.dep 文件的生成过程1. 定义 .dep 依赖文件的生成规则。

常用的规则有以下两种:.dep: .cpp(CPP) (CPP_FLAGS) -MM < -MF @或.cpp.dep:(CPP) (CPP_FLAGS) -MM < -MF @2. 定义 .dep 文件的依赖规则。

sources := (wildcard *.cpp)deps := (patsubst .cpp,.dep,(sources))all: (deps)(deps): .dep: .cppinclude (deps)3. 执行makefile 生成 .dep 文件。

在命令行中执行`make` 命令,make 工具会根据 .dep 文件的规则和源代码文件的依赖关系生成 .dep 文件。

make makefile 的参数

make makefile 的参数

make makefile 的参数make命令是一款非常强大的工具,可以帮助我们自动化构建项目,特别是在大型项目中,make命令可以极大地提高开发效率。

makefile是make命令的配置文件,可以用来指定构建项目的规则和依赖关系,下面我们将介绍makefile的参数以及其用法。

1. -f-f参数可以用来指定makefile文件的名称,如果不指定,则默认使用当前目录下的makefile文件或Makefile文件。

例如,我们可以使用以下命令来指定makefile文件的名称:make -f mymakefile2. -C-C参数可以用来指定make命令的工作目录,即make命令将在指定目录下执行构建操作。

例如,我们可以使用以下命令来指定工作目录:make -C /path/to/project3. -n-n参数可以用来显示make命令将要执行的动作,但并不真正执行。

这个参数在调试makefile文件时非常有用,可以帮助我们检查makefile文件的正确性。

例如,我们可以使用以下命令来显示make 命令将要执行的动作:make -n4. -B-B参数可以用来强制执行make命令,即使目标文件已经是最新的了。

这个参数通常在我们需要重新构建项目时使用。

例如,我们可以使用以下命令来强制执行make命令:make -B5. -j-j参数可以用来指定make命令并行执行的任务数,可以加快构建速度。

这个参数通常在大型项目中使用,可以充分利用计算机的多核处理能力。

例如,我们可以使用以下命令来指定make命令并行执行的任务数:make -j46. --debug--debug参数可以用来打开make命令的调试模式,可以帮助我们更好地理解make命令的执行过程。

例如,我们可以使用以下命令来打开make命令的调试模式:make --debug7. --version--version参数可以用来显示make命令的版本信息。

makefile obj用法

makefile obj用法

文章标题:深入探讨Makefile中的Obj用法在软件开发中,Makefile是一个非常重要的工具,它帮助程序员管理项目的编译和信息过程。

而Makefile中的Obj用法则是Makefile中非常重要的一部分,它用来指定项目中的目标文件。

在本篇文章中,我们将深入探讨Makefile中的Obj用法,从简单到复杂,由浅入深,帮助读者更好地理解和运用Obj用法。

1. 什么是Makefile在开始深入探讨Makefile中的Obj用法之前,我们先来了解一下什么是Makefile。

Makefile是一种文件,其中包含了一系列规则和命令,用于指导编译器如何编译和信息项目中的源文件,最终生成可执行文件。

Makefile通过维护文件之间的依赖关系,可以使得在修改源文件后,只重新编译需要重新编译的文件,而不是整个项目。

这样可以提高编译的效率,特别是在大型项目中非常重要。

2. Obj用法的基础概念Obj用法是Makefile中用来指定目标文件的一个重要部分。

在Makefile中,通常通过指定目标文件来定义一个编译单元,Obj用法就是用来指定这些目标文件的。

在Makefile中,Obj用法通常是在规则中使用的,用来指定编译的目标文件是哪些。

我们可以这样定义一个规则:```main.o : main.cgcc -c main.c -o main.o```在这个例子中,main.o就是通过Obj用法指定的目标文件,它告诉Makefile需要生成名为main.o的目标文件,并且它是由main.c编译而来的。

3. Makefile中的Obj用法进阶除了简单地指定目标文件外,Obj用法还可以进一步扩展。

在实际开发中,一个目标文件可能由多个源文件编译而来,这时候就需要用到Obj用法的进阶用法了。

在Makefile中,我们可以使用通配符来指定一组目标文件,例如:```%.o : %.cgcc -c $< -o $@```这个规则中,%表示任意的文件名,$<表示依赖文件,$@表示目标文件。

MakeFile详解

MakeFile详解

引用其它的Makefile-实例



有这样几个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

在大多数时候,由于源文件太多,编译生成的中间目标文 件太多,而在链接时需要明显地指出中间目标文件名,这
对于编译很不方便,所以,通常要给中间目标文件打个包,
在Windows 下这种包叫“库文件”(Library File),也就 是 .lib 文件,在UNIX 下,是Archive File,也就是 .a 文件。
定义变量和引用变量
变量的定义和应用与Linux环境变量一样,变量名 要大写,变量一旦定义后,就可以通过将变量名 用圆括号括起来,并在前面加上“$”符号来进行 引用。 变量的主要作用: 1、保存文件名列表 2、保存可执行命令名,如编译器 3、保存编译器的参数 变量一般都在makefile的头部定义。按照惯例, 所有的makefile变量都应该是大写。
者,通常是你需要告诉编译器头文件的所在位置,只要所有的语法正
确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应 该对应于一个中间目标文件(O 文件或是OBJ 文件)。
孙钦东
程序的编译和链接

链接时,主要是链接函数和全局变量。链接器并不管函数
所在的源文件,只管函数的中间目标文件(Object File)。



clean: -rm -f $(EXEC) *.elf *.gdb *.o

简述Makefile文件的格式

简述Makefile文件的格式

简述Makefile文件的格式Makefile文件是一种常见的文本文件,用于描述一个项目中各个文件之间的依赖关系和编译规则。

Makefile文件通常由一系列规则组成,每个规则由一个目标、依赖关系和命令组成。

Makefile文件的格式如下:1. 目标(Target)目标是指需要生成的文件或者执行的操作。

在Makefile中,目标通常是一个可执行程序或者一个库文件。

目标的格式为:target: dependenciescommand其中,target表示目标名称,dependencies表示该目标所依赖的其他文件或者操作,command表示生成该目标所需要执行的命令。

2. 依赖关系(Dependencies)依赖关系指该目标所依赖的其他文件或者操作。

在Makefile中,可以通过在目标后面加上冒号(:)来定义该目标所依赖的其他文件或者操作。

多个依赖关系之间可以使用空格或者Tab键来进行分隔。

3. 命令(Command)命令是指生成该目标所需要执行的具体操作。

在Makefile中,可以通过在每个规则后面添加一行以Tab键开头的命令来定义具体操作。

4. 变量(Variables)变量是指用于存储各种编译参数和路径等信息的变量。

在Makefile中,可以通过使用$()符号来引用变量,并使用=符号来进行赋值操作。

例如:CFLAGS = -Wall -O2CC = gcctarget: dependencies$(CC) $(CFLAGS) -o target dependencies5. 注释(Comments)注释是指用于对Makefile中各个规则进行解释说明的文本。

在Makefile中,可以使用#符号来进行注释,#符号后面的内容将被忽略。

总之,Makefile文件是一个非常重要的工具,在项目开发过程中起到了至关重要的作用。

掌握Makefile文件的格式和编写方法,可以帮助我们更加高效地管理和组织项目代码,并提高项目开发效率。

makefile中的gcc -c -o语法

makefile中的gcc -c -o语法

文章标题:深度探讨makefile中的gcc -c -o语法在makefile中,gcc -c -o是一个非常重要的语法结构,用于编译源文件并生成目标文件。

在本文中,我将对这个语法进行深入探讨,帮助你更好地理解它的用途和功能,并运用到实际的项目中。

1. gcc -c -o的基本概念在makefile中,gcc -c -o用于将源文件编译成目标文件。

其中,-c表示编译但不信息,-o用于指定编译后生成的目标文件名。

这个语法结构在实际的项目中非常常见,尤其是在大型的软件开发过程中。

2. 深入理解gcc -c -o的作用通过gcc -c -o,我们可以将源文件编译成目标文件,然后再将多个目标文件信息起来,生成可执行文件。

这样的分步编译方式可以提高编译的效率,尤其是在一个项目中包含大量源文件的情况下。

另外,通过指定-o参数,我们可以自定义目标文件的生成规则和命名规范,让项目结构更加清晰和灵活。

3. 实际应用案例举一个实际的例子,比如我们有一个项目包含多个源文件,分别是main.c、function1.c和function2.c。

我们可以使用gcc -c -o将这些源文件分别编译成目标文件main.o、function1.o和function2.o,然后通过gcc将这些目标文件信息起来,生成可执行文件。

这样的分步编译方式可以提高项目的维护性和灵活性。

4. 对于gcc -c -o的个人观点和理解个人认为,gcc -c -o是一个非常实用的编译选项,尤其是在大型的软件开发项目中。

通过这个选项,我们可以更加灵活地管理项目的结构,提高编译效率,同时也让代码更加清晰和易于维护。

在实际的项目中,我经常使用这个选项来进行分步编译,以便更好地管理和组织代码。

5. 总结通过本文的深入探讨,相信你对makefile中的gcc -c -o语法有了更深入的理解。

这个语法不仅在软件开发中非常常见,而且也非常实用。

通过灵活运用这个选项,我们可以更好地管理和组织项目,提高代码的可维护性和开发效率。

Makefile经典教程(最掌握这部分足够---因为汇集全部精华)!!!!!!!!!!

Makefile经典教程(最掌握这部分足够---因为汇集全部精华)!!!!!!!!!!

Makefile经典教程0 Makefile概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。

这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。

特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

因为,makefile关系到了整个工程的编译规则。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。

可见,makefile都成为了一种在工程方面的编译方法。

现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。

当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。

必竟,这个make是应用最为广泛的,也是用得最多的。

而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。

在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。

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的流程。

makefile 命令行参数

makefile 命令行参数
2. -C选项
-C选项可以指定Makefile所在的路径。如果我们在当前路径下执行make命令,但是Makefile文件不在当前路径下,那么就需要使用-C选项来指定Makefile所在的路径。例如:
make -C /path/to/Makefile
3. -f选项
-f选项可以指定要使用的Makefile文件名。如果我们有多个Makefile文件,那么就可以使用-f选项来指定要使用哪个Makefile文件。例如:
makefile 命令行参数
Makefile是一种用来管理代码编译的工具,它可以自动化执行编译任务,帮助程序员更高效地管理代码。在Makefile中,可以定义一系列规则来指定如何编译代码。在使用Makefile时,我们可以通过命令行参数来控制编译过程的行为。本文将详细介绍makefile命令行参数的使用方法。项
-j选项可以指定并行编译时所使用的线程数。如果我们有多个CPU核心,并且要编译大型项目,那么就可以使用-j选项来加速编译过程。例如:
make -j4
5. --dry-run选项
--dry-run选项可以模拟执行make命令,并输出将要执行的命令列表,但是并不会真正地执行这些命令。这个功能非常实用,因为我们可以预先查看将要执行的命令,确保它们是正确的。例如:
这样做的好处是,我们可以在不修改Makefile的情况下,通过命令行参数来控制编译过程的行为。
四、总结
本文介绍了Makefile命令行参数的用法,包括make命令、-C选项、-f选项、-j选项、--dry-run选项和--print-data-base选项。同时,本文还介绍了一些Makefile常用技巧,包括使用变量来存储编译选项、使用通配符来自动生成目标文件列表和使用命令行参数来控制编译过程。希望本文能够对大家理解和学习Makefile有所帮助。

makefile 生成依赖关系

makefile 生成依赖关系

一、概述在软件开发过程中,源文件之间的依赖关系是非常重要的。

当一个文件发生变化时,其依赖文件可能也会受到影响,因此需要一个工具来管理这些依赖关系,确保在编译过程中能够正确地处理依赖关系。

makefile就是一个非常强大的工具,能够自动生成依赖关系,本文将详细介绍makefile生成依赖关系的方法。

二、什么是makefilemakefile是一个包含规则和命令的文本文件,用来描述软件项目的编译过程。

它告诉make工具,如何去利用源文件生成目标文件。

makefile通常包含了以下内容:1. 目标(target):表示要生成的文件,可以是可执行文件、中间文件或其他类型的文件。

2. 依赖(dependencies):表示目标文件所依赖的源文件或其他文件。

3. 命令mands):表示生成目标文件的具体操作,通常是编译、信息等。

三、makefile生成依赖关系的原理在编译过程中,一个源文件可能会依赖于其他源文件或头文件,当这些依赖关系发生变化时,我们需要重新编译相关的文件。

makefile 生成依赖关系的原理就是通过分析源文件中的#include语句,自动识别出文件之间的依赖关系,并生成相应的规则。

1. 使用gcc的-M选项gcc是一个非常流行的编译器,在编译过程中,它提供了-M选项来生成依赖关系。

例如:```make.o: .cgcc -c $< -o $ -MMD -MF $*.d```这里,-MMD选项表示生成依赖关系文件,-MF选项指定了依赖关系文件的名称。

通过这样的makefile规则,gcc能够自动生成每个源文件的依赖关系。

2. 使用自定义脚本除了使用gcc的-M选项外,我们也可以编写一个自定义的脚本来生成依赖关系。

这样能够更加灵活地控制依赖关系的生成过程。

五、makefile生成依赖关系的优势1. 自动化:makefile能够自动分析源文件之间的依赖关系,不需要手动维护依赖关系。

2. 灵活性:makefile生成依赖关系的方法非常灵活,可以根据实际需要选择不同的生成方式。

sv 中的makefile 写法

sv 中的makefile 写法

SV(SystemVerilog)是一种硬件描述语言,用于设计和验证数字电路。

在进行SV代码编写的过程中,makefile是一种非常有用的工具,可以帮助组织和管理SV项目中的代码文件。

本文将介绍SV中makefile的写法,希望能为SV开发者提供一些参考和帮助。

1. 为什么需要makefile在SV项目中,通常会涉及到多个源文件、库文件、测试文件等。

使用makefile可以帮助我们轻松地组织和管理这些文件,实现自动化编译、信息和运行测试的功能。

makefile还可以帮助我们避免重复编译文件,提高开发效率。

2. makefile的基本结构makefile由一系列规则组成,每个规则由一个目标、依赖列表和命令组成。

一个基本的makefile看起来像这样:```makefiletarget: dependenciesmand```其中,target表示规则的目标文件,dependencies表示该目标文件的依赖文件mand表示需要执行的命令。

3. 使用变量在makefile中,我们可以使用变量来定义一些常量,方便我们在后续的规则中使用。

例如:```makefileSV_SRC = file1.sv file2.sv file3.sv```这样,我们就可以在后续的规则中使用$(SV_SRC)来表示这些文件,而不需要重复地写出它们的文件名。

4. 基本规则在SV项目中,常见的makefile规则包括编译规则、信息规则和运行测试规则。

以下是一个简单的例子:```makefileall: $(SV_SRC)vlog $(SV_SRC)sim: allvsim top_module```在这个例子中,我们定义了两个规则,分别是all和sim。

all规则依赖于$(SV_SRC)中的文件,使用vlog命令对这些文件进行编译。

sim规则依赖于all规则,使用vsim命令来运行测试。

5. 使用通配符在makefile中,我们还可以使用通配符来表示一类文件。

Makefile

Makefile

定义
概述
Linux环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序 员,至少不能称得上是 Unix程序员。在 Linux(unix )环境下使用GNU的make工具能够比较容易的构建一个属 于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投 入一些时间去完成一个或者多个称之为Makefile文件的编写。
在 UNIX系统中,习惯使用 Makefile作为 makefile文件。如果要使用其他文件作为 makefile,则可利用 类似下面的 make命令选项指定 makefile文件:
make命令
$ make -f Makefile.debug
Makefile文件工程样例例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件 LS编译生成,这三个文件还分别包含自己的头文件a.h、b.h和c.h。通常情况下,C编译器将会输出三个目标文件 filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即 在filea.c和fileb.
所要完成的Makefile文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以 及如何编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来 可能是很复杂的事情,但是为工程编写Makefile的好处是能够使用一行命令来完成“自动化编译”,一旦提供一 个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的事就是在shell提示符下输入 make命令。整个工程完全自动编译,极大提高了效率。

海思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 中的语法和bat语法

makefile 中的语法和bat语法

makefile 中的语法和bat语法Makefile 是一种用于自动化构建和管理代码的工具,它使用了自己的语法和规则来描述项目的编译和链接过程。

而 BAT (Batch) 是一种用于 Windows 系统的批处理文件,用于执行一系列命令来实现自动化任务。

本文将分别介绍 Makefile 中的语法和 BAT 语法。

一、Makefile 中的语法1. 目标与依赖关系在 Makefile 中,每一条规则包含一个目标和一组依赖。

目标表示要生成的文件,依赖表示生成目标所需要的文件或其他目标。

语法如下:```target: dependency1 dependency2 ...command1command2...```其中,target 和 dependency 可以是文件名或者其他目标名称。

command 表示生成目标的具体操作命令。

2. 变量Makefile 中可以定义变量,用于存储一些常用的值或路径。

语法如下:```VAR_NAME = value```变量的值可以是字符串或者路径等。

在规则中使用变量时,需要在变量前加上 $ 符号,例如:```target: dependencycommand $(VAR_NAME)```3. 函数Makefile 中提供了一些内置函数来处理变量和字符串。

常用的函数有:- $(wildcard pattern): 查找符合 pattern 的文件或目录。

- $(foreach var, list, text): 遍历 list 中的每个元素,将其赋值给 var,并将 text 应用到每个元素上。

- $(shell command): 执行 command 命令,并将标准输出作为函数返回值。

- ...4. 条件判断在 Makefile 中,可以使用条件语句来根据不同的条件执行不同的指令。

常用的条件语句有:- ifeq (arg1, arg2)...else...endif- ifdef var...else...endif- ...二、BAT 语法BAT 文件是包含一系列批处理命令的文本文件,用于在 Windows 系统中执行一系列自动化任务。

面试题----makefile文件的作用

面试题----makefile文件的作用

⾯试题----makefile⽂件的作⽤
make⼯具和makefile⽂件
make⼯具和makefile⽂件简介
make命令和makefile⽂件的结合提供了⼀个在项⽬管理领域⼗分强⼤的⼯具。

它不仅常被⽤于控制源代码的编译和链接,⽽且还⽤于⼿册页的编写以及将应⽤程序安装到⽬标⽬录。

makefile⽂件由⼀组依赖关系和规则构成。

每个依赖关系⼜⼀个⽬标(即将要创建的⽂件)和⼀组该⽬标所依赖的源⽂件组成。

⽽规则描述了如何通过这些依赖⽂件创建⽬标。

⼀般来说,⽬标是⼀个单独的可执⾏⽂件。

make命令会读取makefile⽂件的内容,它先确定⽬标⽂件和要创建的⽂件,然后⽐较该⽬标所依赖的源⽂件的⽇期和时间以决定该采取那条规则来构建⽬标。

通常在创建最终的⽬标⽂件之前,它需要先创建⼀些中间⽬标。

make命令会根据makefile⽂件来确定⽬标⽂件的创建顺序以及正确的规则调⽤顺序。

⾯试题:makefile⽂件的作⽤是什么?
makefile⽂件和make⼯具⼀起使⽤,⽤于控制⼯程项⽬的编译和链接,也可以⽤来编写⼿册页和程序的安装。

make⼯具⽤于解释执⾏makefile⽂件中的内容。

makefile⽂件中通常包含源⽂件和⽬标⽂件的依赖关系以及从源⽂件⽣成⽬标⽂件的规则。

make⼯具可以根据makefile判断哪些⽂件需要被重新编译,⽬标⽂件的构建顺序等。

makefile--参数传递、条件判断、include(五)

makefile--参数传递、条件判断、include(五)

makefile--参数传递、条件判断、include(五)在多个Makefile嵌套调⽤时,有时我们需要传递⼀些参数给下⼀层Makefile。

⽐如我们在顶层Makefile⾥⾯定义的打开调试信息变量DEBUG_SYMBOLS,我们希望在进⼊⼦⽬录执⾏⼦Makefile时该变量仍然有效,这是需要将该变量传递给⼦Makefile,那怎么传递呢?这⾥有两种⽅法:1. 在上层Makefile中使⽤”export”关键字对需要传递的变量进⾏声明。

⽐如:1 2DEBUG_SYMBOLS = TRUE export DEBUG_SYMBOLS当不希望将⼀个变量传递给⼦ make 时,可以使⽤指⽰符 “unexport”来声明这个变量。

export⼀般⽤法是在定义变量的同时对它进⾏声明。

如下:1export DEBUG_SYMBOLS = TRUE2. 在命令⾏上指定变量。

⽐如:1$(MAKE) -C xxx DEBUG_SYMBOLS = TRUE这样在进⼊⼦⽬录xxx执⾏make时该变量也有效。

像编程语⾔⼀样,Makefile也有⾃⼰的条件语句。

条件语句可以根据⼀个变量值来控制make的执⾏逻辑。

⽐较常⽤的条件语句是ifeq –else-endif、ifneq-else-endif、ifdef-else-endif。

ifeq关键字⽤来判断参数是否相等。

⽐如判断是否⽣成调试信息可以这么⽤:1 2 3 4 5 6ifeq ($(DEBUG_SYMBOLS), TRUE) >---CFLAGS += -g -Wall -Werror -O0 else>---CFLAGS += -Wall -Werror -O2 endifIfneq和ifeq作⽤相反,此关键字是⽤来判断参数是否不相等。

ifdef关键字⽤来判断⼀个变量是否已经定义。

后两个关键字⽤法和ifeq类似。

现在我们继续改进我们上⼀节的Makefile,上⼀节的Makefile完成Makefile的嵌套调⽤,每⼀个模块都有⾃⼰的Makefile。

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

Makefile全解析什么是makefile或许很多Winodws 的程序员都不知道这个东西,因为那些Windows的IDE 都为你做了这个工作,但我觉得要作一个好的和professional 的程序员,makefile 还是要懂。

这就好像现在有这么多的HTML 的编辑器,但如果你想成为一个专业人士,你还是要了解HTML 的标识的含义。

特别在Unix 下的软件编译,你就不能不自己写makefile 了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

程序的编译连接源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。

在编译时,编译器只检测程序语法,和函数、变量是否被声明。

如果函数未被声明,编译器会给出一个警告,但可以生成Object File。

而在链接程序时,链接器会在所有的ObjectFile 中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001 错误,意思说是说,链接器未能找到函数的实现。

你需要指定函数的Object File.Makefile 的规则target ... : prerequisites ...command......target 也就是一个目标文件,可以是Object File,也可以是执行文件。

还可以是一个标签(Label),对于标签这种特性,在后续的―伪目标‖章节中会有叙述。

prerequisites 就是,要生成那个target 所需要的文件或是目标。

command 也就是make 需要执行的命令。

(任意的Shell 命令)如果命令太长,你可以使用反斜框(‗\‘)作为换行符。

一般来说,make 会以UNIX 的标准Shell,也就是/bin/sh 来执行命令。

一个简单Makefile的解析test:main.ogcc -o test main.omain.o:main.cgcc -c main.c -o main.oclean:@rm -vf main.o test使用:定义依赖关系;依赖的下行是要执行的编译或连接命令,必须以TAB开头;在clean其冒号后什么也没有,那么,make 就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。

要执行其后的命令,就要在make 命令后明显得指出这个lable 的名字。

这样的方法非常有用,我们可以在一个makefile 中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

在默认的方式下,也就是我们只输入make 命令。

那么,1、make 会在当前目录下找名字叫―Makefile‖或―makefile‖的文件。

2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到―test‖这个文件,并把这个文件作为最终的目标文件。

3、如果test文件不存在,或是test所依赖的后面的 .o 文件的文件修改时间要比test这个文件新,那么,他就会执行后面所定义的命令来生成test这个文件。

4、如果test所依赖的.o 文件也存在,那么make 会在当前文件中找目标为.o 文件的依赖性,如果找到则再根据那一个规则生成.o 文件。

(这有点像一个堆栈的过程)5、当然,你的C 文件和H 文件是存在的啦,于是make 会生成 .o 文件,然后再用 .o 文件生命make 的终极任务,也就是执行文件edit 了。

这就是整个make 的依赖性,make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make 根本不理。

make 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

通过上述分析,我们知道,像clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make 执行。

即命令——―make clean‖,以此来清除所有的目标文件,以便重编译。

GNU 的make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make 会自动识别,并自己推导命令。

只要make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make 找到一个whatever.o ,那么whatever.c ,就会是whatever.o 的依赖文件。

并且cc -cwhatever.c 也会被推导出来。

使用变量本例中只是用到了一个收入文件,如果以来文件比较多,为了便于输入和引用,可以使用定义变量,如SRC=main.c,这样以后就可以使用$(SRC)来代替main.c了。

注意:也可以使用―:=‖操作符定义变量.Makefile详述Makefile 里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

1、显式规则。

显式规则说明了,如何生成一个或多的的目标文件。

这是由Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

2、隐晦规则。

由于我们的make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make 所支持的。

3、变量的定义。

在Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点你C 语言中的宏,当Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。

4、文件指示。

其包括了三个部分,一个是在一个Makefile 中引用另一个Makefile,就像C 语言中的include 一样;另一个是指根据某些情况指定Makefile 中的有效部分,就像C 语言中的预编译#if 一样;还有就是定义一个多行的命令。

引用其它的Makefile:在Makefile 使用include 关键字可以把别的Makefile 包含进来,这很像 C 语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。

include 的语法是:include <filename>filename 可以是当前操作系统Shell 的文件模式(可以保含路径和通配符)在include 前面可以有一些空字符,但是绝不能是[Tab]键开始。

include 和<filename>可以用一个或多个空格隔开。

5、注释。

Makefile 中只有行注释,和UNIX 的Shell 脚本一样,其注释是用―#‖字符,这个就像C/C++中的―//‖一样。

如果你要在你的Makefile 中使用―#‖字符,可以用反斜框进行转义,如:―\#‖。

最后,还值得一提的是,在Makefile 中的命令,必须要以[Tab]键开始。

这样,make的执行过程如下:1、读入所有的Makefile。

2、读入被include 的其它Makefile。

3、初始化文件中的变量。

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

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

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

7、执行生成命令。

使用通配符如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。

make 支持三各通配符:―*‖,―?‖和―[...]‖。

这是和Unix 的B-Shell 是相同的。

波浪号(―~‖)字符在文件名中也有比较特殊的用途。

如果是―~/test‖,这就表示当前用户的$HOME 目录下的test 目录。

而―~hchen/test‖则表示用户hchen 的宿主目录下的test 目录。

(这些都是Unix 下的小知识了,make 也支持)而在Windows 或是MS-DOS下,用户没有宿主目录,那么波浪号所指的目录则根据环境变量―HOME‖而定。

通配符代替了你一系列的文件,如―*.c‖表示所以后缀为 c 的文件。

一个需要我们注意的是,如果我们的文件名中有通配符,如:―*‖,那么可以用转义字符―\‖,如―\*‖来表示真实的―*‖字符,而不是任意长度的字符串。

好吧,还是先来看几个例子吧:clean:rm -f *.o上面这个例子我不不多说了,这是操作系统Shell 所支持的通配符。

这是在命令中的通配符。

print: *.clpr -p $?touch print上面这个例子说明了通配符也可以在我们的规则中,目标print 依赖于所有的[.c]文件。

其中的―$?‖是一个自动化变量,表示被修改的文件。

objects = *.o上面这个例子,表示了,通符同样可以用在变量中。

并不是说[*.o]会展开,不!objects的值就是“*.o”。

Makefile 中的变量其实就是C/C++中的宏。

如果你要让通配符在变量中展开,也就是让objects 的值是所有[.o]的文件名的集合,那么,你可以这样:objects := $(wildcard *.o),这种用法由关键字―wildcard‖指出。

路径的自动搜索在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。

所以,当make 需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make 在自动去找。

Makefile 文件中的特殊变量―VPATH‖就是完成这个功能的,如果没有指明这个变量,make 只会在当前的目录中去找寻依赖文件和目标文件。

如果定义了这个变量,那么,make 就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

VPATH = src:../headers上面的的定义指定两个目录,―src‖和―../headers‖,make 会按照这个顺序进行搜索。

目录由―冒号‖分隔。

(当然,当前目录永远是最高优先搜索的地方)伪目标最早先的一个例子中,我们提到过一个―clean‖的目标,这是一个―伪目标‖,clean:正像我们前面例子中的―clean‖一样,即然我们生成了许多文件编译文件,我们也应该提供一个清除它们的―目标‖以备完整地重编译而用。

(以―make clean‖来使用该目标)因为,我们并不生成―clean‖这个文件。

―伪目标‖并不是一个文件,只是一个标签,由于―伪目标‖不是文件,所以make 无法生成它的依赖关系和决定它是否要执行。

我们只有通过显示地指明这个―目标‖才能让其生效。

当然,―伪目标‖的取名不能和文件名重名,不然其就失去了―伪目标‖的意义了。

当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记―.PHONY‖来显示地指明一个目标是―伪目标‖,向make 说明,不管是否有这个文件,这个目标就是―伪目标‖。

相关文档
最新文档