Makefile的学习之路

目录

1、简介

2、语法规则

3、变量

4、函数

5、伪目标.PHONY

6、嵌套执行makefile

7、makefile示例

 8、gcc编译选项

基本选项

调试选项

优化选项

警告选项

语言选项

链接选项

预处理选项

其他选项

1、简介

makefile是一个用于自动化构建程序的脚本文件,它包含一组规则,这些规则描述了如何从一个或多个源文件(如.c/.cpp文件)编译生成目标文件(如.o文件)再链接生成可执行文件(如.exe文件)或库(如.dll文件)。makefile的好处就是自动编译,只需一个make命令就能完成整个工程的编译。

gcc:可以简单的认为是编译器,它可以编译多种语言(如C、C++、Java等)。我们的程序中包含很多的源文件,都可以用gcc命令逐个编译,但当源文件太多时就容易混乱且工作量大,这时就需要批量处理,因此就有了make工具。

make:可以看成是一个智能的批处理工具,它没有编译和链接功能,而是通过执行makefile文件中用户指定的命令来完成编译和链接。

makefile:该文件中包含了调用gcc去编译某个源文件的命令。当工程非常大时,手写makefile也比较麻烦,因此就有了cmake工具辅助生成makefile文件。

cmake:也有自己的一套规则,它根据CMakeLists.txt文件更简单的生成makefile文件。

那有没有更简单的工具来生成CMakeLists.txt文件呢?

答:no,这就需要自己动手了。

2、语法规则

目标 ... : 依赖 ...命令1命令2. . .

目标:即要生成的文件,默认情况下makefile的第一个目标为终极目标;

依赖:即生成目标文件所需要的源文件;

命令:即通过执行命令由依赖文件生成目标文件,注意每条命令之前必须有一个tab;

all:makefile文件默认只生成第一个目标文件即完成编译,但我们可以通过all指定所需要生成的目标文件。

all: target1 target2 target3
target1:
# 编译规则1
target2:
# 编译规则2
target3:
# 编译规则3

3、变量

‘$’符号通常表示取变量的值,当变量名多于一个字符时,使用"( )";

‘$^’ 表示所有的依赖文件;

‘$@’ 表示生成的目标文件;

‘$<’ 表示第一个依赖文件;

‘:=’ 符号用于变量赋值(当前值);

‘=’ 符号用于变量赋值(整个makefile中最后被指定的值);

‘?=’ 符号表示如果该变量没有被赋值,则赋值等号后的值;

‘+=’ 符号表示将符号后面的值追加到前面的变量上;

4、函数

# 匹配当前目录下所有.c文件
SRC = $(wildcard *.c)# 将SRC中所有文件名中的.c替换成.o
OBJ = $(patsubst %.c, %.o, $(SRC))ALL: hello.outhello.out: $(OBJ)gcc $(OBJ) -o hello.out%.o: %.cgcc -c $< -o $@clean:rm -rf $(OBJ) hello.out.PHONY: clean ALL

wildcard:是make工具提供的一个函数,用于查找匹配模式的所有文件名;

patsubst:该函数用于匹配模式替换,基于一种模式替换文本字符串中另一部分;

5、伪目标.PHONY

为目标只是个标签,clean是个伪目标,没有依赖文件,只有make来调用时才执行;

6、嵌套执行makefile

在一些大工程中,会把不同模块的源文件放在不同目录中,我们可以在每个目录中都写一个makefile,这有利于让我们的makefile更简洁。列如在子目录subdir目录下有个Makefile文件,来指明这个目录下文件的编译规则。外部总控Makefile可以这样写

subsystem:cd subdir && $(MAKE)
其等价于:
subsystem:$(MAKE) -C subdir

如果需要传递变量到下级makefile中,可以这样写

export variable := value

如果不想传递变量到下级makefile中,可以这样写

unexport variable := value

7、makefile示例

假设有一个项目结构如下:

myproject/  
├── Makefile    # 主Makefile  
├── src/  
│   ├── main.c  
│   └── Makefile # src目录的Makefile  
└── include/  └── myheader.h

主makefile

# myproject/Makefile  # 设置编译器和编译选项  
CC=gcc  
CFLAGS=-Wall -Iinclude  # 定义子目录  
SUBDIRS=src  # 默认目标  
all: $(SUBDIRS)  # 伪目标,用于构建子目录  
.PHONY: $(SUBDIRS)  # 递归地调用子目录中的Makefile  
$(SUBDIRS):  $(MAKE) -C $@  # 清理目标,也递归地调用子目录中的清理目标  
clean:  for dir in $(SUBDIRS); do \  $(MAKE) -C 
$$
dir clean; \  done  # 安装目标(示例)  
install:  # 这里你可以添加安装命令,比如复制到某个目录  echo "Installing project..."  # 卸载目标(示例)  
uninstall:  # 这里你可以添加卸载命令,比如从某个目录删除文件  echo "Uninstalling project..."

 src目录下makefile

# myproject/src/Makefile  # 假设我们有一个名为main的目标文件  
OBJ=main.o  # 链接main.o生成可执行文件  
main: $(OBJ)  $(CC) $(CFLAGS) -o $@ $^  # 编译main.c生成main.o  
%.o: %.c  $(CC) $(CFLAGS) -c $< -o $@  # 清理目标  
clean:  rm -f $(OBJ) main  # 依赖项(如果需要)  
# DEPS = ...  
# ...(依赖项的处理)

 8、gcc编译选项

GCC(GNU Compiler Collection)提供了大量的编译选项,这些选项允许用户定制编译过程以满足不同的需求。以下是一些常用的GCC编译选项的概述:

基本选项

  • -c:只编译不链接,生成目标文件(.o)。
  • -o <output_file>:指定输出文件名。
  • -S:只进行编译预处理和汇编,生成汇编文件(.s)。
  • -E:只进行编译预处理,生成预处理后的文件(通常是.i文件,但默认输出到标准输出)。

调试选项

  • -g:生成调试信息,使调试器(如GDB)能够使用。
  • -ggdb:生成GDB可以使用的调试信息。
  • -g3:生成包含额外调试信息的调试信息。

优化选项

  • -O0:不进行优化(默认)。
  • -O1:进行基本优化。
  • -O2:进行更多的优化,但不增加编译时间太多。
  • -O3:进行更多的优化,可能会增加编译时间。
  • -Os:优化生成代码的大小。
  • -Ofast:进行所有可能的优化,包括那些可能改变程序行为的优化(如浮点运算的舍入模式)。

警告选项

  • -Wall:显示所有警告信息。
  • -Wextra:显示额外的警告信息。
  • -Werror:将警告信息当作错误处理。
  • -Wno-<warning>:禁用指定的警告(例如,-Wno-unused-variable禁用未使用变量的警告)。

语言选项

  • -std=<standard>:指定C或C++语言标准(如-std=c99-std=c++11)。
  • -fPIC:生成位置无关代码(Position Independent Code),常用于共享库。
  • -fPIE:生成位置无关的可执行文件。

链接选项

  • -L<directory>:添加库文件的搜索目录。
  • -l<library>:链接指定的库(如-lm链接数学库)。
  • -static:静态链接库(而不是默认的动态链接)。
  • -shared:生成共享库(动态链接库)。

预处理选项

  • -I<directory>:添加头文件搜索目录。
  • -D<macro>:定义宏(如-DDEBUG)。
  • -U<macro>:取消定义宏。

其他选项

  • -v:显示详细的编译和链接过程。
  • -version:显示GCC版本信息。
  • -M:生成依赖关系(通常是预处理器的依赖关系),但不编译。
  • -MM:与-M类似,但忽略系统头文件。
  • -MP:生成phony目标,以便在头文件更改时重新编译。
  • -MT:指定目标名称,通常与-M-MM一起使用。

这只是一个GCC编译选项的简要概述,GCC还提供了许多其他选项和功能。要获取完整的选项列表和详细信息,请查阅GCC的官方文档或使用gcc --help命令。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

轮式机器人Swiss-Mile城市机动性大提升:强化学习引领未来城市物流

喜好儿小斥候消息&#xff0c;苏黎世联邦理工学院的研究团队成功开发了一款革命性的机器人控制系统&#xff0c;该系统采用强化学习技术&#xff0c;使轮式四足机器人在城市环境中的机动性和速度得到了显著提升。 喜好儿网 这款专为轮腿四足动物设计的控制系统&#xff0c;能…

k8s 证书更新

如何使用脚本更新Kubernetes集群证书 引言 Kubernetes集群中&#xff0c;由kubeadm初始化的证书有效期默认为一年。当这些证书接近或已经超过有效期时&#xff0c;它们必须被更新以保证集群的正常运作。本文将介绍如何使用特定脚本来更新这些证书&#xff0c;将它们的有效期延…

机械臂抓取物体整体的开发流程

开发一个机械臂抓取物体的系统涉及多个步骤和不同领域的知识&#xff0c;包括机械设计、控制系统、传感器集成、软件开发等。以下是一个全面的开发流程概述&#xff1a; 1. 需求分析与系统设计 需求分析&#xff1a; 明确机械臂需要抓取的物体类型&#xff08;大小、重量、材…

【redis过期删除】

redis过期删除 redis的键可以设置过期时间&#xff0c;但是并不是每个键一到过期时间就会立即删除&#xff0c;redis不可能给每个设置过期时间的key上添加一个定时器来监视是否过期&#xff0c;CPU根本承受不了如此多的定时线程 注意&#xff1a;我使用的版本是6.0.10&#xf…

618必抢清单:内存升级国货更强,DDR5劲爆大白菜

随着数字时代的加速发展&#xff0c;平时在PC上玩游戏、办公的时候&#xff0c;电脑性能对我们的影响越来越打。相比于CPU、显卡等硬件&#xff0c;内存对于电脑性能的重要性也很高&#xff0c;而且可以通过更低的成本来升级。内存就像是电脑的神经网络&#xff0c;影响着CPU数…

linux中unattended-upgr是什么,如何关闭

unattended-upgrades 是 Ubuntu 操作系统自动更新软件包的一个进程。它默认开启&#xff0c;定期检查可用更新并自动升级。 要关闭 unattended-upgrades 进程&#xff0c;您可以执行以下步骤&#xff1a; 进入命令窗口。 输入以下命令并运行&#xff1a; sudo systemctl st…

超强生图模型,抢先体验!

文生图模型Stable Diffusion 3 Medium开源啦&#xff01;优刻得GPU云主机目前已上线该模型镜像&#xff0c;开箱即用&#xff0c;即刻体验&#xff01;具体操作见文末。 近年来&#xff0c;生成式人工智能的快速发展正在改变我们的生活。作为这一领域的前沿技术之一&#xff0…

成都跃享未来教育咨询解锁新篇章

在快节奏的现代社会中&#xff0c;每个人都在追求着属于自己的非凡人生。而成都跃享未来教育咨询&#xff0c;正是那个能够智慧引领你走向成功、成就非凡人生的灯塔。 跃享未来教育咨询&#xff0c;位于历史悠久的文化名城成都&#xff0c;这里不仅有丰富的文化底蕴&#xff0c…

Score Matching(得分匹配)

Score Matching&#xff08;得分匹配&#xff09;是一种统计学习方法&#xff0c;用于估计概率密度函数的梯度&#xff08;即得分函数&#xff09;&#xff0c;而无需知道密度函数的归一化常数。这种方法由Hyvrinen在2005年提出&#xff0c;主要用于无监督学习&#xff0c;特别…

python-03

使用File操作文件 open(file, moder, buffering-1,encodingNone, errorsNone, newlineNone, closefdTrue, openerNone) file&#xff1a;要打开的文件 mode&#xff1a;文件打开模式。默认访问模式是读&#xff08;r&#xff09; buffering&#xff1a;缓冲区大小 encodin…

【proteus仿真】基于51单片机的电压检测系统

【proteus仿真】基于51单片机的电压检测系统 资料下载地址&#xff1a;关注公众号 小邵爱电子 获取 1.前言 使用51单片机和ADC模块设计一个数字电压表&#xff0c;将模拟信号0~5V之间的电压转换为数字量信号&#xff0c;并通过LED实时显示电压数据 、 2.仿真原理图 3.硬件…

java的深拷贝和浅拷贝

总结&#xff1a; 深拷贝&#xff1a;无论是基本类型还是引用类型都会创建新的实例。 浅拷贝&#xff1a;对于基本类型就是复制其值&#xff0c;对于引用类型则是复制了指向这些数据类型的内存地址。 浅拷贝&#xff08;Shallow Copy&#xff09; 浅拷贝是指在创建新对象时&am…

AI写代码,CS还有前途吗?加州大学伯克利分校:CDSS申请人数激增48%!

目录 01 CS入学人数暴涨 02 人类Coder可堪大任 03 AI还没有学会创新 04 编程与农耕不同 AI写了这么多代码&#xff0c;你还应该学习计算机科学吗&#xff1f; 新的数据显示&#xff0c;学生们仍然热衷于选修计算机科学&#xff1a;加州大学伯克利分校&#xff08;UCB&#…

低代码组件扩展方案在复杂业务场景下的设计与实践

组件是爱速搭的前端页面可视化模块的核心能力之一&#xff0c;它将前端研发人员从无休止的页面样式微调和分辨率兼容工作中解放了出来。 目前&#xff0c;爱速搭通过内置的上百种功能组件&#xff08;120&#xff09;&#xff0c;基本可以覆盖大部分中后台页面的可视化设计场景…

如何安全进行亚马逊、沃尔玛测评?

在亚马逊、沃尔玛、速卖通、阿里国际站等电商平台上&#xff0c;测评已成为一种高效的推广手段&#xff0c;但伴随的风险也不容忽视。这些风险主要源于平台严格的大数据风控机制&#xff0c;它涵盖了多个方面&#xff0c;以确保评价的真实性和合规性。 首先&#xff0c;硬件参数…

如何以银行客户为中心实现自动化,并创造更顺畅的客户体验?

在当今社会&#xff0c;客户已习惯于通过几次点击就能迅速得到所需&#xff0c;但银行业的客户旅程仍然因为延误、错误、隐藏费用和资金可获取性问题而显得繁琐。试问&#xff0c;您上一次向他人推荐自己的银行、保险公司或税务局提供的优质服务是何时&#xff1f; 无论是购车…

EXCEL数据导入HIVE

引言 本文将论述如何将Windows本地的excel表数据,导入到虚拟机Linux系统中的Hadoop生态中的Hive数据仓库中。 实验准备 DBeaver Hive3.1(Hadoop3.1) excel数据表 实验步骤 一、首先打开虚拟机,启动Hadoop,启动hive,启动hiveserver2,连接DBeaver,成功连接展示如下…

游戏类APP选对开发框架很重要,Uni-app和Cocos Creator如何选?

开发游戏app&#xff0c;选择使用Uniapp和Cocos Creator这两种不同的技术平台开发时&#xff0c;需要考虑和比较这两者间的区别和差距。 Unity被公认为3D游戏开发的首选&#xff0c;它拥有成熟的3D开发工具和海量资源。华服巨作《王者荣耀》就是基于Unity引擎打造。而Cocos作为…

详解 HBase 的常用 API

一、环境准备 创建一个 Maven 工程并引入依赖 <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>1.3.1</version> </dependency> <dependency><groupId>org.apach…

详细描述拍立淘接口的实现过程,包括接口设计、开发、测试、部署等关键步骤

拍立淘接口的实现过程可以详细分为以下几个步骤&#xff1a; 注册与权限获取&#xff1a; 注册成为阿里巴巴开放平台开发者&#xff0c;并创建应用。获取API的调用权限和密钥&#xff08;如AppKey和AppSecret&#xff09;&#xff0c;这些密钥将用于后续的身份验证和请求签名。…