http://blog.chinaunix.net/uid-10429687-id-3374873.html
OpenWrt是一個比較完善的嵌入式Linux開發平臺,在無線路由器應用上已有100多個軟件包。人們可以在其基礎上增加軟件包,以擴大其應用範圍。OpenWrt在增加軟件方面使用極其方便,按照OpenWrt的約定就可以很簡單完成。
加入的軟件包可以是網上可下載的開源軟件或自行開發的軟件。為加入軟件包需要在package目錄下創建一個目錄,以包含軟件包的各種信息和與OpenWrt建立聯繫的文件。然後創建一個Makefile與OpenWrt建立聯繫,Makefile需要遵循OpenWrt的約定。另外可以創建一個patchs目錄保存patch文件,對下載的源代碼進行適量修改。下面主要介紹Makefile的基本約定。
1、引入文件
OpenWrt使用三個makefile的子文件,分別爲:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
由這些makefile子文件確立軟件包加入OpenWrt的方式和方法。$(TOPDIR)/rules.mk一般在Makefile的開頭,$(INCLUDE_DIR)/kernel.mk文件對於軟件包為內核時不可缺少,$(INCLUDE_DIR)/package.mk一般在軟件包的基本信息完成後再引入。
2、編寫軟件包的基本信息,這些軟件包的信息均以PKG_開頭,其意思和作用如下:
PKG_NAME表示軟件包名稱,將在menuconfig和ipkg可以看到。
PKG_VERSION表示軟件版本號。
PKG_RELEASE表示Makefile的版本號
PKG_SOURCE表示源代碼的文件名。
PKG_SOURCE_URL表示源代碼的下載網站位置。@SF表示在sourceforge網站,@GNU表示在GNU網站,還有@GNOME、@KERNEL。獲取方式可以為:git、svn、cvs、hg、bzr等。有關下載方法可參考$(INCLUDE_DIR)/download.mk和$(SCRIPT_DIR)/download.pl。
PKG_MD5SUM表示源代碼文件的效驗碼。用於覈對軟件包是否正確下載。
PKG_CAT表示源代碼文件的解壓方法。包括zcat, bzcat, unzip等。
PKG_BUILD_DIR表示軟件包編譯目錄。它的父目錄爲$(BUILD_DIR)。如果不指定,默認爲$(BUILD_DIR)/$( PKG_NAME)$( PKG_VERSION)。
還有一些有關源代碼的定義。
PKG_SOURCE_SUBDIR
PKG_SOURCE_PROTO
PKG_SOURCE_MIRROR
PKG_MIRROR_MD5SUM
PKG_SOURCE_VERSION
3、編譯包定義
用戶程序和內核模塊的定義不一樣。用戶態軟件包使用Package,內核模塊使用KernelPackage。
3.1用戶程序編譯包定義
用戶程序的編譯包以Package/開頭,然後接着軟件名,在Package定義中的軟件名可以與軟件包名不一樣,而且可以多個定義。下面使用$(PKG_NAME)只是做一個標示,並非真正使用$(PKG_NAME)。
Package/$(PKG_NAME)
SECTION表示包的類型,預留。
CATEGORY表示分類,在menuconfig的菜單下將可以找到。
TITLE用於軟件包的簡短描述
DESCRIPTION用於軟件包的詳細描述,已放棄使用。如果使用DESCRIPTION將會提示“error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description”。
URL表示軟件包的下載位置。
MAINTAINER表示維護者,選項。
DEPENDS表示與其他軟件的依賴。即如編譯或安裝需要其他軟件時需要說明。如果存在多個依賴,則每個依賴需用空格分開。依賴前使用+號表示默認顯示,即對象沒有選中時也會顯示,使用@則默認為不顯示,即當依賴對象選中後才顯示。
在用戶態的軟件包中沒有內核模塊的AUTOLOAD參數。如果軟件需要在boot時自動運行,則需要在/etc/init.d增加相應的腳本文件。腳本文件需要START參數,說明在boot時的優先級,如果在boot過程啟動後在關閉,則需要進一步設置STOP參數。如果STOP參數存在,其值必須大於START。腳本文件需要start()和stop()兩個函數,start()是執行程序,stop()是關閉程序。關閉程序一般需要執行killall命令。由/etc/rc.d/S10boot知道,裝載內核模塊的優先級為10,需要使用自己設計的內核模塊的程序其START的值必須大於10.
同樣由/etc/rc.d/S40network知道,使用網絡通信的程序其START的值必須大於40。
Package/$(PKG_NAME)/conffiles
本包安裝的配置文件,一行一個。如果文件結尾使用/,則表示為目錄。用於備份配置文件說明,在sysupgrade命令執行時將會用到。
Package/$(PKG_NAME)/description
軟件包的詳細描述,取代前面提到的DESCRIPTION詳細描述。
Build/Prepare
編譯準備方法,對於網上下載的軟件包不需要再描述。對於非網上下載或自行開發的軟件包必須說明編譯準備方法。一般的準備方法爲:
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
按OpenWrt的習慣,一般把自己設計的程序全部放在src目錄下。
Build/Configure
在Automake中需要進行./configure,所以本配置方法主要針對需要配置的軟件包而設計,一般自行開發的軟件包可以不在這裏說明。需要使用本定義的情況,可參考dropbear。
Build/Compile
編譯方法,沒有特別說明的可以不予以定義。如果不定義將使用默認的編譯方法Build/Compile/Default
自行開發的軟件包可以考慮使用下面的定義。
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
$(TARGET_CONFIGURE_OPTS) CFLAGS="$(TARGET_CFLAGS) -I$(LINUX_DIR)/include"
Endef
Package/$(PKG_NAME)/install
軟件包的安裝方法,包括一系列拷貝編譯好的文件到指定位置。調用時會帶一個參數,就是嵌入系統的鏡像文件系統目錄,因此$(1)表示嵌入系統的鏡像目錄。一般可以採用下面的方法:
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ $(PKG_NAME) $(1)/usr/bin/
endef
INSTALL_DIR、INSTALL_BIN在$(TOPDIR)/rules.mk文件定義,所以本Makefile必須引入$(TOPDIR)/rules.mk文件。
INSTALL_DIR :=install -d -m0755 意思創建所屬用戶可讀寫即執行,其他用戶可讀可執行的目錄。
INSTALL_BIN:=install -m0755意思編譯好的文件到鏡像文件目錄。
如果用戶態軟件在boot時要自動運行,則需要在安裝方法說明中增加自動運行的腳本文件安裝和配置文件安裝方法。
例如:
define Package/mountd/install
$(INSTALL_DIR) $(1)/sbin/ $(1)/etc/config/ $(1)/etc/init.d/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mountd $(1)/sbin/