首页 > 系统相关 >【Linux】Makefile 基本语法

【Linux】Makefile 基本语法

时间:2024-04-07 15:58:16浏览次数:33  
标签:文件 make 规则 Makefile 语法 Linux input main

make :一般说的是 GNU Make,是一个软件,将源代码文件编译成可执行的二进制文件;
Makefile : make 工具编译的时候需要使用 Makefile 文件,Makefile 文件描述了整个工程的编译、连接规则。

接上一节make 工具和 Makefile 文件的引入

Makefile 举例

注意 Makefile 的大小写 !!!
在这里插入图片描述
需要注意的是,所有行首需要空出来的地方一定要使用 TAB 键 !!!
在这里插入图片描述
执行一下 Makefile 文件,只需要输入make命令;
在这里插入图片描述
若要清除工程,只需要输入make clean,注意是删掉所有编译出来的文件,而不是删除源文件。
在这里插入图片描述
现在进行一些操作来展现 make 工具的强大之处,比如只修改一下 input.c 文件(在第 5 行输入回车换行);
在这里插入图片描述
在这里插入图片描述
再次输入make命令;
在这里插入图片描述
通过两次 make 之后的结果可以看出,修改某个源文件,只会重新编译这个源文件。

Makefile 语法

Makefile 可以完成以下功能:
如果工程没有编译过,那么工程中的所有 .c 文件都会被编译并且连接成可执行文件;
如果只修改了工程中某几个 .c 文件,则只会重新编译这几个源文件;
如果只修改了工程中某几个 .h 文件,则就会重新编译包含这几个头文件的所有源文件并且连接成可执行文件;
要使用 make 工具,首先就要编写 Makefile 文件。

Makefile 规则格式:

目标:依赖文件集合
	命令1
	命令2
	......
命令1和命令2前面空出来的地方必须使用 TAB 键

比如下面这条规则:

main:main.o input.o calcu.o
	gcc -o main main.o input.o calcu.o

这条规则的目标是 main ,main.o、input.o、calcu.o 是生成 main 的依赖文件,如果要更新 main ,就必须要先更新他的所有依赖文件,只要依赖文件任何一个有了更新,那么它的目标就必须更新。

Makefile 变量

Makefile 中的变量都是字符串,类似于 C 语言中的宏定义;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
赋值符 =
在这里插入图片描述
前面加上 @ 符号就不会显示执行过程;
在这里插入图片描述
采用等号(=)赋值,变量的真实值取决于它所引用的最后一次有效值。

赋值符 :=
在这里插入图片描述
在这里插入图片描述
采用冒号等号(:=)赋值,不会使用后面定义的变量,只能使用前面已经定义好了的。

赋值符 ?=
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
采用问号等号(?=)赋值,通过对比可以发现,curname ?= z 这句的意思是如果 curname 前面没有被赋值,则使用 ?= 后面的值,如果 curname 前面已经被赋值过,则使用前面赋的值。

赋值符 +=
在这里插入图片描述
在这里插入图片描述
采用加等号(+=)赋值, 原来 objects 是 main.o input.o ,追加一个 calcu.o ,现在 objects 是 main.o input.o calcu.o 。

Makefile 模式规则

%.o: %.c
	命令
当 % 出现在目标中的时候,目标中 % 的值决定了依赖中 % 的值

Makefile 自动化变量

在这里插入图片描述
通过模式规则和自动化变量将 Makefile 修改如下
在这里插入图片描述
在这里插入图片描述

Makefile 伪目标

Makefile 有一种特殊的目标叫做伪目标,一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命令。
使用伪目标主要是为了避免 Makefile 中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创建文件的。
在这里插入图片描述
上述规则中并没有创建文件 clean 的命令,因此工作目录下永远都不会存在文件 clean,当我们输入“ make clean ”以后,后面的“ rm *.o ”和“ rm main ”总是会执行。可是当不小心在工作目录下创建一个名为“ clean ”的文件之后,那就不一样了,当执行“ make clean ”的时候,规则因为没有依赖文件,所以目标被认为是最新的,因此后面的 rm 命令也就不会执行,我们预先设想的清理工程的功能也就无法完成。
在这里插入图片描述
为了避免这个问题,我们可以将 clean 声明为伪目标。声明方式如下:
在这里插入图片描述
在这里插入图片描述

Makefile 条件判断

与 C 语言类似,通过条件判断语句来根据不同的情况执行不同的分支,条件关键字有 4 个(ifeq、ifneq、ifdef、ifndef)。

Makefile 函数声明

Makefile 中的函数都是定义好了的,可以直接使用,不支持自定义函数,make 所支持的函数虽然不多但绝对够用。

make 的执行过程

1、make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件
2、当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
3、当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比
目标文件晚)的话就会执行后面的命令来更新目标。

  1 main: main.o input.o calcu.o
  2     gcc -o main main.o input.o calcu.o
  3 main.o: main.c
  4     gcc -c main.c
  5 input.o: input.c
  6     gcc -c input.c
  7 calcu.o: calcu.c
  8     gcc -c calcu.c
  9 
 10 clean:
 11     rm *.o
 12     rm main

上述代码中一共有 5 条规则,1、2 行为第一条规则,3、4 行为第二条规则,5、6 行为第三条规则,7、8 行为第四条规则,10、11、12 为第五条规则,make 命令在执行这个 Makefile 的时候其执行步骤如下:
首先更新第一条规则中的 main,第一条规则的目标成为默认目标,只要默认目标更新了那么就认为 Makefile 的工作完成了,整个 Makefile 就是为了完成这个工作。在第一次编译的时候由于 main 还不存在,因此第一条规则会执行,第一条规则依赖于文件 main.o、input.o 和 calcu.o 这个三个 .o 文件,这三个 .o 文件目前还都没有,因此必须先更新这三个文件。make 会查找以这三个 .o 文件为目标的规则并执行。以 main.o 为例,发现更新 main.o 的是第二条规则,因此会执行第二条规则,第二条规则里面的命令为“ gcc -c main.c ”,就是不连接编译 main.c,生成 main.o,其它两个 .o 文件同理;最后一个规则目标是 clean,它没有依赖文件,因此会默认依赖文件都是最新的,所以其对应的命令不会执行,当我们想要执行 clean 的话可以直接使用命令“ make clean ”,执行以后就会删除当前目录下所有的 .o 文件以及 main,因此 clean 的功能就是完成工程的清理。

make 工具完成了自动化编译工作,一旦写好了 Makefile 文件,以后只需要一个 make 命令即可完成整个工程的编译,避免了不必要的重复编译,大大提高了效率。

标签:文件,make,规则,Makefile,语法,Linux,input,main
From: https://blog.csdn.net/ZSW2027008838/article/details/137397878

相关文章

  • 远程连接与Linux基础使用指南
    1.远程连接与Linux基础使用指南1.远程连接排错详解1.0 Vmware小技巧挂起:把正在运行的虚拟机暂停,这样好处就是虚拟机不用关机。快照:给虚拟机当前状态拍摄一个保存节点,这个保存的节点可以用于恢复。可以在开机,挂起,关机状态拍摄。1.1现象关键提示:Connectionfaile......
  • Linux之隔离技术
    前言Linux的内核有两大特性Namespace和CGroup,这两种特性可以在Linux主机上实现主机名、用户、网络等全局资源的隔离,也是实现网络虚拟化、容器技术的基础。命名空间LinuxNamespace(命名空间)是一种操作系统层级的资源隔离技术,能够将Linux的全局资源,划分为namespace范围内......
  • ZYNQ学习之Petalinux 设计流程实战
    基本都是摘抄正点原子的文章:<领航者ZYNQ之嵌入式Linux开发指南V3.2.pdf,因初次学习,仅作学习摘录之用,有不懂之处后续会继续更新~PetaLinux工具提供了在Xilinx处理系统上自定义、构建和部署嵌入式Linux解决方案所需的一切。该解决方案旨在提高设计生产力,可与Xilinx硬......
  • Win11中安装虚拟化软件VMware,以及Linux虚拟机的详细安装配置
    文章目录前言安装VMwareWorkstationPro安装注意事项确认服务正常开启确认虚拟网络正常确认虚拟网卡使用VM新建Linux虚拟机新建虚拟机向导开启虚拟机后电脑蓝屏(可能)安装Linux虚拟机登录虚拟机前言记录时间[2024-4-7]本文讲述如何在Win11中安装虚拟化软......
  • linux 的一个socket 客户端程序
    linux的一个socket客户端程序 #ifndef__TCP_CLIENT_TEST_1__#define__TCP_CLIENT_TEST_1__#include<iostream>#include<cstring>#include<unistd.h>#include<arpa/inet.h>#include<sys/socket.h>intmain(){constchar*s......
  • Linux C指针以及指针在Linux内核中的应用
    在Linux环境下编写C语言程序时,指针是一个非常重要的概念,因为它们为处理内存地址、数组、字符串、函数、结构体等提供了极大的灵活性。在本篇博客中,我们将深入探讨C语言中的指针,理解它们的工作原理,并通过示例来展示它们的用途。什么是指针?指针是C语言的核心特性之一,它是一......
  • 面试常问问题——常用linux命令及如何查看日志?
    一、常用linux命令pwd   查看当前目录位置lscpgrepcdmvtaillesstouchmkdirpsaux  查看系统所有进程数据kill-oPID  强制中断一个进程的进行chmod  -Rxyz 文件或目录   改变文件或......
  • 掌握Linux内核技能:创建你的第一个字符设备驱动
    Linux字符设备驱动简介在Linux系统中,设备驱动是操作系统的重要组成部分,负责在用户程序和硬件设备之间提供接口。设备驱动可以分为字符设备驱动和块设备驱动,本文将重点介绍字符设备驱动的基本概念和实现方法。1.字符设备驱动概念字符设备是指那些以字符为单位进行数据传......
  • 2024年最新,Linux平台 CentOS8安装mysql流程,以及可能遇到的问题
    0.删除mysql如果下载过mysql,请先删除mysql,不确定的也可以先查询一下查询命令: rpm-qa|grepmysqlrpm-qa|grepmariadb删除查询到的这些文件rpm-e--nodeps//查询到的软件名称例如:查询到的mysql相关文件删除mysql相关文件,并查询***别忘记去解压目录下......
  • 手把手教你构建嵌入式Linux根文件系统
    /bin:此目录下存放着系统需要的可执行文件,一般都是一些命令,比如ls、mv等命令/dev:device的缩写,此目录下的文件都是和设备有关的。在Linux下一切皆文件,即使是硬件设备,也是以文件的形式存在的,比如/dev/ttymxc0就表示串口0/etc:此目录下存放着各种配置文件/lib:library的简称,也就是......