[Linux_IMX6ULL应用开发]-Makefile

目录

Makefile的规则

Makefile的语法

通配符

假想目标

变量

Makefile的函数

foreach函数

filter和filter-out

wildcard

patsubst

修改头文件无法make解决

CFLAGS


Makefile的规则

当我们在使用gcc进行编译链接的时候,我们需要手动在shell窗口键入命令。比如说我们目前有两个c文件,想要对它们进行编译生成test可执行文件

gcc -o test a.c b.c

通过执行如上代码,我们可以生成一个test可执行文件

那么问题就来了,如果存在几千个文件同时需要进行编译链接的话,难道也需要这样一个个键入命令生成吗,所以,我们在嵌入式系统中,使用的是makefile进行批处理

同时,如上代码还有一个缺点,那就是如果修改了a.c文件,那么执行如上命令的时候,即使b.c文件没有动过,也会被重新编译一次,如果文件很多,这是很消耗时间的

Makefile的最核心的规则如下

基于这个核心规则,把如下的命令转化为makefile

gcc -o test a.c b.c
#test可执行文件依赖a.o b.o
test : a.o b.o
    gcc -o test a.o b.o

#a.o依赖a.c
a.o : a.c
    #编译生成a.o但是不链接
    gcc -c -o a.o a.c

#b.o依赖b.c
b.o : b.c
    #编译生成b.o但是不链接
    gcc -c -o b.o b.c

新建一个Makefile文件,然后键入如上内容,然后直接输入命令make就可以完成编译和链接了


Makefile的语法

通配符

原先通过a.o和b.o链接生成test可执行文件的makefile过于的繁琐,因为每有一个文件,都要在下方新添加一个编译规则

test : a.o b.o
        gcc -o $@ $^
%.o : %.c
        gcc -c -o $@ $<

假想目标

当我们需要通过makefile一键清除生成的文件和目标的时候,可以添加一个clean

test : a.o b.o
        gcc -o $@ $^
%.o : %.c
        gcc -c -o $@ $<
clean:
        rm *.o test

删除test可执行文件以及所有.o后缀的文件

由此可知,如果make没有带目标名,那么它是生成规则的第一个目标,比如说只键入make,那么它就是执行第一个目标,生成test文件,如果是make clean,那么就是执行clean处的操作

由于makefile执行的条件是,目标文件不存在或者依赖文件比目标文件新,如果存在如下情况,那么make clean就无法正常执行

创建了一个名为clean的文件,makefile会判断clean文件已经存在,并且没有依赖比目标文件新,则无法正常执行,此时如果有这种情况那么我们就需要使用假想目标

假想目标(有时也称为伪目标或标签)不代表一个真正的文件名。它更多的是作为一个目标集合或动作,用于在执行make命令时指定并执行其所在规则定义的命令。假想目标不生成文件,只是作为几个命令组成特殊规则的名称。可以理解为,假想目标只执行命令,不是用于生成文件

test : a.o b.o
        gcc -o $@ $^
%.o : %.c
        gcc -c -o $@ $<
clean:
        rm *.o test
.PHONY : clean

添加最后一行后,便可以正常执行make clean,即使存在clean文件


变量

:=         为即时变量,假如 A:= C ,那么A就是执行到这一句的时候C的值,后续不管C在怎么改变,A都不会因为C的改变而改变。它可以确保变量的值在赋值时就是确定的,并且在整个Makefile中保持不变,除非被重新赋值。

=        为延时变量,假如 A=C,那么直到结束,C不管改变多少次,C最终是多少A就是多少

?=      延时变量如果是第1次定义才起效,如果在前面该变量已定义则忽略这句

+=      附加


Makefile的函数

foreach函数

$(foreach var,list,text)

类似与for循环,把list中的字符串通过空格划分,然后执行text中的表达式,然后赋值给var,直到list结束

输出结果为a.o b.o c.o,分出的第一个字符为a,执行增加.o的操作,赋值给f,以此叠加直到list也就是A中无法在通过空格划分出字符

filter和filter-out

#在text中取出符合pattern的值
$(filter pattern...,text)

#在text中取出不符合pattern的值
$(filter-out pattern...,text)

示例如下

文件夹中存在如下不同格式的文件,如何筛选出只包含.c为后缀的文件呢

通过执行shell命令ls列举出所有文件,然后赋值给C,然后使用filter函数,在C变量中,把满足以c为后缀的变量赋值给D,就可以获得只以c为后缀的文件了

如果我们在这里使用的是filter-out函数,那就是排除以.c为后缀的文件,那么获得的就是

D = a.d b.d c.d d.d了 

wildcard

此函数可以从该文件夹目录中取出指定的文件的格式

#pattern定义了文件名格式

$(wildcard pattern)

执行的结果如下

patsubst

$(patsubst pattern,replacement,text)

把text中的所有满足pattern的内容替换为replacement的内容,其他的内容不会进行改变,除了满足的变量进行操作外,不满足的也不会被剔除

执行的结果如下


修改头文件无法make解决

当我们在使用makefile的时候,可能会存在如下的问题

假设我有如下三个文件,a.c b.c c.c ,c.c文件包含了c.h这个头文件,当我们make生成了可执行文件之后,我们修改头文件,然后打算重新编译的时候会被告知无法重新进行编译,因为,我们的makefile中没有文件依赖h文件生成

那么我们如何解决这个问题呢,这里就需要用到依赖文件,通过如下makefile,即使只是头文件被修改了,重新进行make编译也是可以编译的,因为这里我们使用了依赖文件,头文件被更改了,依赖文件也会被更改

OBJ = a.o b.o c.o
DEPEND_FILE:=$(patsubst %,.%.d,$(OBJ))
DEPEND_FILE:=$(wildcard $(DEPEND_FILE))

test : $(OBJ)
        gcc -o $@ $^
        @echo depend_file = $(DEPEND_FILE)

ifneq ($(DEPEND_FILE),)
include $(DEPEND_FILE)
endif


%.o : %.c
        gcc -c -o $@ $< -MD -MF .$@.d

clean_d:
        rm $(DEPEND_FILE)


clean:
        rm *.o test

总的来说,就是通过获取对应文件的依赖文件,并包含进makefile当中,只要包含进去,makefile会自动识别出当哪些头文件发生变化的时候,需要对哪些文件进行重新编译


CFLAGS

CFLAGS可以理解为一个宏,可以再上面添加各种的编译参数

一般来说,项目的文件夹是这样的结构

h文件是单独放在一个文件夹里面的,那么当我们在包含此头文件的时候,就不能使用""而是应该使用<>,那么,我们就要在编译参数里面指定头文件的路径

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大模型“说胡话”现象辨析

在人工智能快速发展的今天&#xff0c;大型深度学习模型已成为自然语言处理领域的核心力量。然而&#xff0c;随着这些模型规模的不断扩大和功能的日益增强&#xff0c;一种被称为“说胡话”的现象也愈发引人关注。这种现象不仅影响了模型在实际应用中的效果&#xff0c;也引发…

Linux入门-常见指令及权限理解

目录 1、Linux背景 1.1、发展历史 1.2、开源 1.3Linux企业应用现状 2、Linux下的基本命令 2.1、ls 指令 2.2、pwd 命令 2.3、cd 命令 2.4、touch命令 2.5、mkdir 命令 2.6、rmdir 指令和 rm指令 2.7 man 指令 2.8、cp指令 2.9、mv 指令 2.10 cat 2.11 more 2…

RocketMq 顺序消费、分区消息、延迟发送消息、Topic、tag分类 实战 (消费者) (三)

消费端配置 如下所示&#xff1a;是消费者的配置类&#xff0c;有以下几点需要注意的地方 1、是TargetMessageListener这个监听类&#xff08;下文会把这个监听类的具体代码贴出来&#xff09;&#xff0c;需要把这个监听类订阅。 2、rocketMqDcProperties.getTargetProperties…

MySQL 多表查询与事务的操作

一,多表联查 有些数据我们已经拆分成多个表,他们之间通过外键进行连接.当我们要查询两个表的数据,各取其中的一列或者多列. 这时候就需要使用多表联查. 数据准备: # 创建部门表 create table dept(id int primary key auto_increment,name varchar(20) ) insert into dept (n…

力扣---打家劫舍---动态规划

思路 1&#xff1a; 我将res[i]定义为&#xff1a;一定要取第 i 个房子的前提下&#xff0c;能获取的最大金额。那么直接用cnt从头记录到尾&#xff0c;每个房子的res最大值即是答案。那么递推公式是什么&#xff1f;res[i]max(res[i-2],res[i-1],...,res[0])nums[i]。数组初始…

cmake与交叉编译(x86 to arm)过程和问题全记录

一、背景 公司维护一批c动态库&#xff0c;由于生产需要&#xff0c;每次更新都要在windows、linux_x86、kylin_arm等多个环境中编译一遍&#xff0c;操作比较麻烦&#xff0c;所以想通过交叉编译的方式在一台机器上边编译多个环境的动态库&#xff0c;减少工作量。考虑到工作…

浅谈大模型“幻觉”问题

大模型的幻觉大概来源于算法对于数据处理的混乱&#xff0c;它不像人类一样可以by the book&#xff0c;它没有一个权威的对照数据源。 什么是大模型幻觉 大模型的幻觉&#xff08;Hallucination&#xff09;是指当人工智能模型生成的内容与提供的源内容不符或没有意义的现象。…

Linux——程序地址空间

我们先来看这样一段代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <stdlib.h>int g_val 0;int main() {pid_t id fork();if(id < 0){perror("fork");return 0;}else if(id 0){ //child,子进程肯定先跑完&#xff0c;也…

提升Java编程安全性-代码加密混淆工具的重要性和应用

在Java编程领域中&#xff0c;保护代码安全性和知识产权至关重要。本文旨在探讨代码加密混淆工具在提升代码安全性和保护知识产权方面的重要性。我们将介绍几款流行的Java代码加密混淆工具&#xff0c;如ProGuard、DexGuard、Jscrambler、DashO和ipaguard&#xff0c;并分析它们…

多线程(剩余部分)

Day29 多线程(剩余部分) 十二、线程的礼让 Thread.yield(); 理解&#xff1a;此方法为静态方法&#xff0c;此方法写在哪个线程中&#xff0c;哪个线程就礼让 注意&#xff1a;所谓的礼让是指当前线程退出CPU资源&#xff0c;并转到就绪状态&#xff0c;接着再抢 需求&#x…

浅谈一下对于DDD模式的理解3

浅谈一下对于DDD模式的理解&#xff0c;相互学习交流&#xff0c;不对之处欢迎大家指正。 在说到DDD(Domain-Driven Design)设计模式之前&#xff0c;先要说下我们在对系统进行架构设时需要遵循的几个原则&#xff1a; 单一职责&#xff08;SRP&#xff09; "单一职责原则…

直播预约丨《袋鼠云大数据实操指南》No.1:从理论到实践,离线开发全流程解析

近年来&#xff0c;新质生产力、数据要素及数据资产入表等新兴概念犹如一股强劲的浪潮&#xff0c;持续冲击并革新着企业数字化转型的观念视野&#xff0c;昭示着一个以数据为核心驱动力的新时代正稳步启幕。 面对这些引领经济转型的新兴概念&#xff0c;为了更好地服务于客户…

文献速递:基于SAM的医学图像分割---阶梯式微调方法,用于整合补充网络的自适应矩估计(SAM)

Title 题目 Ladder Fine-tuning approach for SAM integrating complementary network 阶梯式微调方法&#xff0c;用于整合补充网络的自适应矩估计&#xff08;SAM&#xff09; 01 文献速递介绍 医学图像分割在医疗保健中扮演着至关重要的角色。它旨在使用各种医学成像方式…

MS2574/2574T/2574S高速、四通道差动线路驱动器

品简述 MS2574/MS2574T/MS2574S 是一款高速、低功耗的四通道 差动线路驱动芯片&#xff0c;用于平衡或非平衡的数字数据传输。可 以满足 ANSI TIA/EIA-422-B 和 ITU &#xff08;原 CCITT &#xff09;建议 V.11 的要求。 三态输出可提供用于驱动双绞线或平行双线传输线路等…

公司购买阿里云服务器多少钱一年?199元2核4G5M配置

阿里云服务器ECS u1实例&#xff0c;2核4G&#xff0c;5M固定带宽&#xff0c;80G ESSD Entry盘优惠价格199元一年&#xff0c;性能很不错&#xff0c;CPU采用Intel Xeon Platinum可扩展处理器&#xff0c;购买限制条件为企业客户专享&#xff0c;实名认证信息是企业用户即可&a…

基于机器视觉的太阳能电池片异物遮挡检测含数据集

分享链接见文末 近年来&#xff0c;随着太阳能发电技术的快速发展&#xff0c;太阳能电池片的应用越来越广泛。然而&#xff0c;太阳能电池片在实际运行过程中常常会受到各种异物的遮挡&#xff0c;如树叶、灰尘等&#xff0c;导致发电效率下降甚至损坏设备。因此&#xff0c;…

python 基于 websocket 的简单将视频推流到网页

本来有一台设备是要搞成无线的形式的&#xff0c;设备的摄像头的数据可以在一台局域网连接的平板上查看&#xff0c;因为试着使用 RTMP 推流&#xff0c;感觉延时太大了&#xff0c;而 Webrtc 感觉有太麻烦了&#xff0c;所以一开始看到这篇文章使用 UDP 协议进行推流&#xff…

竞赛 - 基于机器视觉的图像拼接算法

前言 图像拼接在实际的应用场景很广&#xff0c;比如无人机航拍&#xff0c;遥感图像等等&#xff0c;图像拼接是进一步做图像理解基础步骤&#xff0c;拼接效果的好坏直接影响接下来的工作&#xff0c;所以一个好的图像拼接算法非常重要。 再举一个身边的例子吧&#xff0c;…

“比特币跌至8900美元”?逢低买入信号闪现!亚洲投资者需求正持续增长!

3月19日&#xff0c;美股三大指数集体收涨&#xff0c;美联储正在召开为期两天的货币政策会议&#xff0c;周三公布结果&#xff0c;市场普遍预计美联储将按兵不动。 然而&#xff0c;比特币近几日却面临显著的价格回调&#xff0c;昨早再次从6.7万美元水平快速下滑&#xff0c…

学习vue3第九节(新加指令 v-pre/v-once/v-memo/v-cloak )

1、v-pre 作用&#xff1a;防止编译器解析某个特定的元素及其内容&#xff0c;即v-pre 会跳过当前元素以及其子元素的vue语法解析&#xff0c;并将其保持原样输出&#xff1b; 用于&#xff1a;vue 中一些没有指令和插值表达式的节点的元素&#xff0c;使用 v-pre 可以提高 Vu…