本帖最后由 jf_50393217 于 2022-3-18 09:40 编辑 背景 自从21年接触了OpenHARMony后,就对GN+Ninja的构建系统特别感兴趣,然后自己尝试着做了一个简化版的构建系统。而本次比赛中,如果不考虑使用官方IDE的话,又不想用makefile(主要是不会写),所以还是尝试着用GN+Ninja完成了rt1062的构建系统。windows下未验证相关配置内容,理论上可以使用。 项目地址(已更新地址) (https://gitee.com/walker2048/rt1060_play) 本次比赛的内容都会在这个地址开源 源码目录结构说明
对于喜欢瞎折腾的人来说,没有使用自己最熟悉的目录和源码结构更开心的事儿了(**我的项目我做主,折腾不嫌事儿多**)。毕竟熟悉一个RTOS也是需要花费很多时间的。好在腾讯TinyOS的定位就是轻量化代码,简化代码功能和配置,能轻松的适应。如果大家不喜欢这样的目录结构,只需要自己修改对应的目录,并更新依赖配置即可。同时记得修改build/config/compiler/BUILD.gn文件中的 include_dirs字段内容,更新头文件目录就可以了。难度并不高。 GN + Ninja构建环境的优势 1. 代码依赖树清晰明了 2. GN语法容易看得懂 3. 构建脚本分工明确 4. 编译参数可见 5. 构建速度快 综上所述,GN + Ninja可以成为个人或者公司考虑新的构建系统时,一个非常优质的选择方案。 使用方法 1、 构建配置命令(使用export BOARD=TencentOS_tiny_EVB_AIoT命令先设定好BOARD环境变量,然后在bash环境下执行):
命令解析:若修改了构建脚本(如BUILD.gn文件),应先执行gn gen命令生成新的ninja构建文件,ninja才知道构建内容有变化了。一般不用和ninja命令拆分。out/${BOARD}为指定生成的编译构建配置目录, --args="product = "${BOARD}""为传递给gn的参数,告诉gn为product名称是${BOARD}环境变量配置相关参数(如查找真实的executable对象和相关依赖,以及编译参数)。 2、编译构建命令:
3、建议使用方式: 我比较懒,喜欢直接在~/.bashrc中配置好BOARD环境变量,并设置命令别名:
例如以上分别是gbuild命令,执行了构建配置命令(一般在几毫秒到几十毫秒级别)和编译构建命令(全新构建在11秒左右,增量编译不到1秒,比官方工具快多了);gdesc命令,用于获取编译配置相关的依赖树,编译参数等内容;gformat命令,用于格式化gn配置文件。 也许有朋友会问怎样清理编译产物,直接rm -rf out目录即可。 4、烧录命令: 烧录使用pyocd进行烧录,执行命令(可使用elf文件,hex文件进行烧录,两者都是带了地址的,不需要指定烧录地址)
5、添加源码 完成功能不可避免的需要修改源码,添加c源文件和.h头文件。我们先说一下添加c源文件,可以在组件目录添加c源文件,只需要在组件的BUILD.gn配置文件中修改sources字段内容即可。若需要新增组件,可以复制其他组件的BUILD.gn文件过来,修改组件名称,组件依赖(deps),源文件(sources)等内容即可。若需要添加.h头文件,分为两种情况。1、改文件仅在组件内使用,此时不需要定义头文件目录(按相对路径引用即可);2、若该头文件为组件对外接口定义文件,则需要在前面提到的build/config/compiler/BUILD.gn文件中的 修改include_dirs字段内容。 对于不想了解细节的同学,只需要关注前面的内容即可,有兴趣了解GN构建系统的,可以往下看。 ===================================================================== 接下来我们来说明一下GN构建配置文件和一些知识点。由于gn在国内项目应用的非常少,中文资料是少得可怜,想学习gn知识的,只能通过gn help命令和官网文档(基本也和help命令差不多),以及实际应用来学习。好在gn的配置文件是可读性比较高的,理解一些基本的知识点就可以用了。 GN的组件依赖 GN构建系统,它的依赖树根节点是executable类型的对象,然后在这个对象的依赖组件上,延伸至末端组件。例如本项目的依赖树展开为如下内容(可通过命令gn desc out/${BOARD} --args="product = "${BOARD}"" //hardware/board/${BOARD} deps --tree来获得,该命令的${BOARD}环境变量为TencentOS_tiny_EVB_AIoT)
例如第一行的//TinyOS:TinyOS,这是executable对象所引用的第一个依赖组件,它的路径是根目录下的TinyOS目录,在此目录下的BUILD.gn配置文件中,使用的是TinyOS同名的对象。下面的例子会说明GN的组件常见配置。 GN组件配置文件语法说明 举个例子,我们拿TinyOS组件的配置文件作为例子(文件路径为TinyOS/BUILD.gn)
在这个文件里,我们定义了一个名称为TinyOS的源代码集合对象,为什么要命名成跟文件夹名称一致的对象名称呢?这是GN其中一个规则:若上级指定依赖时,仅给出了路径,那默认的组件对象名称就是该路径最后的文件夹名称(隐式调用)。例如上面所示,TinyOS组件下依赖有三个组件,分别是arch路径的common组件和cortex-m7组件,以及kernel组件。这三个组件文件夹下,也有BUILD.gn配置文件,里面定义了组件名称和组件包含内容(若有依赖则添加deps依赖,无依赖则添加源码)。deps为本组件依赖的组件名称 # 末端组件配置语法说明 kernel组件下包含的源码定义如下(文件路径为TinyOS/kernel/BUILD.gn)。本文件中,组件名称与文件夹一致,上级依赖调用时不需要指定组件名称。若组件名称与文件夹名称不一致,则需指定组件名称。如本例中,source_set("kernel"),如果想定义成另一个组件名称(同目录有不同的组件,并且目录名称与组件名称不相符的情况下),可以改成source_set("kernel_name"),而上级组件调用时,应在目录后添加组件名称,比如"kernel:kernel_name",前面是依赖组件的相对目录,后面是组件名称(显式调用)。
如上所示,GN的组件依赖,相对传统makefile和cmake文件来说,更容易看懂,也更容易阅读和维护。从组件解耦来说,真正能做到所有的组件都能通过健康的依赖完成整个项目构建的(没有循环依赖和恶性依赖),功能解耦就做的不错了。 # 构建脚本分析
基本上只需要修改build目录就能完成编译参数的变更,对应功能也拆分得比较细,如果能详细做注释就更好了。因为我不是专业的工程师,有很多注释内容不准确,甚至错误也有可能。 以上就是本次分享的内容,gn的功能相对来说也会有点复杂,但是用习惯之后,就很舒服了。 |
只有小组成员才能发言,加入小组>>
2008个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36695 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
6183 浏览 1 评论
6400 浏览 1 评论
7028 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4432 浏览 0 评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
884浏览 2评论
995浏览 2评论
1157浏览 2评论
如何读取MPC5777C单片机中的pwm信号?有没有应用示例或代码示例?
502浏览 2评论
1598浏览 2评论