OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)

一、软件包目录及结构(package目录)

  • 概念:OpenWrt 有一个非常好的构建系统,这样我们就可以非常方便地管理数千个软件包和几十个硬件平台。我们也可以非常方便地移植已有的软件到OpenWrt系统中。在前面我们介绍的OpenWrt源码中,你会发现各个软件包目录下一般会有两个文件夹和一个Makefile 文件

目录结构

  • 我们以dnsmasq软件为例,此软件的目录下会有如下几个文件和目录

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第1张图片

  • 补丁(patches)目录:是可选的,典型包含缺陷修改或者用于优化可执行程序大小的补丁文件
  • files目录:也是可选的,它一般用于保存默认配置文件和初始化启动脚本
  • src目录:如果为OpenWrt本身项目所包含的软件模块,因为代码将完全受到自己控制,这时将不会patches 目录存在,而是会有一个 src 目录,代码直接放在src目录下(在下一篇文章中我们自己定义的软件包就有这个目录)
  • Makefile:提供下载、编译、安装以及生成 OPKG 安装包的功能,这个文件是必须有的

二、软件包的Makefile

  • Makefile提供下载、编译、安装以及生成 OPKG 安装包的功能,这个文件是必须有的
  • OpenWrt下的Makefile:从Makefile的内容可以看出,此Makefile与普通的Makefile不同,OpenWrt没有遵守传统的Makefile格式风格,而是将Makefile写成面向对 象格式,这样就简化了多平台移植过程

Makefile的结构

下面我们以dnsmasq软件的Makefile为例,此Makefile可以编译3个软件包(分别为 dnsmasq、dnsmasq-dhcpv6 和dnsmasq-full

  • ①首先是使用“include”指示符来包含顶层目录的rules.mk文件

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第2张图片

  • ②接着是变量定义,它定义了软件包的基本信息,如名称、版本、下载地址、许可协议和编译目录等信息

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第3张图片

  • ③在“PKG_*”变量定义完成之后再包含package.mk文件

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第4张图片

  • ④中间部分是软件包的宏定义和一 些编译选项定义(篇幅过大,此处只截取了部分)

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第5张图片OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第6张图片

  • ⑤最后是调用BuildPackage。“BuildPackage”是在包含头文件“include/package.mk”中定义的。BuildPackage仅仅需要一个直接参数——要编译的软件包名称。在这个例子中传递了 3 个软件包名称作为参数,分别为 dnsmasq、dnsmasq-dhcpv6 和dnsmasq-full

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第7张图片

rules.mk、package.mk

下面我们还是以dnsmasq软件的Makefile为例

  • 软件包的Makefile没有太多其他逻辑依赖的工作需要去做,所有的一切都是隐藏在被包含的Makefile(include/package.mk 及 rules.mk)中的
  • Makefile文件非常抽象,你只需要按照通用的模板定义变量即可
  • rules.mk文件是全局的编译变量定义,在每一个软件包的Makefile文件的第一行均首先包含这个文件
  • rules.mk文件中经常使用的变量定义有以下几个:
    • INCLUDE_DIR:源代码目录下的 include 目录
    • BUILD_DIR:代码编译的根目录,通常为“build_dir/target-*”目录
    • TARGET_CFLAGS:指定目标平台的 C 语言编译选项
    • TARGET_LDFLAGS:指定目标平台的编译链接选项
    • INSTALL_DIR:创建目录,并设置目录权限
    • INSTALL_DATA:安装数据文件,即复制并设置权限为 0644
    • INSTALL_CONF:安装配置文件,即复制并设置权限为 0600
    • INSTALL_BIN:安装可执行程序,即复制并增加执行权限,设置权限表示为 0777

OpenWrt——Makefile变量

  • OpenWrt 预定义了很多变量,这些变量减少了使用者的开发代价,但需要使用者按照语义进行使用
变 量 含 义 示 例
PKG_NAME 软件包的名称,可以通过 menuconfig 和 ipkg 查看到 dnsmasq
PKG_VERSION 上游软件的版本号,为 2.73 2.73
PKG_RELEASE Makefile 的版本号 1
PKG_SOURCE 原始的源代码文件名  
PKG_SOURCE_URL 用于下载源码的地址(目录) http://thekelleys.org.uk/dnsmasq
PKG_MD5SUM 软件包的 MD5 值,用于验证下载的文件 是否正确 b8bfe96d22945c8cf4466826ba 9b21bd
PKG_LICENSE 这个软件的许可协议,开源软件的许可证 以 GPL 家族最多 GPL-2.0
PKG_LICENSE_FILES 许可协议文件,是指代码目录下的文件名, 一般均为 COPYING COPYING
PKG_BUILD_DIR 软件包的编译目录(就是编译过程中的临时目录build_dir  
PKG_INSTALL 设置为 1 将调用软件包自己的“make install”,安装目录前缀为 PKG_INSTALL_ DIR 1
PKG_BUILD_PARALLEL 是否可以并行编译 1
PKG_CONFIG_DEPENDS 编译依赖,指定哪些选项依赖本软件包  
PKG_INSTALL_DIR 当调用原始软件包“make install”时的安 装目录  
PKG_SOURCE_PROTO 用于下载的传输协议(git、svn),如果为 压缩包则不用指定  
PKG_SOURCE_SUBDIR 下载目录,如果下载传输协议为“svn”或 “git”时必须指定。例如:"PKG_SOURCE_ SUBDIR:=$(PKG_NAME)-$(PKG_VERSI ON)"  
PKG_SOURCE_VERSION 下载协议为“git”时必须指定,指定的提 交哈希点将会被检出  
PKG_MAINTAINER 维护者的姓名和邮件地址  
PKG_BUILD_DEPENDS 软件包编译依赖,即在这个包编译之前编 译,但是在运行时不需要,和 DEPENDS 有相同的语法  

三、软件包Makefile中的宏定义

  • 软件包定义用于编译前的软件包选择和编译后的IPKG安装包生成。这些设置的参数传递给 buildroot进行交叉编译,buildroot 是交叉编译环境的统称。这些是在menuconfig和生成的IPKG安装包实体中显示的

Package宏定义

  • 一些宏定义以“Package/”开头,Package开头的定义用于“make menuconfig”选择及编译生成软件包
  • 但你可以将一个源代码包分割为多个安装包。 你可以增加许多软件安装包“Package/”定义来多次调用BuildPackage,这样就可以从单个 源代码编译出来多个软件安装包
  • 例如dnsmasq软件的Makefile中就定义了3种软件安装包,即dnsmasq、 dnsmasq-dhcpv6 和 dnsmasq-full

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第8张图片

Package/宏定义下的变量赋值

  • 下面是在软件包“Package/”宏定义下可以赋值的变量
  • 例如是下图是dnsmasq软件的Makefile中,其中定义了3种软件安装包(dnsmasq、 dnsmasq-dhcpv6 和 dnsmasq-full),每个软件包下有一些变量的定义
变量 含义
SECTION 软件包的类型,如 network、Sound、Utilities 或 Multimedia等
CATEGORY 在 menuconfig 中显示到菜单分类中
TITLE 标题,是软件包的简短描述
URL 软件包的原始网站地址,可以在这里找到该软件
MAINTAINER 维护者的姓名和邮件地址。一般为这个软件包作者的邮件地址
DEPENDS (可选)依赖项,需要在本软件包之前编译和安装的软件包
OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第9张图片

Package/宏定义选项

  • 软件包 Package 选项
安装包选项 是否必需 含 义
Package/<软件包名称> 定义软件包的描述信息,例如网站地址和menuconfig 中的菜单分类等
Package/<软件包名>/Default 可选 软件包的默认选项
Package/<软件包名>/description 软件包的详细描述
Package/<软件包名>/install 复制文件到 ipkg 目录中,使用$(1)代表 ipkg 的目录,在源代码中使 用相对目录。编译生成的安装文件由$(PKG_INSTALL_ DIR)目录下 复制到 ipkg 的目录下
Package/<软件包名>/config 可选 根据软件包的选择对编译选项进行定义
Package/<软件包名>/conffiles 可选 定义本软件包的运行配置文件列表,一行一个文件
Package/<软件包名>/preinst 可选 这是在安装之前实际执行的脚本,不要忘了包含#!/bin/sh。如果 你需要中止安装就返回 false
Package/<软件包名>/postinst 可选 在安装完成后执行的脚本,例如启动程序。不要忘了包含 #!/bin/sh
Package/<软件包名>/prerm 可选 在删除之前执行的脚本,例如停止程序的执行。不要忘了包含 #!/bin/sh。如果需要中止删除就返回 false
Package/<软件包名>/postrm 可选 在删除之后执行的脚本,不要忘了包含#!/bin/sh。如果需要中止 删除就返回 false
  •  例如下面是dnsmasq软件包Makefile中的Package/选项

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第10张图片

Build宏定义

  • 一些宏定义为“Build/”开头,这些用于代码编译
  • 通常编译过程都是一样的,只是中间的编译参数有所不同,因此只有一个全局“Build”定
  • 例如下面是iproute2软件的Makefile中的Build宏定义

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第11张图片

四、构建

  • 软件包模块的编译步骤,通常包含下面4步:
    • 准备(Prepare)
    • 配置(Configure)
    • 编译 (Compile)
    • 安装(Install)
  • 上面这部分在构建时都是可选的,因为OpenWrt已经制作了通用的模板,适合大多数模块来编译使用。
  • 上面我们介绍的dnsmasq软件就是采用默认的步骤,因此在Makefile中没有看到Build宏定义。但指定了编译选项,例如设置 MAKE_FLAGS 变量指定编译选项,CONFIGURE_ARGS 变量用 于指定配置选项。这些变量都在“package-defaults.mk”文件中定义,我们可以在软件包的 Makefile中修改它

软件包构建步骤

Build 步骤 是否必需 含 义
Build/Prepare 可选 一组用于解包及打补丁的命令,也可以不使用
Build/Configure 可选 如果源代码不需要configure来生成Makefile或者是通用的configure脚本, 就不需要这部分。否则就需要你自己的命令脚本或者使用"$(call Build/Configure/Default, FOO=bar)"增加额外的参数传递给 configure 脚本
Build/Compile 可选 编译源代码,在大多数情况下应该不用定义而使用默认值。如果你想传递给 make 特定的参数,可以使用“$(call Build/Compile/Default, FOO=bar)”
Build/Install 可选 安装编译后的文件,默认是调用 make install,如果需要传递指定的参 数,使用$(call Build/Install/Default,install install-foo)。注意你需要传递所 有的参数,要增加在“install”参数后面,不要忘了“install”参数
Build/InstallDev 可选 例如静态库和头文件等,但是不需要在目标设备上使用
  • 例如下面是iproute2软件的Makefile中的Build宏定义

OpenWrt开发:15---软件编译构建系统(package目录、rules.mk、package.mk)_第12张图片

五、自定义软件的构建

  • 见文章:https://blog.csdn.net/qq_41453285/article/details/102545618

你可能感兴趣的:(OpenWrt开发)