Openwrt:添加自定义软件包.ipk

2024-05-18 18:48

本文主要是介绍Openwrt:添加自定义软件包.ipk,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们已经尝试做的一件事情,是让移植软件到OpenWrt的操作变得非常容易。如果打开OpenWrt里的一个软件包的目录(OpenWrt/Package/* 或 OpenWrt/feeds/packages//),通常会发现几样东西:

  • package/Makefile [必备]
  • package/patches/ [可选]
  • package/files/ [可选]

patches目录和files目录都是可选的,pactches目录通常包括bug修复和对可执行文件体积的优化,files目录通常包括配置文件。你也可能看到其它目录,因为只要在Makefile文件中指明,目录名字是可以任取的。前面两个是约定俗成的做法,强烈建议你也这么做。

Makefile文件最关键,一般来说它提供了下载、编译、安装这个软件包的步骤。

当我们打开这里的Makefile文件,很难认出这是一个Makefile。它的格式跟一般的Makefile不一样,因为它的功能跟普通Makefile就是不一样的。它是一种编写方便的模板。

这里,以package/bridge/Makefile文件为例:

include $(TOPDIR)/rules.mkPKG_NAME:=bridge
PKG_VERSION:=1.0.6
PKG_RELEASE:=1PKG_BUILD_DIR:=$(BUILD_DIR)/bridge-utils-$(PKG_VERSION)
PKG_SOURCE:=bridge-utils-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/bridge
PKG_MD5SUM:=9b7dc52656f5cbec846a7ba3299f73bd
PKG_CAT:=zcatinclude $(INCLUDE_DIR)/package.mkdefine Package/bridgeSECTION:=baseCATEGORY:=NetworkTITLE:=Ethernet bridging configuration utility#DESCRIPTION:=This variable is obsolete. use the Package/name/description define instead!URL:=http://bridge.sourceforge.net/
endefdefine Package/bridge/descriptionEthernet bridging configuration utilityManage ethernet bridging; a way to connect networks together toform a larger network.
endefdefine Build/Configure$(call Build/Configure/Default,--with-linux-headers=$(LINUX_DIR))
endefdefine Package/bridge/install$(INSTALL_DIR) $(1)/usr/sbin$(INSTALL_BIN) $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin/
endef$(eval $(call BuildPackage,bridge))

软件包变量

建立一个软件包不需要太多工作;大部分工作都隐藏在其它的 makefiles 中,编写工作被抽象成对几个变量的赋值。

  • PKG_NAME -软件包的名字, 在 menuconfig 和 ipkg 显示
  • PKG_VERSION -软件包的版本,主干分支的版本正是我们要下载的
  • PKG_RELEASE -这个 makefile 的版本
  • PKG_BUILD_DIR -编译软件包的目录
  • PKG_SOURCE -要下载的软件包的名字,一般是由 PKG_NAME 和 PKG_VERSION 组成
  • PKG_SOURCE_URL -下载这个软件包的链接
  • PKG_MD5SUM -软件包的 MD5 值
  • PKG_CAT -解压软件包的方法 (zcat, bzcat, unzip)
  • PKG_BUILD_DEPENDS -需要预先构建的软件包,但只是在构建本软件包时,而不是运行的时候。它的语法和下面的DEPENDS一样。

PKG_*变量定义了从何处下载这个软件包;@SF是表示从sourceforge网站下载的一个特殊关键字。md5sum用来检查从网上下载的软件包是否完好无损。PKG_BUILD_DIR定义了软件包源代码的解压路径。

注意到上面示例文件底部的最后一行吗?这是最为关键的BuildPackage宏。它是在$(INCLUDE_DIR)/package.mk文件里定义的。BuildPackage宏只要求一个参数,即要编译的软件包名,在本例中是”bridge”。所有其他信息都通过宏来获得,这提供了一种内在的简洁性。比如BuildPackage需要软件包的一大串描述信息,我们并不要向它传递冗长的参数,因为我们已经约定描述信息定义在DESCRIPTION宏,BuildPackage从里面读取就可以了。

BuildPackage相关的宏

Package/

描述软件包在menuconfig和ipkg中的信息,可以定义如下变量:
  • SECTION - 软件包类型 (尚未使用)
  • CATEGORY - menuconfig中软件包所属的一级目录,如Network
  • SUBMENU - menuconfig中软件包所属的二级目录,如dial-in/up
  • TITLE - 软件包标题
  • DESCRIPTION - 软件包的详细说明
  • URL - 软件的原始位置,一般是软件作者的主页
  • MAINTAINER - (optional) 软件包维护人员
  • DEPENDS - (optional) 依赖项,运行本软件依赖的其他包

Package/conffiles (可选)

软件包需要复制的配置文件列表,一个文件占一行

Build/Prepare (可选)

一组解包源代码和打补丁的命令,一般不需要。

Build/Configure (可选)

如果源代码编译前需要configure且指定一些参数,就把这些参数放在这儿。否则可以不定义。

Build/Compile (可选)

编译源代码命令。

Package/install

软件安装命令,主要是把相关文件拷贝到指定目录,如配置文件。

Package/preinst

软件安装之前被执行的脚本,别忘了在第一句加上#!/bin/sh。如果脚本执行完毕要取消安装过程,直接让它返回false即可。

Package/postinst

软件安装之后被执行的脚本,别忘了在第一句加上#!/bin/sh。

Package/prerm

软件删除之前被执行的脚本,别忘了在第一句加上#!/bin/sh。如果脚本执行完毕要取消删除过程,直接让它返回false即可。

Package/postrm

软件删除之后被执行的脚本,别忘了在第一句加上#!/bin/sh。

为什么一些定义是”Package/”前缀,另一些定义却是”Build”前缀?这是因为我们支持一个特性:从单个源代码构建多个软件包。OpenWrt工作在一个Makefile对应一个源代码的假设之上,但是你可以把编译生成的程序分割成任意多个软件包。因为编译只要一次,所以使用全局的”Build”定义是最合适的。然后你可以增加很多“Package/”定义,为各软件包分别指定安装方法。建议你去看看dropbear包,这是一个很好的示范。

提示:对于所有在pre/post, install/removal脚本中使用的变量,都应该使用”“代替” "make" ”代替”“。 – 更多信息

在编辑好Makefile文件,并放到指定目录后,这个新的软件包将在下次执行make menuconfig时出现,你可以选择这个软件包,保存退出,用make编译。现在就把一个软件成功移植到OpenWrt中了!

创建内核模块软件包

内核模块是一类扩展Linux内核功能的可安装程序。内核模块的加载发生在内核加载之后,(比如使用insmod命令)。

Linux源代码包含了很多内核应用程序。在menuconfig时有3种选择,

  1. 编译进内核;
  2. 编译成可加载的内核模块;
  3. 不编译。

参看FIX:Customizingthekerneloptions customizing the kernel options

要包含这些内核模块,只要make menuconfig选择相应的内核模块选项。(参看Build Configuration)。如果在make menuconfig时没有发现想要的内核模块,必须添加一个stanza到package/kernel/modules目录的一个文件中。下面是一个从package/kernel/modules/other.mk提取出来的例子。

define KernelPackage/loopTITLE:=Loopback device supportDESCRIPTION:=Kernel module for loopback device supportKCONFIG:=$(CONFIG_BLK_DEV_LOOP)SUBMENU:=$(EMENU)AUTOLOAD:=$(call AutoLoad,30,loop)FILES:=$(MODULES_DIR)/kernel/drivers/block/loop.$(LINUX_KMOD_SUFFIX)
endef
$(eval $(call KernelPackage,loop))

此外,你还可以添加不属于Linux源码包的内核模块。在这种情况下,内核模块放在package/目录,跟通常的软件包是一样的。package/Makefile文件使用KernelPackage/xxx定义代替Package/xxx。

这是package/madwifi/Makefile的例子:

#
# Copyright (C) 2006 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id$include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mkPKG_NAME:=madwifi
PKG_VERSION:=0.9.2
PKG_RELEASE:=1PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=@SF/$(PKG_NAME)
PKG_MD5SUM:=a75baacbe07085ddc5cb28e1fb43edbb
PKG_CAT:=bzcatPKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)include $(INCLUDE_DIR)/package.mkRATE_CONTROL:=sampleifeq ($(ARCH),mips)HAL_TARGET:=mips-be-elf
endif
ifeq ($(ARCH),mipsel)HAL_TARGET:=mips-le-elf
endif
ifeq ($(ARCH),i386)HAL_TARGET:=i386-elf
endif
ifeq ($(ARCH),armeb)HAL_TARGET:=xscale-be-elf
endif
ifeq ($(ARCH),powerpc)HAL_TARGET:=powerpc-be-elf
endifBUS:=PCI
ifneq ($(CONFIG_LINUX_2_4_AR531X),)BUS:=AHB
endif
ifneq ($(CONFIG_LINUX_2_6_ARUBA),)BUS:=PCI AHB  # no suitable HAL for AHB yet.
endifBUS_MODULES:=
ifeq ($(findstring AHB,$(BUS)),AHB)BUS_MODULES+=$(PKG_BUILD_DIR)/ath/ath_ahb.$(LINUX_KMOD_SUFFIX)
endif
ifeq ($(findstring PCI,$(BUS)),PCI)BUS_MODULES+=$(PKG_BUILD_DIR)/ath/ath_pci.$(LINUX_KMOD_SUFFIX)
endifMADWIFI_AUTOLOAD:= \wlan \wlan_scan_ap \wlan_scan_sta \ath_hal \ath_rate_$(RATE_CONTROL) \wlan_acl \wlan_ccmp \wlan_tkip \wlan_wep \wlan_xauthifeq ($(findstring AHB,$(BUS)),AHB)MADWIFI_AUTOLOAD += ath_ahb
endif
ifeq ($(findstring PCI,$(BUS)),PCI)MADWIFI_AUTOLOAD += ath_pci
endifdefine KernelPackage/madwifiSUBMENU:=Wireless DriversDEFAULT:=y if LINUX_2_6_BRCM |  LINUX_2_6_ARUBA |  LINUX_2_4_AR531X |  LINUX_2_6_XSCALE, m if ALLTITLE:=Driver for Atheros wireless chipsetsDESCRIPTION:=\This package contains a driver for Atheros 802.11a/b/g chipsets.URL:=http://madwifi.org/VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE)FILES:= \$(PKG_BUILD_DIR)/ath/ath_hal.$(LINUX_KMOD_SUFFIX) \$(BUS_MODULES) \$(PKG_BUILD_DIR)/ath_rate/$(RATE_CONTROL)/ath_rate_$(RATE_CONTROL).$(LINUX_KMOD_SUFFIX) \$(PKG_BUILD_DIR)/net80211/wlan*.$(LINUX_KMOD_SUFFIX)AUTOLOAD:=$(call AutoLoad,50,$(MADWIFI_AUTOLOAD))
endefMADWIFI_MAKEOPTS= -C $(PKG_BUILD_DIR) \PATH="$(TARGET_PATH)" \ARCH="$(LINUX_KARCH)" \CROSS_COMPILE="$(TARGET_CROSS)" \TARGET="$(HAL_TARGET)" \TOOLPREFIX="$(KERNEL_CROSS)" \TOOLPATH="$(KERNEL_CROSS)" \KERNELPATH="$(LINUX_DIR)" \LDOPTS=" " \ATH_RATE="ath_rate/$(RATE_CONTROL)" \DOMULTI=1ifeq ($(findstring AHB,$(BUS)),AHB)define Build/Compile/ahb$(MAKE) $(MADWIFI_MAKEOPTS) BUS="AHB" allendef
endififeq ($(findstring PCI,$(BUS)),PCI)define Build/Compile/pci$(MAKE) $(MADWIFI_MAKEOPTS) BUS="PCI" allendef
endifdefine Build/Compile$(call Build/Compile/ahb)$(call Build/Compile/pci)
endefdefine Build/InstallDev$(INSTALL_DIR) $(STAGING_DIR)/usr/include/madwifi$(CP) $(PKG_BUILD_DIR)/include $(STAGING_DIR)/usr/include/madwifi/$(INSTALL_DIR) $(STAGING_DIR)/usr/include/madwifi/net80211$(CP) $(PKG_BUILD_DIR)/net80211/*.h $(STAGING_DIR)/usr/include/madwifi/net80211/
endefdefine KernelPackage/madwifi/install$(INSTALL_DIR) $(1)/etc/init.d$(INSTALL_DIR) $(1)/lib/modules/$(LINUX_VERSION)$(INSTALL_DIR) $(1)/usr/sbin$(INSTALL_BIN) ./files/madwifi.init $(1)/etc/init.d/madwifi$(CP) $(PKG_BUILD_DIR)/tools/{madwifi_multi,80211debug,80211stats,athchans,athctrl,athdebug,athkey,athstats,wlanconfig} $(1)/usr/sbin/
endef$(eval $(call KernelPackage,madwifi))

转自:https://wiki.openwrt.org/zh-cn/doc/devel/packages

这篇关于Openwrt:添加自定义软件包.ipk的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995676

相关文章

SpringBoot全局异常拦截与自定义错误页面实现过程解读

《SpringBoot全局异常拦截与自定义错误页面实现过程解读》本文介绍了SpringBoot中全局异常拦截与自定义错误页面的实现方法,包括异常的分类、SpringBoot默认异常处理机制、全局异常拦... 目录一、引言二、Spring Boot异常处理基础2.1 异常的分类2.2 Spring Boot默

自定义注解SpringBoot防重复提交AOP方法详解

《自定义注解SpringBoot防重复提交AOP方法详解》该文章描述了一个防止重复提交的流程,通过HttpServletRequest对象获取请求信息,生成唯一标识,使用Redis分布式锁判断请求是否... 目录防重复提交流程引入依赖properties配置自定义注解切面Redis工具类controller

kafka自定义分区器使用详解

《kafka自定义分区器使用详解》本文介绍了如何根据企业需求自定义Kafka分区器,只需实现Partitioner接口并重写partition()方法,示例中,包含cuihaida的数据发送到0号分区... 目录kafka自定义分区器假设现在有一个需求使用分区器的方法总结kafka自定义分区器根据企业需求

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

SpringBoot AspectJ切面配合自定义注解实现权限校验的示例详解

《SpringBootAspectJ切面配合自定义注解实现权限校验的示例详解》本文章介绍了如何通过创建自定义的权限校验注解,配合AspectJ切面拦截注解实现权限校验,本文结合实例代码给大家介绍的非... 目录1. 创建权限校验注解2. 创建ASPectJ切面拦截注解校验权限3. 用法示例A. 参考文章本文

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1