OpenWrt的主Makefile工作过程

来源:互联网 发布:万利达t8软件下载 编辑:程序博客网 时间:2024/06/05 17:55

转自:http://blog.csdn.net/mrwangwang/article/details/46928647

原文地址:OpenWrt的主Makefile工作过程 作者:apple_guet

        OpenWrt是一个典型的嵌入式Linux工程,了解OpenWrt的Makefile工作过程对提高嵌入式Linux工程的开发能力有极其重要意义。
        OpenWrt的主Makefile文件只有100行,可以简单分为三部分,1~17行为前导部分,19~31为首次执行部分,33~101为再次执行部分。
一、前导部分
        “CURDIR”为make默认变量,默认值为当前目录。
        前导部分主要把变量TOPDIR赋值为当前目录,把变量LC_ALL、LANG赋值为C,并使用变量延伸指示符export,把上述三个变量延伸到下层Makefile。
        使用文件指示符“include”引入“$(TOPDIR)/include/host.mk”。在OpenWrt的主Makefile文件使用了多次 include指示符,说明主Makefile文件被拆分成多个文件,被拆分的文件放在不同的目录。拆分的目的是明确各部分的功能,而且增加其灵活性。
        在前导部分比较费解的是使用world目标,在makefile中基本规则为:
        TARGETS : PREREQUISITES
        COMMAND
        ...
        即makefile规则由目标、依赖、命令三部分组成,在OpenWrt的主Makefile文件的第一个目标world没有依赖和命令。它主要起到指示当make命令不带目标时所要执行的目标,没有设定依赖和命令部分表明此目标在此后将会有其他依赖关系或命令。world目标的命令需要进一步参考“$(TOPDIR)/include/toplevel.mk”和主Makefile文件的再次执行部分。
二、首次执行部分
        OPENWRT_BUILD是区分首次执行与再次执行的变量。在首次执行时使用强制赋值指示符override把OPENWRT_BUILD赋值为1,并使用变量延伸指示符“export”把OPENWRT_BUILD延伸。在OPENWRT_BUILD使用强制赋值指示符override意味着make命令行可能引入OPENWRT_BUILD参数。
        引入$(TOPDIR)/include/debug.mk、$(TOPDIR)/include/depends.mk、$(TOPDIR) /include/toplevel.mk三个文件,由于TOPDIR是固定的,所以三个文件也是固定的。其中“$(TOPDIR)/include/toplevel.mk”的135行%::有效解释首次执行时world目标的规则。
三、再次执行部分
        引入rules.mk、$(INCLUDE_DIR)/depends.mk、$(INCLUDE_DIR)/subdir.mk、target /Makefile、package/Makefile、tools/Makefile、toolchain/Makefile七个文 件,rules.mk没有目录名,即引入与主Makefile文件目录相同的rules.mk。在rules.mk定义了“INCLUDE_DIR”为$(TOPDIR)/include,所以“$(INCLUDE_DIR)/depends.mk”实际上与首次执行时引入的“$(TOPDIR) /include/depends.mk”是同一个文件。
        四个子目录下的Makefile实际上是不能独立执行。主要利用$(INCLUDE_DIR)/subdir.mk动态建立规则,诸如“$(toolchain/stamp-install)”目标是靠“$(INCLUDE_DIR)/subdir.mk的stampfile”函数动态建立。 在“package/Makefile”动态建立了$(package/stamp-prereq)、$(package/stamp-cleanup)、$(package/stamp-compile)、$(package/stamp-install)、$(package/stamp-rootfs-prepare)目标。
        定义一些使用变量命名的目标,其变量的赋值位置在“$(INCLUDE_DIR)/subdir.mk”的stampfile函数中。目标只有依赖关系,可能说明其工作顺序,在“$(INCLUDE_DIR)/subdir.mk”的stampfile函数中有进一步说明其目标执行的命令,并为目标建立一个空文件,即使用变量命名的目标为真实的文件。
四、定义一些使用固定的目标规则
        其中:clean是清除编译结果的目标,清除$(BUILD_DIR)、$(BIN_DIR)和$(BUILD_LOG_DIR)三个目录的用意是十分明确。暂时不知道为什么执行make target/linux/clean。
        dirclean是删除所有编译过程产生的目录和文件的目标,执行dirclean目标依赖于clean,因此将执行clean目标所执行的命令,然后删除$(STAGING_DIR)、$(STAGING_DIR_HOST)、$(STAGING_DIR_TOOLCHAIN)、$(TOOLCHAIN_DIR)、$(BUILD_DIR_HOST)、$(BUILD_DIR_TOOLCHAIN)目录,以及删除$(TMP_DIR)目录。上述目录的变量均在rules.mk定义。好像删除 staging_dir目录就意味着删除staging_dir目录下的所有子目录,不知道为什么要强调删除$(STAGING_DIR_HOST)、$(STAGING_DIR_TOOLCHAIN)、$(TOOLCHAIN_DIR)目录。同样删除builde_dir目录就意味着删除builde_dir目录下的所有子目录,不知道为什么要强调删除$(BUILD_DIR_TOOLCHAIN)目录。
        tmp/.prereq_packages目标是对所需软件包的预处理。目标依赖于.config,即执行make menuconfig后将会进行一次所需软件包的预处理。不知什么原因在编译前删除tmp目录,执行时无法建立tmp/.prereq_packages文件。
        prereq应该是预请求目标,在OpenWrt执行Makefile时好像都要先执行prereq目标。
        prepare应该是准备目标,是world依赖的一个伪目标。依赖于文件.config和$(tools/stamp-install) $(toolchain/stamp-install)目标。
        world就是编译的目标。依赖于prepare为目标和前面提到的变量命名目标。采用取消隐含规则方式执行package/index目标。package/index目标在package/Makefile的92行定义。
        package/symlinks和package/symlinks-install是更新或安装软件包来源的目标,使用$(SCRIPT_DIR)/feeds脚本文件完成。
        package/symlinks-clean是清除软件包来源的目标,也是使用$(SCRIPT_DIR)/feeds脚本文件完成。
        最后使用伪目标.PHONY说明clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean属于伪目标。通过伪目标说明可以知道可以执行的目标。
转自:http://blog.chinaunix.net/uid-23780428-id-4367378.html

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 厦门网上办理居住证怎么办 宝宝风热咳嗽怎么办 小孩感冒后鼻炎怎么办 小孩感冒引起鼻炎怎么办 婴幼儿喉咙有痰怎么办 驾校的居住证明怎么办 去韩国留学护照怎么办 去韩国签证怎么办d4 出国留学拒签怎么办 高中毕业考不上大学怎么办 深圳怎么办客运营运证 深圳龙岗怎么办居住证 想去日本怎么办签证 孩子没有出生证怎么办通行证 去日本旅游怎么办签证 去美国旅游签证怎么办 我想去泰国怎么办签证 怎么办去泰国的签证 去韩国工作怎么办签证 去越南打工怎么办签证 越南到中国签证怎么办 去越南工作签证怎么办 马来西亚留学签证过期后怎么办 日本留学存款不够怎么办 没有工作单位怎么办签证 深户日本签证怎么办 土耳其跟团签证怎么办 公司取消交通车职工怎么办 出国健康证丢失怎么办 大三阳怎么办健康证 办不了健康证怎么办 办健康证不合格怎么办 美团健康证怎么办 便检取样很多怎么办 拉不出大便怎么办马上解决方法 无业人员怎么办健康证 健康证没身份证怎么办 身份证过期了怎么办护照 驾照体检表丢了怎么办 驾照体检表掉了怎么办 驾校体检表掉了怎么办