(四) openwrt单个ipk编译过程
Tags : Makefile
本周是成胖子每周一博的第五周.
更好的阅读体验,请点击这里
前言
前一篇博客中,我们已经知道整个openwrt的编译顺序,本文我们来探讨与开发者息息相关的单个ipk的编译过程.在开发者进行二次开发的时候,我们既可以单个编译ipk也可以完整编译整个镜像文件.在完整编译的时候,我们选中的单个ipk同样会被编入镜像文件中,所以完整编译同样会进行单个ipk包的编译.
我们前面在stampfile函数部分提高过,当编译目标为package/stamp-compile的时候,实际执行的目标为package/compile;同时根据subdir函数的定义,package/compile将会依赖于package文件夹下被make menuconfig选中的子文件夹的compile.简而言之,当我们执行make package/compile相当于对所有选中的文件夹执行make package/XXX/compile.
ipk Makefile分析
我们以一个具体的包的编译过程来看看,本文我们以package/network/services/dropbear这个包为例.当我们在命令行中输入make package/network/services/dropbear/compile的时候,make将会读入dropbear下的Makefile文件,同时目标指定为compile.[1]
因为空间问题,我在这里不展开具体的Makefile文件.相信能看这篇博客的同学应该都有源码,自己打开便是.
下面我们根据GNU make语法来分析这个Makefile文件.它包含了两个.mk文件:一个是rules.mk,另一个是package.mk.
- rules.mk
- 这个文件我们前文已经提到过了,主要是大量变量的定义.包括各种路径的定义,编译器的定义等等.其中要说明的是.config文件也是这里被包含进来的.
- package.mk
- 这个文件首先定义和补充了一些变量.其次是openwrt为我们封装了BuildPackage函数,对于普通开发者而言,只需要参照模板定义相应的变量,最后调用这个函数即可.
其余的我们可以认为是变量的赋值语句,很明显使用它们的地方并不在这里.关于模板和变量值的说明及作用.,你可以参照官方说明,也可以在网上找到一大堆资料.
最后,最重要的语句是这一句:
$(eval $(call BuildPackage,dropbear))
这里将会把dropbear作为参数值传给函数BuildPackage
- Tips
- 不知道大家还记得我们Makefile的执行顺序么?Makefile是先读入所有信息,展开,然后生成依赖关系.最后再按依赖关系先后来执行.
依赖关系
BuildPackage分析
BuildPackage的定义在package.mk中,定义如下:
define BuildPackage
$(Build/IncludeOverlay)
$(eval $(Package/Default))
$(eval $(Package/$(1)))
ifdef DESCRIPTION
$$(error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description)
endif
ifndef Package/$(1)/description
define Package/$(1)/description
$(TITLE)
endef
endif
BUILD_PACKAGES += $(1)
$(STAMP_PREPARED): $$(if $(QUILT)$(DUMP),,$(call find_library_dependencies,$(DEPENDS)))
$(foreach FIELD, TITLE CATEGORY SECTION VERSION,
ifeq ($($(FIELD)),)
$$(error Package/$(1) is missing the $(FIELD) field)
endif
)
$(if $(DUMP), \
$(Dumpinfo/Package), \
$(foreach target, \
$(if $(Package/$(1)/targets),$(Package/$(1)/targets), \
$(if $(PKG_TARGETS),$(PKG_TARGETS), ipkg) \
), $(BuildTarget/$(target)) \
) \
)
$(if $(PKG_HOST_ONLY)$(DUMP),,$(call Build/DefaultTargets,$(1)))
endef
那么这里的$(1)就是指的传入的参数dropbear.这里包含了一些检查和补充变量定义.继续深究下去的线索是第25~32行之间.这里我将它简化后就是展开BuildTarget/ipkg;同时第33行,将dropbear当作参数传给函数Build/DefaultTargets.
BuildTarget/ipkg定义在package-ipkg.mk中,我们需要重点关注其中的冒号,这个形成我们的依赖关系.
Build/DefaultTargets定义在package.mk中,其中形成了我们stamp-*的依赖关系.根据这些依赖关系,我将关系图绘制如下:

执行
当我们得出依赖关系后,执行过程就是倒序进行而已,即从上图的右边向左执行.这也可以和我们预料的执行过程相印证.
- $(stamp-prepared)
- 主要完成代码包的准备工作,如果开发者定义了build/prepare,则执行build/prepare.如果开发者未定义,则执行build/prepare/default这其中包含了多个情形,最为常见的是将dl下的压缩包解压并打上patch.
- $(stamp-built)
- 这个将会进入到build_dir/target-XXX/下对应的文件夹进行编译.同时将会带入一些定义好的变量.比如CFLAGS,LDFLAGS.
- IPKG_(1)
- 这个目标将会将编译好的文件安装到对应的ipkg-arch目录下,同时将这个目录打包为ipk文件.
尾记
本周博客基本就到这里,本来私心想着元旦没啥大事,可以写两篇的.结果混着混着就到第三天晚上了.剩下的最后一篇我们看看单个的ipk编译好了,内核的编译过程,最后的打包过程.整个镜像文件由哪些部分组成.下周再见.
全部过程分析请参见前文,至少还应包含必要的检查,tools和toolchain的编译.这里因为我们主要分析单个ipk的编译过程,所以我将之略过 ↩︎
(四) openwrt单个ipk编译过程的更多相关文章
- 搭建OpenWrt开发环境(包括编译过程)
OpenWrt是一个高度模块化.高度自动化的嵌入式linux发行版,其编译和安装过程比普通的linux发行版而言,要简单太多了.如果您是新手,您那恐惧的心大可放到肚子里,呵呵.对于新手来说最麻烦的恐怕 ...
- openWRT自学---自己编译的第一个 backfire10.03 版本的过程记录(转)
基于 backfire10.03(从http://downloads.openwrt.org/backfire/10.03/ 中下砸的源码包backfire_10.03_source.tar.bz2: ...
- openWRT自学---自己编译的第一个 backfire10.03 版本的过程记录 --- 实际是由于下载了错误的backfire源码包导致的
基于 backfire10.03(从http://downloads.openwrt.org/backfire/10.03/ 中下砸的源码包backfire_10.03_source.tar.bz2: ...
- (二)我的Makefile学习冲动&&编译过程概述
前言 一 年轻的冲动 二 学习曲线 1 Makefile基本语法 2 bash基础 3 world 三 编译过程概述 1 主机预装工具 2 编译host工具 3 编译交叉工具链 4 编译内核模块 5 ...
- 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...
- java编译过程(字节码编译和即时编译)
Javac编译与JIT编译 简介: 编译包括两种情况: 1,源码编译成字节码 2,字节码编译成本地机器码(符合本地系统专属的指令) 解释执行也包括两种情况: 1,源码解释执行 2,字节码解释执行 解释 ...
- MDK 的编译过程及文件类型全解
MDK 的编译过程及文件类型全解 ------(在arm9的开发中,这些东西都是我们自己搞定的,但是在windows上,IDE帮我们做好了,了解这些对深入开发是很有帮助的,在有arm9开发的基础上,下 ...
- gcc 学习笔记(一) - 编译C程序 及 编译过程
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...
- 第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429系列
第48章 MDK的编译过程及文件类型全解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
随机推荐
- myeclipse的实用快捷键
(1)Ctrl+M切换窗口的大小(2)Ctrl+Q跳到最后一次的编辑处(3)F2当鼠标放在一个标记处出现Tooltip时候按F2则把鼠标移开时Tooltip还会显示即Show Tooltip Desc ...
- 使用EasyUI的插件前需要引入的文件
一.使用EasyUI的插件需要引入一些文件 1.引入相关文件 easyui.css: easyUi的样式文件 icon.css:easyUI的图标样式文件 easyui.min.js:easyUi的类 ...
- C#为工作Sql而产生的字符串分割小工具(很实用,你值得拥有)
写在前面 为什么要写这个工具? 工作需要,拼接字符串头晕眼花拼接的,特别是in 查询,后面的参数太多,想在数据执行一些这个sql语句老费劲了. 看正文 工作所有的(后台)攻城狮们都会接触到sql语句, ...
- ajax onblur 用法
value为当前框中的值 <input name="num"type="text" onblur="changeorder(id,this. ...
- 误报的java.sql.SQLException: Parameter number 21 is not an OUT parameter
今天为了模拟一个mysql内存不释放问题,要测试一个存储过程,同时具有出参和入参,启动时报了上述错误. <select id="funcl_trd_secu_execution_que ...
- rabbitmq+ keepalived+haproxy高可用集群详细命令
公司要用rabbitmq研究了两周,特把 rabbitmq 高可用的研究成果备下 后续会更新封装的类库 安装erlang wget http://www.gelou.me/yum/erlang-18. ...
- React入门--------JSX
React学习网站 React官方英文网站:http://reactjs.cn/react/docs/top-level-api.html React官方中文网站:http://www.css88.c ...
- RHEL7用户管理
本文介绍Linux的用户管理 用户管理 Linux 是一个可以实现多用户登陆的操作系统,不同用户可以同时登陆同一台主机,他们共享一些主机的资源,但他们也分别有自己的用户空间,用于存放各自的文件. 但实 ...
- SharePoint 2010 文档管理之点击次数
前言:很多场景下,我们都需要对一篇文章或者文档的点击次数进行统计,然而SharePoint本身并没有给我们设计这样一个字段,所以我们需要通过简单的字段开发来实现这样一个功能. 一.创建项目: 1. 创 ...
- 挣值管理(PV、EV、AC、SV、CV、SPI、CPI)记忆之我见
挣值管理(PV.EV.AC.SV.CV.SPI.CPI)记忆之我见 挣值管理法中的PV.EV.AC.SV.CV.SPI.CPI这些英文简写相信把大家都搞得晕头转向的.在挣值管理法中,需要记忆理解的有三 ...