新用户注册入口 老用户登录入口

[转载]Contiki 2.7 Makefile 文件(五)

文章作者:转载 更新时间:2023-03-28 09:49:23 阅读数量:281
文章标签:oname函数自定义函数APPS变量
本文摘要:本文详细介绍了Makefile中自定义函数`oname`的实现原理,该函数利用`patsubst`内置函数将源文件(.c和.s)转换为目标文件(.o)。同时,文章说明了如何通过自定义变量`CONTIKI_OBJECTFILES`和`PROJECT_OBJECTFILES`管理目标文件集合,并添加路径前缀。在处理目录依赖关系链时,Makefile会自动创建如`obj_native`这样的目标目录。针对APPS变量,文章阐述了其应用原理,利用`wildcard`与`foreach`函数结合遍历指定目录下符合应用程序名称的源文件和Makefile文件,最终将这些源文件添加到`CONTIKI_SOURCEFILES`中以供编译。通过这一系列操作,实现了对项目构建过程中源文件、目标文件以及相关依赖关系的有效管理和自动化处理。
转载文章

本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_34399060/article/details/94095820。

该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。

作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。

如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。

4、第四部分

 (1)

oname = ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)} }

自定义函数$(1)表示调用oname这个函数的第一个参数,patsubst是make内置函数,即模式字符串替换函数。

oname函数实现的功能是:

  将第一个参数中符合%.s模式的替换成%.o

  再继续将上述结果中符合%.c模式的替换成%.o

  也就是把所有 .s 和 .c文件名替换成 .o文件名

  这个函数的功能就是计算源文件名(c源文件,汇编源文件)所相对应的目标文件名(经过编译汇编后的文件)。

 

CONTIKI_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CONTIKI_SOURCEFILES)} }PROJECT_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(PROJECT_SOURCEFILES)} }

定义CONTIKI_OBJECTFILES变量

  首先用oname函数,将CONTIKI_SOURCEFILES所对应的源文件名,改为目标文件名,如process.c将会变为process.o

  再在文件名前边加上前缀$(OBJECTDIR)/,前边我们知道这个变量为obj_native,故process.c会变为obj_native/process.o

  这个变量应该是代表即将生成的Contiki操作系统目标文件名

 

定义PROJECT_OBJECTFILES变量

  功能同上

  这个变量应该是代表即将生成的项目中目标文件名

  PROJECT_SOURCEFILES这个变量为空,所以PROJECT_OBJECTFILES也为空。

 

# Provide way to create $(OBJECTDIR) if it has been removed by make clean
$(OBJECTDIR):mkdir $@

$@是自动化变量,表示规则中的目标文件集。我们知道OBJECTDIR为obj_native,所以$@为obj_native。

mkdir $@生成obj_native目录。

但是这个依赖关系链,怎么会涉及到obj_native的?

调试了一下:

在生成CONTIKI_OBJECTFILES所代表的文件时,目录不存在,会先找依赖关系生成目录,再生成具体文件。

所以mkdir obj_native会被执行。

 (2)

ifdef APPSAPPDS = ${wildcard ${foreach DIR, $(APPDIRS), ${addprefix $(DIR)/, $(APPS)} }} \${wildcard ${addprefix $(CONTIKI)/apps/, $(APPS)} \${addprefix $(CONTIKI)/platform/$(TARGET)/apps/, $(APPS)} \$(APPS)}APPINCLUDES = ${foreach APP, $(APPS), ${wildcard ${foreach DIR, $(APPDS), $(DIR)/Makefile.$(APP)} }}-include $(APPINCLUDES)APP_SOURCES = ${foreach APP, $(APPS), $($(APP)_src)}DSC_SOURCES = ${foreach APP, $(APPS), $($(APP)_dsc)}CONTIKI_SOURCEFILES += $(APP_SOURCES) $(DSC_SOURCES)
endif

 The project's makefile can also define in the APPS variable a list of applications from the apps/ directory that should be included in the Contiki system.

hello-world这个例子没有定义APPS变量,故这段不会执行。

我们假设定义了APPS变量,其值为APPS += antelope unit-test

 

相关知识点:

wildcard函数: 返回所有符合pattern的文件名,以空格隔开

$(wildcard pattern)

The argument pattern is a file name pattern, typically containing wildcard
characters (as in shell file name patterns). The result of wildcard is a
space-separated list of the names of existing files that match the pattern.

 

foreach函数:

The syntax of the foreach function is:
$(foreach var,list,text)
The first two arguments, var and list, are expanded before anything else is done; note that
the last argument, text, is not expanded at the same time. Then for each word of the
expanded value of list, the variable named by the expanded value of var is set to that word,
and text is expanded. Presumably text contains references to that variable, so its expansion
will be different each time.
The result is that text is expanded as many times as there are whitespace-separated
words in list. The multiple expansions of text are concatenated, with spaces between them,
to make the result of foreach.

每次从list中取出一个词(空格分隔),赋给var变量,然后text(一般有var变量)被拓展开来。

只要list中还有空格分隔符就会一直循环下去,每一次text返回的结果都会以空格分隔开。

 

${wildcard ${foreach DIR, $(APPDIRS), ${addprefix $(DIR)/, $(APPS)} }}

先分析${foreach DIR, $(APPDIRS), ${addprefix $(DIR)/, $(APPS)} }

其中DIR是变量(var)$(APPDIRS)列表(list),这个例子中没有定义APPDIRS这个变量,估计是用于定义除了$CONTIKI/apps/之外的apps目录。

${addprefix $(DIR)/, $(APPS)}是text。我们假设定义了APPDIRS为a b。

那么第一次:DIR 会被赋值为a,${addprefix $(DIR)/, $(APPS)},又我们假定APPS为antelope unit-test,所以最终会被拓展为a/antelope  a/unit-test。

     DIR 会被赋值为b,${addprefix $(DIR)/, $(APPS)}又我们假定APPS为antelope unit-test所以最终会被拓展为b/antelope  b/unit-test

最终这两次结果会以空格分隔开,即a/antelope  a/unit-test b/antelope  b/unit-test

${wildcard a/antelope  a/unit-test b/antelope  b/unit-test} 返回空,因为找不到符合这样的目录。

所以最终这句语句,实现的功能是,返回$APPDIRS目录中,所有符合$APPS的目录。

 

${wildcard ${addprefix $(CONTIKI)/apps/, $(APPS)}

这句语句返回$(CONTIKI)/apps/目录下所有符合$APPS的目录,即contiki-release-2-7/apps/antelope contiki-release-2-7/apps/unit-test

 

${addprefix $(CONTIKI)/platform/$(TARGET)/apps/, $(APPS)}

这句语句返回$(CONTIKI)/platform/$(TARGET)/apps/目录下所有$APPS的目录,即contiki-release-2-7/platform/native/apps/antelope contiki-release-2-7/platform/native/apps/unit-test。

在contiki-release-2-7/platform/native目录下,并没有apps目录,后边有差错处理机制

 

$(APPS)

在当前目录下的所有$APPS目录,即antelope unit-test。

在hello-world例子中,并没有这些目录。

 

所以APPDS变量是包含所有与$APPS有关的目录。

 

APPINCLUDES变量是所有需要导入的APP Makefile文件。

在所有APPDS目录下,所有Makefile.$(APPS)文件。

 

在我们的假设条件APPS = antelope unit-testAPPDIRS =

只会导入contiki-release-2-7/apps/antelope/Makefile.antelope contiki-release-2-7/apps/unit-test/Makefile.unit-test

其余的均不存在,所以在include指令前要有符号-,即出错继续执行后续指令。

 

contiki-release-2-7/apps/antelope/Makefile.antelope

分别定义了两个变量,antelope_src用于保存antelope这个app的src文件,antelope_dsc用于保存antelope这个app的dsc文件。

 

contiki-release-2-7/apps/unit-test/Makefile.unit-test

分别定义了两个变量,unit-test_src用于保存unit-test这个app的src文件,unit-tes_dsc用于保存unit-test这个app的dsc文件。

 

变量APP_SOURCES

  APP_SOURCES = ${foreach APP, $(APPS), $($(APP)_src)}

取出所有APPS中的src文件变量,这个例子是$(antelope_src) 和$(unit-test_src)

 

变量APP_SOURCES

  DSC_SOURCES = ${foreach APP, $(APPS), $($(APP)_dsc)}

取出所有APPS中的dsc文件变量,这个例子是$(antelope_dsc) 和$(unit-test_dsc)

 

  CONTIKI_SOURCEFILES += $(APP_SOURCES) $(DSC_SOURCES)

这段话的最终目的:

将$APPS相关的所有源文件添加进CONTIKI_SOURCEFILES变量中。

(3)

target_makefile := $(wildcard $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET) ${foreach TDIR, $(TARGETDIRS), $(TDIR)/$(TARGET)/Makefile.$(TARGET)})# Check if the target makefile exists, and create the object directory if necessary.
ifeq ($(strip $(target_makefile)),)${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
elseifneq (1, ${words $(target_makefile)})${error More than one TARGET Makefile found: $(target_makefile)}endifinclude $(target_makefile)
endif

这断代码主要做的就是,找到在所有TAGET目录下找到符合的Makefile.$(TARGET)文件,放到target_makefile变量中。

再检查是否存在或者重复。并做相应的错误提示信息。

${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}

${error More than one TARGET Makefile found: $(target_makefile)}

 

我们这个例子中 TARGET = native 并且 TARGETDIRS为空

所以最后会导入$(CONTIKI)/platform/native/Makefile.native

 

接下去要开始分析target和cpu的makefile文件了。

 

转载于:https://www.cnblogs.com/songdechiu/p/6012718.html

本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_34399060/article/details/94095820。

该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。

作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。

如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。

相关阅读
文章标题:[转载][洛谷P1082]同余方程

更新时间:2023-02-18
[转载][洛谷P1082]同余方程
文章标题:[转载]webpack优化之HappyPack实战

更新时间:2023-08-07
[转载]webpack优化之HappyPack实战
文章标题:[转载]oracle 同时更新多表,在Oracle数据库中同时更新两张表的简单方法

更新时间:2023-09-10
[转载]oracle 同时更新多表,在Oracle数据库中同时更新两张表的简单方法
文章标题:[转载][Unity] 包括场景互动与射击要素的俯视角闯关游戏Demo

更新时间:2024-03-11
[转载][Unity] 包括场景互动与射击要素的俯视角闯关游戏Demo
文章标题:[转载]程序员也分三六九等?等级差异,一个看不起一个!

更新时间:2024-05-10
[转载]程序员也分三六九等?等级差异,一个看不起一个!
文章标题:[转载]海贼王 动漫 全集目录 分章节 精彩打斗剧集

更新时间:2024-01-12
[转载]海贼王 动漫 全集目录 分章节 精彩打斗剧集
名词解释
作为当前文章的名词解释,仅对当前文章有效。
patsubst函数patsubst是Makefile中的一个内置函数,用于模式匹配和替换。在文章中,patsubst函数接收两个参数,第一个参数为模式字符串(包含%通配符),第二个参数为目标模式。当对文件名列表应用此函数时,它会查找与模式字符串相匹配的元素,并将匹配部分按照目标模式进行替换。例如,在文中提到的oname函数中,通过两次调用patsubst函数,实现了将源文件名(如.c和.S)的扩展名替换为.o,从而生成对应的目标文件名。
自动化变量($@)在Makefile中,自动化变量是在规则执行过程中根据上下文自动设置的特殊变量。其中$@代表当前规则的目标文件集,即正在构建或更新的目标文件名。在文章描述中,当定义OBJECTDIR依赖关系链时,使用了自动化变量$@来表示目标目录obj_native,当make执行到这一规则时,会根据这个变量的值创建对应的目录。
APPS变量在项目构建和管理中,APPS变量是一个用户自定义的变量,用来存储需要包含在Contiki系统中的应用程序列表。在文章中,假设APPS变量被赋值为antelope unit-test,那么在编译过程中,会根据这个变量的值去查找并包含指定目录下相应名称的源文件和Makefile文件。通过wildcard和foreach函数结合,可以遍历多个预定义的目录路径,找到所有与APPS变量中列出的应用程序相关的源代码和配置文件,并将它们添加到CONTIKI_SOURCEFILES变量中,以便后续进行编译链接操作。
延伸阅读
作为当前文章的延伸阅读,仅对当前文章有效。
在阅读了上述关于Makefile中自定义函数、变量以及源文件与目标文件转换机制的深入解析后,您可能对自动化构建工具和工程管理有了更深层次的理解。实际上,这种技术在现代软件开发中的应用非常广泛,特别是在持续集成/持续部署(CI/CD)流程中扮演着至关重要的角色。
近日,GitHub推出了Actions Workflows YAML语法的重大更新,其中就包含了对多步骤构建过程中的依赖关系处理和自定义函数式编程的支持,这与Makefile的工作原理有异曲同工之妙。通过灵活定义构建规则,开发者能够实现从源代码到最终可执行文件或部署包的自动化编译和打包,极大地提高了工作效率和代码质量。
此外,对于大型项目如Linux内核的构建,其Kbuild系统就是一种高度复杂且高效的Makefile集,它利用类似的模式替换函数处理成千上万的源文件,并实现了模块化编译,这对于深入理解Makefile的应用场景具有很高的参考价值。
进一步了解,可以关注以下资源:
1. "GitHub Actions: Extending Workflows with Custom Runners and Functions" - 这篇文章详细解读了如何在GitHub Actions中创建自定义工作流并利用其功能实现复杂的构建逻辑。
2. "An In-depth Look at the Linux Kernel Build System (Kbuild)" - 这篇深度分析文章揭示了Linux内核编译系统的设计理念和实现细节,包括其对Makefile强大特性的运用。
3. "Modern C++ Project Automation with Makefiles" - 该教程结合现代C++项目实践,展示了如何与时俱进地使用Makefile进行项目自动化构建,同时探讨了与其他构建工具如CMake、Meson等的对比和融合。
通过延伸阅读以上内容,您可以更好地将理论知识应用于实际项目开发,优化构建过程,提高项目的可维护性和迭代速度。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
grep -ir "search_text" . - 在当前目录及其子目录中递归搜索文本。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
HessianRPC在高负载下服务降级与熔断器模式保障用户体验 05-01 jQuery和TweenMax简单实用的水平手风琴特效 01-20 jquery选择国家下拉列表框插件 01-21 Sqoop在Hadoop集群中的数据传输机制及数据库迁移、收集与备份恢复应用实践 12-23 简约渔具批发牧渔企业类网站前端模板下载 11-09 基于bootstrap功能齐全的jQuery进度条插件 10-20 简约大气男性护肤产品HTML5网站模板 09-22 宽屏大气机械设备制造公司网站模板 08-13 演讲会门票销售网站模板下载 07-30 本次刷新还10个文章未展示,点击 更多查看。
经典响应式投资理财企业前端模板 06-26 基于Redis的键值对存储实现用户阅读状态跟踪与管理 06-24 Netty框架中CannotFindServerSelection异常:服务器地址配置错误与通道类型匹配详解 06-18 简洁设计公司响应式网站模板下载 05-06 绿色苗木草坪种植绿化类企业前端CMS模板下载 04-30 怎么在cmd开启mysql服务 04-15 保洁公司家庭保洁服务网站模板 03-26 SpringCloud微服务中分布式锁的死锁问题与状态一致性维护:避免循环依赖、公平锁及超时重试机制在Redisson中的实践运用 03-19 HBase性能测试与RegionServer配置、架构及数据模型调优实践:关注响应时间、并发处理能力与BlockCache优化 03-14 jquery控制radio触发事件 02-15 简约HTML5软件营销业务公司网站模板 02-09
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"