写大型C工程makefile构建~

news2025/1/14 18:34:03

629c33eaca92772b1cbae50443e4f604.gif

正文


最开始学习linux应用开发编写的时候,估计大部分伙伴们都是在一个目录里面编译整个工程,主要是linux通常没有非常合适的集成开发环境。

以前单目录的方式实在太过捡漏,在linux环境中进行C代码工程开发很多时候需要编写一个相对比较通用的makefile,一劳永逸,能自动查找并归类每个目录的文件进行编译。

可能很多朋友会选择一些cmake,scons等自动化构建工具,但也有部分伙计编写makefile也完全够用,嵌入式平台迭代速度不快的话基本上可以成为传承级代码,那么今天大致梳理了一下makefile中构建大型一点的工程需要用到的一些编译语法与函数。

1

常用的特殊变量

这些符号是Makefile中的特殊变量,用于在规则中引用文件名和目标,

  • $^ 用于表示所有的依赖文件列表,多个文件以空格分隔。在规则中,它可以用来引用所有依赖文件的列表。例如:

target: dependency1 dependency2 dependency3
    command $^

在这个例子中,$^ 将会展开为 dependency1 dependency2 dependency3

  • $@ 用于表示目标文件的名称。在规则中,它可以用来引用目标文件的名称。例如:

target: dependency1 dependency2 dependency3
    command $@

在这个例子中,$@ 将会展开为 target

  • $<用于表示规则中的第一个依赖文件。通常在单目标多源文件的情况下使用。例如:

target: dependency1 dependency2
    command $<

在这个例子中,$< 将会展开为 dependency1

  • $? 用于表示所有比目标文件新的依赖文件列表。通常在需要重新生成目标文件的情况下使用。例如:

target: dependency1 dependency2
    command $?

在这个例子中,如果 dependency1dependency2 新,则 $? 将会展开为 dependency1;如果 dependency2dependency1 新,则 $? 将会展开为 dependency2;如果两者都是相同的时间戳,则 $? 将为空。

  • $* 用于表示规则中目标文件的文件名部分(不包括扩展名)。通常在需要将目标文件名作为参数传递给命令时使用。例如:

%.o: %.c
    gcc -c $< -o $@
    ./process $*

在这个例子中,如果目标文件是 example.o,则 $* 将会展开为 example

除了上面提到的 $^$@$<$?$*,Makefile 中还有一些其他常用的特殊变量。

  • $(MAKE): 用于表示 make 命令的名称。这在递归调用 make 的时候非常有用。

  • $(CC): 用于表示 C 编译器的名称,默认情况下是 cc。你可以在 Makefile 中使用这个变量来指定编译器。

  • $(CFLAGS): 用于表示传递给编译器的参数。这个变量通常用于指定编译选项,比如警告选项、优化选项等。

  • $(LDFLAGS): 用于表示传递给链接器的参数。这个变量通常用于指定链接选项,比如库路径、库文件等。

  • $(RM): 用于表示删除文件的命令,默认情况下是 rm -f。你可以在 Makefile 中使用这个变量来指定删除文件的命令。

比如$(CFLAGS) 是一个在 Makefile 中常用的特殊变量,用于指定传递给编译器的参数,可以使用它来设置编译选项,比如警告选项、优化选项等。

通常是在 Makefile 中定义 $(CFLAGS) 变量,并在编译规则中使用。例如:

CC = gcc
CFLAGS = -Wall -O2

# 编译规则
%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

# 默认目标
all: program

# 目标程序
program: file1.o file2.o
    $(CC) $(CFLAGS) $^ -o $@

# 清理规则
clean:
    rm -f *.o program

在这个示例中,$(CFLAGS) 被设置为 -Wall -O2,表示编译器应该使用所有警告选项并进行优化。然后,在编译规则中,$(CFLAGS) 被用于传递给编译器。

这样做的好处是,如果你需要修改编译选项,只需修改 $(CFLAGS) 的值,而不必在每个编译规则中都修改。这样可以使得 Makefile 更加易于维护和管理。

包括前面的特殊变量都是可以使得Makefile更加灵活和易于维护,在规则中引用文件名和目标名,而不必重复键入。

2

$(wildcard pattern)

这个规则函数看起来比较唬人,wildcard pattern英文名字就是"wildcard" 这个单词的字面意思是"通配符",那么整体就是表示为通配符表示的文件名模式,

示例:

SRCS := $(wildcard *.c)

在这个例子中,$(wildcard *.c) 将匹配当前目录下所有以 .c 结尾的文件,并将符合条件的文件名列表赋值给变量 SRCS。

另一个示例:

FILES := $(wildcard src/*.c include/*.h)

这个示例相信是很多编写C程序的makefile中经常用到的,$(wildcard src/.c include/.h) 将匹配 src 目录下的所有 .c 文件和 include 目录下的所有 .h 文件,并将结果合并为一个文件列表赋值给变量 FILES。

3

$(patsubst pattern,replacement,text)

在 Makefile 中,$(patsubst pattern,replacement,text) 是一个用于模式替换的函数,将文本中符合指定模式的部分替换为指定的字符串。

这个函数通常用于对文件名或路径进行模式匹配和替换,非常适合在 Makefile 中进行文件名的转换操作。

$(patsubst pattern,replacement,text)

参数:

pattern:要匹配的模式,可以包含通配符 * 和 ?。

replacement:要替换成的字符串。

text:要进行模式替换的文本。

比如如下这个简单的例子:

SOURCES := file1.c file2.c file3.c

OBJECTS := $(patsubst %.c,%.o,$(SOURCES))

将会把 SOURCES 变量中以 .c 结尾的文件名替换为以 .o 结尾的文件名,最终将得到 OBJECTS 变量的赋值结果为 “file1.o file2.o file3.o”。

4

addprefix

Makefile 中,$(addprefix prefix,names…) 是一个函数,用于将指定的前缀添加到一组空格分隔的文件名中。

这个函数通常用于将相同的前缀添加到一组文件名或路径中,非常适合在 Makefile 中进行路径拼接操作。

语法:

$(addprefix prefix,names...)

参数:

prefix:要添加的前缀。

names…:一组空格分隔的文件名或路径。

示例:

SOURCES := file1.c file2.c file3.c

OBJS := $(addprefix obj/,$(SOURCES:.c=.o))

在这个例子将会在 SOURCES 变量中的每个文件名后面添加 obj/ 前缀,并将处理后的结果赋值给 OBJS 变量。最终得到的 OBJS 变量的值为 “obj/file1.o obj/file2.o obj/file3.o”。

5

notdir 

$(notdir names…) 是一个函数,用于获取一组文件名或路径中的文件名部分,并将其返回。

这个函数通常用于从给定的路径中提取文件名部分,非常适合在 Makefile 中进行文件处理操作。

语法:

$(notdir names...)

参数:

names…:一组空格分隔的文件名或路径。

示例:

SRCS := src/file1.c src/file2.c src/file3.c

OBJS := $(notdir $(SRCS))

$(notdir $(SRCS)) 将会从 SRCS 变量中的每个文件路径中提取文件名部分,并将处理后的结果赋值给 OBJS 变量,最终得到的 OBJS 变量的值为 “file1.c file2.c file3.c”。

6

foreach 

foreach是Makefile使用频率非常之高的函数,foreach 函数用于迭代处理一个以空格分隔的列表,并针对列表中的每个元素执行相同的操作。

这个函数通常用于循环处理一组变量或文件名,并执行相同的规则或命令。

语法:

$(foreach var, list, text)

参数:

var:用于表示当前列表中的每个元素的变量。

list:以空格分隔的列表。

text:要对列表中的每个元素执行的操作或命令。

示例:

FILES := file1.c file2.c file3.c

OBJS := $(foreach file, $(FILES), $(file:.c=.o))

$(foreach file, $(FILES), $(file:.c=.o)) 将会遍历 FILES 变量中的每个文件名,并将每个文件名的 .c 扩展名替换成 .o,最终得到 OBJS 变量的值为 “file1.o file2.o file3.o”。

7

最后总结 

好了,基本上使用上介绍这些函数能够解决大部分的文件查找和文件名替换工作,最终就是编译了,对于C的编译过程无非就是编译、链接、清除,就是不细说了。

其实makefile主要就是自动化构建,把我们的源文件、库文件加工处理,那么只要我们的源文件位置没有大变动、编译过程无特别的要求,那么通用化makefile模板做好以后,后续就只需要进行源文件位置的添加和编译选项额修改,跟用那么集成开发环境添加一个一个的路径是一样的。

最后

      好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个~

bug菌唯一、永久、免费分享嵌入式技术知识平台~

推荐专辑  点击蓝色字体即可跳转

☞  MCU进阶专辑 d3efae1b629fe0143db8199c0cdee9e4.gif

☞  嵌入式C语言进阶专辑 977c537b2645891900a52158cbeb21ca.gif

☞  “bug说”专辑 83db37f66dd764f6e5aa2914fb7bb9ae.gif

☞ 专辑|Linux应用程序编程大全

☞ 专辑|学点网络知识

☞ 专辑|手撕C语言

☞ 专辑|手撕C++语言

☞ 专辑|经验分享

☞ 专辑|电能控制技术

☞ 专辑 | 从单片机到Linux

023af59bd7513bd61cf0b8ce9b2b300a.gif

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

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

相关文章

android gradle8.3 发布插件踩过的坑

之前写过gradle6.x和gradle7.x的插件&#xff0c;会有一些改动&#xff0c;到8.x我发现又有一些变化&#xff0c;记录一下&#xff0c;防止后边再遇到相同的情况 下边是插件的gradle文件配置 plugins {id("java-gradle-plugin") //会自动引入java-library、gradleAp…

SwiftUI中Popover的使用(弹出方式,箭头位置,如何退出)

在iOS中&#xff0c;popover是出现在现有内容顶部的UI元素&#xff0c;通常用于在上下文中向用户呈现新视图。与其他占用整个屏幕的视图控制器不同&#xff0c;popover出现在一个较小的、集中的区域&#xff0c;从而使用户能够在必要时与popover外的应用程序的其他部分进行交互…

C#的web项目ASP.NET

添加实体类和控制器类 using System; using System.Collections.Generic; using System.Linq; using System.Web;namespace WebApplication1.Models {public class Company{public string companyCode { get; set; }public string companyName { get; set; }public string com…

国产飞腾/龙芯/瑞芯微芯片在信创行业应用:金融行业、教育行业、党政机关

党政机构 方案背景&#xff1a; 在国家提出信息技术应用创新发展战略的大环境下&#xff0c;政务大厅需要基于国家科技自主技术深入推进“互联网政务服务”。加快建设全国一体化在线政务服务平台&#xff0c;进一步落实创新驱动发展战略&#xff0c;提升政务网络安全保障能力…

智慧园区整理技术方案(ppt,软件全套建设方案)

智慧园区管控平台整体技术方案 1.平台概述 2.公共安全 3.物业管理 4.综合管理 5.企业服务 平台规划&#xff0c;整理技术架构搭建&#xff0c;统一门户&#xff0c;lot物联平台&#xff0c;视频云管理平台&#xff0c;GIS服务平台&#xff0c;服务器架构&#xff0c;统一身份认…

Ps:调整画笔工具

调整画笔工具 Adjustment Brush Tool可以将选区、创建蒙版和应用调整的传统工作流程合并为一个步骤&#xff0c;简化了对图像进行非破坏性局部调整的操作。 快捷键&#xff1a;B 调整画笔工具是 Photoshop 2024 年 5 月版&#xff08;25.9 版&#xff09;新增的工具。 ◆ ◆ …

JavaSE:SE知识整体总结

1、引言 历时一个多月的学习&#xff0c;已经掌握了JavaSE的知识&#xff0c;这篇博客就来做一下SE知识的总结~ 2、数据类型和变量 Java中的数据类型分为基本数据类型和引用数据类型。 2.1 基本数据类型 基本数据类型共有四类八种&#xff1a; 四类&#xff1a;整形、浮点…

遗留和现代数据库中的向量搜索

遗留和现代数据库中的向量搜索 image1 向量数据库是一种将数据&#xff08;包括文本、图像、音频和视频&#xff09;存储为向量的数据库&#xff0c;向量是高维空间中对象或概念的数学表示。 注意&#xff1a;根据数据的复杂程度和细节&#xff0c;每个向量的维数可能差别很大&…

SpringBoot的第二大核心AOP系统梳理

目录 1 事务管理 1.1 事务 1.2 Transactional注解 1.2.1 rollbackFor 1.2.2 propagation 2 AOP 基础 2.1 AOP入门 2.2 AOP核心概念 3. AOP进阶 3.1 通知类型 3.2 通知顺序 3.3 切入点表达式 execution切入点表达式 annotion注解 3.4 连接点 1 事务管理 1.1 事务…

面试杂谈k8s

其实看我之前的博客&#xff0c;k8s刚有点苗头的时候我就研究过&#xff0c;然后工作的时候间接接触 也自己玩过 但是用的不多就忘记了&#xff0c;正苦于不知道写什么&#xff0c;水一篇 用来面试应该是够了 支持云应用开发、运行与运维一体化的云应用平台软件应运而生 k8s核…

前端树形结构组件的设计与实现:以企查查、天眼查股权结构为例

摘要 随着信息化时代的不断发展&#xff0c;数据可视化在各行各业的应用越来越广泛。特别是在商业信息查询领域&#xff0c;如企查查、天眼查等平台&#xff0c;通过直观的数据展示方式&#xff0c;帮助用户快速理解复杂的商业关系。本文将以一个前端tree树形结构模版组件为例…

CompassArena 司南大模型测评--代码编写

测试角度 要说测试模型&#xff0c;对咱们程序员来说&#xff0c;那自然是写代码的能力强不强比较重要了。那么下面我们以 leetcode 中的一道表面上是困难题的题目来考考各家大模型&#xff0c;看看哪个才应该是咱们日常写程序的帮手。 部分模型回答 问题部分如下截图&#…

Day-04python模块

一、模块 1-1 Python 自带模块 Json模块 处理json数据 {"key":"value"} json不是字典 本质是一个有引号的字符串数据 json注意点 {} 中的数据是字符串引号必须是双引号 使用json模块可以实现将json转为字典&#xff0c;使用字典的方法操作数据 。 或者将…

HCIP-Datacom-ARST自选题库__MAC【14道题】

一、单选题 1.缺省情况下&#xff0c;以下哪种安全MAC地址类型在设备重启后表项会丢失? 黑洞MAC地址 Sticky MAC地址 安全动态MAC地址 安全静态MAC地址 2.华为交换机MAC地址表中的动态sticky MAC地址的默认老化时间是多少秒? 300 不会老化 400 500 3.华为交换机MA…

apache大数据各组件部署搭建(超级详细)

apache大数据数仓各组件部署搭建 第一章 环境准备 1. 机器规划 准备3台服务器用于集群部署,系统建议CentOS7+,2核8G内存 172.19.195.228 hadoop101 172.19.195.229 hadoop102 172.19.195.230 hadoop103 [root@hadoop101 ~]# cat /etc/redhat-release CentOS Linux rele…

揭秘APP广告变现项目

在当今移动应用市场&#xff0c;广告变现已经成为开发者盈利策略的重要组成部分。 通过在应用程序中展示多种类型的广告&#xff0c;如插页式广告、横幅广告和激励视频广告&#xff0c;开发者能够获得经济效益。 实现这一目标的核心在于平衡收入与用户体验&#xff0c;避免过…

【差分隐私联邦学习从入门到发文】

差分隐私联邦学习从入门到发文 差分隐私联邦学习从入门到发文一、学习相关理论1. 差分隐私理论解读2. 联邦学习相关收敛性分析3. 差分隐私经典论文解读4. 联邦学习代码解读5. 深度学习相关代码网站 二、必读论文三、最新进展2023 差分隐私联邦学习从入门到发文 这是关于差分隐…

虚拟现实环境下的远程教育和智能评估系统(五)

查阅相关VR眼动注意力联合教育学相关论文 1.Exploring Eye Gaze Visualization Techniques for Identifying Distracted Students in Educational VR&#xff08;IEEE VR 2020&#xff09; 摘要&#xff1a;我们提出了一种架构&#xff0c;使VR教学代理能够响应眼动追踪监控…

校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)

校园交友网站 目录 基于SprinBootvue的校园交友网站 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

2024年四川省三支一扶报名照片上传成功啦

2024年四川省三支一扶报名照片上传成功&#xff0c;一定要下载照片审核工具哦&#xff0c;详情如下图所示