linux下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命令,包括编译、链接、拷贝等操作。
linux中的make命令的详细解释
linux中的make命令的详细解释linxu下的make命令是一个GNU下的工程化编译工具。
下面由店铺为大家整理了linux的make命令的详细解释的相关知识,希望对大家有帮助!一、linux中的make命令的详细解释make命令是GNU的工程化编译工具,用于编译众多相互关联的源代码问价,以实现工程化的管理,提高开发效率。
语法make(选项)(参数)选项-f:指定“makefile”文件;-i:忽略命令执行返回的出错信息;-s:沉默模式,在执行之前不输出相应的命令行信息;-r:禁止使用build-in规则;-n:非执行模式,输出所有执行命令,但并不执行;-t:更新目标文件;-q:make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息;-p:输出所有宏定义和目标文件描述;-d:Debug模式,输出有关文件和检测时间的详细信息。
Linux下常用选项与Unix系统中稍有不同,下面是不同的部分:-c dir:在读取 makefile 之前改变到指定的目录dir;-I dir:当包含其他 makefile文件时,利用该选项指定搜索目录;-h:help文挡,显示所有的make选项;-w:在处理 makefile 之前和之后,都显示工作目录。
参数目标:指定编译目标。
二、Linux中的make命令详解实例1. 一个简单的例子为了编译整个工程,你可以简单的使用 make 或者在 make 命令后带上目标 all。
$ makegcc -c -Wall test.cgcc -c -Wall anotherTest.cgcc -Wall test.o anotherTest.o -o test你能看到 make 命令第一次创建的依赖以及实际的目标。
如果你再次查看目录内容,里面多了一些 .o 文件和执行文件:$ lsanotherTest.c anotherTest.o Makefile test test.c test.h test.o 现在,假设你对 test.c 文件做了一些修改,重新使用 make 编译工程:$ makegcc -c -Wall test.cgcc -Wall test.o anotherTest.o -o test你可以看到只有 test.o 重新编译了,然而另一个 Test.o 没有重新编译。
linux makefile中路径写法
linux makefile中路径写法================Makefile在Linux系统中被广泛用于编译和构建项目,它能够自动化地完成许多重复的任务,大大提高了开发效率。
在Makefile中,路径的书写是一个重要的组成部分。
下面我们将详细讨论在Linux Makefile中如何正确地书写路径。
一、绝对路径与相对路径-----------在Makefile中,路径的书写主要有两种方式:绝对路径和相对路径。
1. **绝对路径**:从文件系统的根目录开始的路径。
例如`/home/user/myfile.txt`就是一个绝对路径。
在Makefile中,绝对路径通常是从构建系统的根目录开始的。
2. **相对路径**:相对于当前工作目录的路径。
在Makefile 中,通常使用`./`表示当前目录,`../`表示上级目录。
选择使用绝对路径还是相对路径取决于你的项目结构和开发者的偏好。
一般来说,推荐使用相对路径,因为它们更灵活,可以适应不同的项目目录结构。
二、路径书写规范--------在Makefile中书写路径时,有一些规范和最佳实践需要遵循:1. **文件名**:文件名应该简洁明了,不要使用空格或其他特殊字符。
避免使用长文件名或难以理解的文件名。
2. **目录分隔符**:在Linux系统中,路径的分隔符是反斜杠(`\`)。
当路径包含多个目录时,需要使用两个反斜杠(`\\` 或`/`)。
在Makefile中,推荐使用正斜杠(`/`),因为它在所有平台上都是通用的。
3. **自动更新**:在Makefile中,可以使用`$(wildcard)`函数来匹配目录中的文件。
例如,`$(wildcard source/*.c)`将匹配source目录下的所有C源文件。
4. **构建系统根目录**:在Makefile中,通常使用构建系统的根目录作为路径的起点。
这可以通过变量来实现,例如`ROOT :=/path/to/build`。
linux vscode makefile语法
linux vscode makefile语法在Linux 系统中,如果您想使用VSCode 编写Makefile 相关的项目,可以参考以下步骤进行安装和配置:1. 首先,确保已经正确安装了Visual Studio Code。
如果尚未安装,可以参考[1] 中的教程进行安装。
2. 安装Makefile 插件。
打开VSCode,转到“扩展”选项卡(快捷键:Ctrl+Shift+X),搜索“Makefile”,找到名为“Makefile Support”的插件,点击“安装”。
3. 创建一个新的Makefile 项目。
在VSCode 中,创建一个新的文件夹,然后在该文件夹中打开终端(快捷键:Ctrl+`)。
4. 编写Makefile 语法。
在项目根目录下创建一个名为“Makefile”的文件,然后编写相应的Makefile 语法。
以下是一个简单的示例:```make# 设置变量MY_PROJECT_NAME = MyProjectMY_PROJECT_VERSION = 1.0# 设置目标all: build# 构建目标build:echo "Building $MY_PROJECT_NAME $MY_PROJECT_VERSION"# 在这里添加您的构建命令,例如:cmake、make等# 清理目标clean:echo "Cleaning $MY_PROJECT_NAME"# 在这里添加您的清理命令,例如:rm -rf build/# 默认执行构建目标default: build```5. 保存Makefile 文件并按F5 键运行项目。
VSCode 将会自动使用内置的终端执行Makefile 中的命令。
6. 如果需要使用GPU 加速构建,可以在Makefile 中添加相应的NVIDIA CUDA 或者AMD OpenCL 命令。
例如,如果您使用的是NVIDIA GPU,可以添加以下命令:```makebuild_gpu:echo "Building $MY_PROJECT_NAME $MY_PROJECT_VERSION using GPU"# 在这里添加您的GPU 构建命令,例如:nvcc、cuda编译器等```7. 按照项目需求修改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基本使用方法
makefile基本使用方法makefile是一种用来管理和自动化构建程序的工具。
它可以根据源代码文件的依赖关系和编译规则来自动构建目标文件和可执行文件。
makefile的基本使用方法如下:1. 创建makefile文件:在项目的根目录下创建一个名为makefile 的文件。
2. 定义变量:在makefile中,可以使用变量来存储一些常用的参数和路径,以便于后续的使用。
例如,可以定义一个名为CC的变量来指定编译器的名称,如:CC=gcc。
3. 编写规则:在makefile中,可以使用规则来指定如何编译源代码文件和生成目标文件。
一个规则由两部分组成:目标和依赖。
目标是要生成的文件,依赖是生成目标文件所需要的源代码文件。
例如,可以编写以下规则:```target: dependency1 dependency2command1command2```其中,target是目标文件,dependency1和dependency2是依赖的源代码文件,command1和command2是生成目标文件所需要执行的命令。
4. 编写默认规则:在makefile中,可以使用一个默认规则来指定如何生成最终的可执行文件。
默认规则的目标通常是可执行文件,依赖是所有的源代码文件。
例如,可以编写以下默认规则:```all: target1 target2```其中,target1和target2是生成的目标文件。
5. 编写clean规则:在makefile中,可以使用clean规则来清理生成的目标文件和可执行文件。
例如,可以编写以下clean规则: ```clean:rm -f target1 target2```其中,target1和target2是要清理的目标文件。
6. 运行make命令:在命令行中,使用make命令来执行makefile 文件。
make命令会自动根据规则和依赖关系来编译源代码文件和生成目标文件。
例如,可以运行以下命令:``````make命令会根据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
linux 顶层makefile分析
Linux顶层Makefile文件分析分类:Linux 系列2013-05-06 17:05 585人阅读评论(0) 收藏举报1、make menuconfigVERSION = 2PATCHLEVEL = 6SUBLEVEL = 26EXTRAVERSION =NAME = Rotary Wombat# *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 avoids hard-to-debug behaviour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory#-r禁止使用build-in规则#--no-print-directory是:不要再屏幕上打印"Entering directory.."#记住变量SHELL,MAKEFLAGS在整个make的执行过程中#始终被自动的传递给所有的子make# We are using a recursive build, so we need to do a little thinking# to get the ordering right.## Most importantly: sub-Makefiles should only ever modify files in# their own directory. If in some directory we have a dependency on# a file in another dir (which doesn't happen often, but it's often# unavoidable when linking the built-in.o targets which finy# turn into vmlinux), we will call a sub make in that other dir, and# after that we are sure that everything which is in that other dir# is now up to date.## The only cases where we need to modify files which have global# effects are thus separated out and done before the recursive# descending is started. They are now explicitly listed as the# prepare rule.# To put more focus on warnings, be less verbose as default# Use 'make V=1' to see the full commandsifdef V #v=1ifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V) #把V的值作为KBUILD_VERBOSE的值 endifendififndef KBUILD_VERBOSE #即默认我们是不回显的#回显即在命令执行前显示要执行的命令KBUILD_VERBOSE = 0endif# 函数origin并不操作变量的值,只是告诉你你的这个变量是哪里来的。
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命令时,如果没有指定目标,则系统会执行的第一个目标。
linux下makefile文件中比较大小的语法
linux下makefile文件中比较大小的语法在Linux下,Makefile是一种常用的构建工具,用于自动化编译和构建软件项目。
在Makefile中,我们经常需要比较文件的大小来判断是否需要重新编译或执行某些操作。
本文将介绍在Linux下Makefile 文件中比较大小的语法。
在Makefile中,我们可以使用shell命令来执行系统命令。
比较文件大小的常用命令是`stat`和`du`。
`stat`命令用于获取文件的详细信息,包括文件大小,而`du`命令用于计算文件或目录的大小。
首先,我们可以使用`stat`命令获取文件的大小,并将结果保存到一个变量中。
下面是一个示例:```file_size := $(shell stat -c %s file.txt)```上述命令将获取文件`file.txt`的大小,并将结果保存到变量`file_size`中。
`-c %s`选项用于指定输出文件大小的格式。
接下来,我们可以使用条件语句来比较文件大小。
常用的条件语句有`ifeq`和`ifneq`。
下面是一个示例:```ifeq ($(file_size), 0)@echo "文件为空"else@echo "文件大小为$(file_size)字节"endif```上述代码将判断文件大小是否为0,如果是,则输出"文件为空",否则输出"文件大小为$(file_size)字节"。
`@echo`命令用于输出信息,`$(file_size)`表示变量的值。
除了使用`stat`命令获取文件大小外,我们还可以使用`du`命令计算文件或目录的大小。
下面是一个示例:```file_size := $(shell du -b file.txt | cut -f1)```上述命令将使用`du`命令计算文件`file.txt`的大小,并使用`cut`命令提取文件大小。
Linuxmake命令详解
a —— 也就是all,输出所有的调试信息。(会非常的多) b —— 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。 v —— 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。 i —— 也就是implicit,输出所以的隐含规则。 j —— 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。 m —— 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。
“-i” “--ignore-errors” 在执行时忽略所有的错误。
“-I <dir>” “--include-dir=<dir>” 指定一个被包含makefile的搜索目标。可以使用多个“-I”参数来指定多个目录。
“-j [<jobsnum>]” “--jobs[=<jobsnum>]” 指同时运行命令的个数。如果-j后没有这个jobsnum参数,make运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后 一个“-j”才是有效的。(注意这个参数在MS-DOS中是无用的)
“--no-print-directory” 禁止“-w”选项。
“-W <file>” “--what-if=<file>” “--new-file=<file>” “--assume-file=<file>” 假定目标<file>需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行UNIX的“touch”命 令一样,使得<file>的修改时间为当前时间。
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 命令行参数
-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有所帮助。
linux make命令的工作原理
linux make命令的工作原理make命令是一个用于自动化编译和构建程序的工具,它通过读取Makefile 文件中的规则来确定如何构建目标文件。
Makefile文件包含了目标文件和依赖关系的描述,以及构建目标文件的命令。
Make命令的工作原理如下:1.读取Makefile文件:make命令首先会读取当前目录下的Makefile文件,该文件包含了目标文件和依赖关系的描述,以及构建目标文件的命令。
2.解析规则:make命令会解析Makefile文件中的规则,包括目标文件、依赖关系和命令。
3.检查依赖关系:make命令会检查目标文件的依赖关系,并判断是否需要重新构建目标文件。
如果目标文件不存在或者依赖的文件被修改过,则需要重新构建目标文件。
4.构建目标文件:如果需要重新构建目标文件,make命令会执行Makefile文件中对应目标文件的构建命令。
构建命令可以是编译源代码、链接目标文件等操作。
5.更新目标文件:构建完成后,make命令会更新目标文件的时间戳,以反映最新的修改时间。
6.递归构建:如果目标文件的依赖关系中还包含其他目标文件,make命令会递归地执行构建过程,以确保所有的依赖关系都得到满足。
7.完成构建:当所有的目标文件都构建完成后,make命令会输出构建成功的消息,并退出。
Make命令的优势在于它只会构建需要更新的目标文件,而不会重新构建所有的文件。
这样可以提高编译和构建的效率,尤其是在大型项目中。
另外,Make命令还支持并行构建,可以同时构建多个目标文件,进一步提高构建的效率。
总结起来,Make命令的工作原理是通过读取Makefile文件中的规则来确定如何构建目标文件,检查目标文件的依赖关系并判断是否需要重新构建,执行构建命令来生成目标文件,递归构建所有的依赖关系,最后输出构建成功的消息。
Make命令的优势在于只构建需要更新的文件,提高构建效率。
Linux的Makefile-电子版课件
makefile的语法-使用变量
定义变量: 变量名 = 值 调用变量: $(变量名) 在多处使用同样的信息时变量非常有用。
makefile的语法-使用变量
修改上面的例子 PROC = hello CC = gcc SOURCES = hello.c func.c
OBJECTS = hello.o func.o
makefile的语法-函数
一个例子: comma:= , empty:= space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo)) 在这里例子中$(bar)的最终取值为“a,b,c”
总述-程序的编译和链接
C或是C++,首先要把源文件变成中间代码,在linux在是“.o”文件,这个一 步动作叫做编译(compile); 把大量的中间文件集合起来合并成一个可执行文件,这个过程叫做链接 (link); 在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接 时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在 Windows 下这种包叫“库文件”(LibraryFile),在 linux,是Archive File,也就是 .a 文件,或者是动态库.so文件。
是一个标签; prerequisites就是,要生成那个target所需要的文件或是目标;
command 也就是make 需要执行的命令(任意的Shell命令)。
make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较 targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要
linux makefile include用法
在 Linux 中,Makefile 是一种文本文件,用于定义项目的构建规则和依赖关系。
include是 Makefile 中的一个关键字,用于引入其他 Makefile 文件。
这对于将构建规则拆分为多个文件以提高可维护性非常有用。
以下是关于include在 Linux Makefile 中的用法的详细解释:include的基本语法:•include后面可以跟一个或多个文件名,用空格分隔。
•这些文件名可以包含通配符,例如*.mk。
示例:假设有两个 Makefile 文件,分别是main.mk和extra.mk。
main.mkextra.mk在上述例子中,main.mk包含了extra.mk。
这样,main.mk中的规则就可以使用extra.mk中定义的规则和变量。
使用场景和注意事项:1.模块化项目:–include用于将项目的不同部分拆分为独立的 Makefile,使得项目结构更加清晰和易于维护。
2.变量和规则共享:–通过include,可以在不同的 Makefile 文件中共享变量和规则,避免代码重复。
3.条件包含:–可以根据条件来选择是否包含某个 Makefile,例如基于不同的操作系统或构建类型。
1.文件名通配符:–include后面可以使用通配符,方便引入符合某个模式的多个文件。
注意事项:•文件名可以是相对路径或绝对路径。
•文件名中可以包含变量,这样可以动态地选择引入的文件。
•在引入文件时,Makefile 会在当前目录和系统的默认搜索路径中查找文件。
通过合理使用include,可以更好地组织和管理项目的构建规则,提高 Makefile 的可读性和可维护性。
linux makefile basename函数
linux makefile basename函数摘要:1.Linux Makefile 简介2.Makefile 中的函数3.basename 函数的作用4.basename 函数的参数5.basename 函数的返回值6.basename 函数在Makefile 中的应用示例正文:Linux Makefile 是一个用于管理编译过程的文件,它可以根据源文件之间的依赖关系自动编译、链接和安装软件。
在Makefile 中,可以定义一些函数来简化重复的操作,提高自动化程度。
basename 函数就是其中一个常用的函数。
basename 函数是用来获取文件名的函数,它可以从给定的路径名中提取文件名部分。
该函数的定义和使用方式类似于shell 脚本中的basename 命令。
在Makefile 中,basename 函数可以方便地提取源文件名,以便进行后续操作。
basename 函数的语法如下:```basename(prefix, suffix)```其中,`prefix` 参数表示路径名的前缀部分,`suffix` 参数表示路径名的后缀部分。
函数返回值是去掉前缀和后缀后的文件名。
basename 函数的参数都是可选的。
如果不提供`prefix` 参数,那么默认前缀为空字符串;如果不提供`suffix` 参数,那么默认后缀为空字符串。
basename 函数的返回值是一个字符串,表示去掉前缀和后缀后的文件名。
如果源路径名中不包含前缀或后缀,那么返回值将与源路径名相同。
下面举一个basename 函数在Makefile 中的应用示例。
假设我们有一个源文件`main.c`,我们想要提取文件名并生成一个名为`main` 的目标文件。
我们可以这样写Makefile:```all: mainmain: main.ct$(CC) $(CFLAGS) -o $@ $<.PHONY: cleanclean:trm -f main```在这个例子中,我们使用了`$(CC) $(CFLAGS) -o $@ $<` 命令来编译源文件。
makefile 条件编译
makefile 条件编译MakefileUnix/Linux译系统编写程序所必需的文件,其中包含了定义规则以及编译程序所必需的指令。
通常情况下,一个规则描述了从一个或多个源文件到一个或多个目标文件之间的变换过程。
在特定的编译环境中,定义的规则必须能够生成所有需要的目标文件及时准确的。
有时候,一个源文件或多个源文件具有不同的编译条件,此时Makefile件编译的技术就派上用场了。
这种技术可以根据指定的编译条件自动生成 Makefile则,使得编译器只有在满足编译条件时才会编译特定的源文件。
Makefile件编译基本依赖于 make令,它可以根据给定的源文件及编译条件,自动生成 Makefile则。
Make令使用 C言编写,可以从一个或多个文本文件中读取输入,比如源文件,然后根据相应的编译条件,使用 if句来生成 Makefile则。
要想理解 Makefile件编译,首先必须明白 Makefile几个基本概念。
Makefile 中有若干规则,每个规则由一个目标文件,一个或多个依赖文件,以及一系列的命令组成。
它们通常以三个元素表示: target: dependenciestcommands其中,target 代表目标文件,dependencies该目标文件的依赖文件,commands该目标文件生成所需的命令。
为了利用 Makefile件编译,可以将每个文件的编译条件定义为一个 Makefile量,这样 Make编译文件时就可以根据指定的编译条件来生成 Makefile则。
例如,对于两个源文件 A B,A编译条件为BUILD_A,B编译条件为 BUILD_B,只有当 BUILD_A 为真,A会被编译,当 BUILD_B 为真,B会被编译。
要实现 Makefile件编译,可以使用 Make 中的 if件语句:ifeq (BUILD_A,1)A: ../A.cpptg++ -o A ../A.cppendififeq (BUILD_B,1)B: ../B.cpptg++ -o B ../B.cppendif上面的 Makefile 中,对于 A B两个源文件,它们的编译条件分别是 BUILD_A BUILD_B,即 BUILD_A 为真时,A会被编译,BUILD_B 为真时,B会被编译。
makefile参数
makefile参数Makefile是一种文本文件,用于描述构建源代码的规则和依赖关系,以及如何将源代码编译成可执行文件或库。
Makefile通常由一个名为"make"的工具来解析和执行,该工具会根据规则自动检测源码的更改,并根据需要重新编译相关文件。
Makefile的参数可以用于修改make工具的行为,并指导其对源代码进行编译和构建。
以下是一些常用的Makefile参数:1. -f <filename>或--file=<filename>: 指定Makefile的文件名。
默认情况下,make工具会在当前目录下寻找名为"Makefile"或"makefile"的文件作为Makefile文件。
使用该参数可以指定不同的Makefile文件。
2. -j <n>或--jobs=<n>: 指定make工具并行处理的任务数。
该参数可以加快构建过程的速度,尤其适用于大型项目。
通常推荐的取值范围是CPU核数的两倍。
3. -C <dir>或--directory=<dir>: 指定make工具的工作目录。
默认情况下,make工具会在当前目录下查找Makefile文件并进行构建。
使用该参数可以指定其他目录,从而在其中查找Makefile文件并在该目录下进行构建。
4. --dry-run: 执行模拟运行,不实际构建任何文件。
该参数可以用于检查Makefile的正确性,以及在构建之前查看将要执行的命令。
5. --silent或--quiet: 取消make工具的输出信息。
使用该参数可以让构建过程更加清晰,只显示构建过程的关键信息。
6. --no-print-directory: 取消make工具的目录切换信息的输出。
默认情况下,make工具会在进入每个目录之前打印当前切换的目录路径。
使用该参数可以减少输出信息的大小。
linux系统中make的用法
linux系统中make的用法make是一个常用的Linux命令,用于自动化编译程序。
当有多个源文件需要编译成可执行文件时,手动一个个编译比较麻烦。
这时候,我们就可以使用make命令实现自动化编译。
make命令的基本用法为:在Makefile文件中定义编译规则和依赖关系,然后运行make命令即可自动编译程序。
Makefile是一个文本文件,可以使用vi、nano等编辑器创建和编辑。
make命令的常用参数如下:* -f 指定Makefile文件,默认为当前目录下的Makefile或makefile文件。
* -n 或 --just-print 只打印命令,而不实际执行。
* -j 指定同时执行的任务数,加快编译速度。
* clean 清除中间文件和可执行文件等生成的文件。
Makefile文件中的基本语法为:```target: prerequisitescommand```其中,target为编译目标,prerequisites为编译目标所依赖的文件,command为执行编译的命令。
例如:```hello: hello.cgcc -o hello hello.c```这个Makefile文件中定义了一个名为“hello”的编译目标,它依赖于名为“hello.c”的源文件,执行命令为“gcc -o hellohello.c”,即将hello.c编译成可执行文件hello。
使用make命令进行编译时,可以直接运行“make”(默认编译第一个目标),也可以指定要编译的目标,例如“make hello”。
当定义的目标有多个依赖时,可以使用“$^”表示所有依赖文件,“$@”表示目标文件。
例如:```main.exe: main.c module1.o module2.ogcc -o $@ $^```这个Makefile文件中定义了一个名为“main.exe”的编译目标,它依赖于名为“main.c”、“module1.o”、“module2.o”的文件,执行命令为“gcc -o $@ $^”,即将这三个文件编译成可执行文件main.exe。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。
这里所默认的编译器是UNIX 下的GCC和CC。
关于程序的编译和链接——————————在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是.obj 文件,UNIX下是.o 文件,即Object File,这个动作叫做编译(compile)。
然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。
对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。
一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。
链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。
链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是.lib 文件,在UNIX 下,是Archive File,也就是.a 文件。
总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。
在编译时,编译器只检测程序语法,和函数、变量是否被声明。
如果函数未被声明,编译器会给出一个警告,但可以生成Object File。
而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。
你需要指定函数的Object File.2009-6-10 22:51 回复nginx_h11位粉丝2楼好,言归正传,GNU的make有许多的内容,闲言少叙,还是让我们开始吧。
Makefile 介绍———————make命令执行时,需要一个Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。
首先,我们用一个示例来说明Makefile的书写规则。
以便给大家一个感兴认识。
这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。
我们的规则是:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make 命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。
一、Makefile的规则在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...command......target也就是一个目标文件,可以是Object File,也可以是执行文件。
还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在command中。
说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile 的规则。
也就是Makefile中最核心的内容。
说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。
呵呵。
还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。
内容还多着呢。
:)二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。
edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o2009-6-10 22:51 回复nginx_h11位粉丝3楼反斜杠(\)是换行符的意思。
这样比较便于Makefile的易读。
我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。
如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。
在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些.c 文件和.h文件。
每一个.o 文件都有一组依赖文件,而这些.o 文件又是执行文件edit 的依赖文件。
依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。
记住,make并不管命令是怎么工作的,他只管执行所定义的命令。
make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。
要执行其后的命令,就要在make命令后明显得指出这个lable 的名字。
这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。
三、make是如何工作的在默认的方式下,也就是我们只输入make命令。
那么,1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果edit文件不存在,或是edit所依赖的后面的.o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。