1 簡(jiǎn)介
OpenWrt是一個(gè)比較完善的嵌入式Linux開發(fā)平臺(tái),在無(wú)線路由器應(yīng)用上已有4000多個(gè)軟件包。我們可以在其基礎(chǔ)上增加軟件包,以擴(kuò)大其應(yīng)用范圍。在OpenWrt中增加軟件包極其方便,按照OpenWrt的約定就可以很簡(jiǎn)單的完成。加入的軟件包可以是網(wǎng)上可下載的開源軟件或自行開發(fā)的軟件。為加入軟件包需要在package目錄下創(chuàng)建一個(gè)目錄,以包含該軟件包的各種信息和與OpenWrt建立聯(lián)系的文件。然后創(chuàng)建一個(gè)Makefile與OpenWrt建立聯(lián)系,Makefile需要遵循OpenWrt的約定。另外可以創(chuàng)建一個(gè)patchs目錄保存patch文件,對(duì)下載的源代碼進(jìn)行適量修改。
2 Makefile語(yǔ)法
下面來(lái)介紹Makefile的基本約定。
2.1 引入文件
OpenWrt使用三個(gè)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文件對(duì)于軟件包為內(nèi)核時(shí)是不可缺少,$(INCLUDE_DIR)/package.mk一般在軟件包的基本信息完成后再引入。
2.2 編寫軟件包的基本信息
軟件包的信息均以PKG_開頭,其意思和作用如下:PKG_NAME表示軟件包名稱,將在menuconfig和ipkg可以看到。PKG_VERSION表示軟件包版本號(hào)。
PKG_RELEASE表示Makefile的版本號(hào)。
PKG_SOURCE表示源代碼的文件名。
PKG_SOURCE_URL表示源代碼的下載網(wǎng)站位置。@SF表示在sourceforge網(wǎng)站,@GNU表示在GNU網(wǎng)站,還有@GNOME、@KERNEL。
PKG_MD5SUM表示源代碼文件的效驗(yàn)碼。用于核對(duì)軟件包是否正確下載。
PKG_CAT表示源代碼文件的解壓方法。包括zcat,bzcat,unzip等。
PKG_BUILD_DIR表示軟件包編譯目錄。它的父目錄為**(BUILD_DIR)。如果不指定,默認(rèn)為**(BUILD_DIR)/(PKG_NAME)/(PKG_VERSION)。
2.3 編譯包定義
應(yīng)用程序和內(nèi)核驅(qū)動(dòng)模塊的定義不一樣。應(yīng)用程序軟件包使用Package,內(nèi)核驅(qū)動(dòng)模塊使用KernelPackage。
1)應(yīng)用程序編譯包定義
應(yīng)用程序的編譯包以Package/開頭,然后接著軟件名,在Package定義中的軟件名可以與軟件包名不一樣,而且可以多個(gè)定義。下面使用**(PKG_NAME)只是做一個(gè)標(biāo)示,并非真正使用**(PKG_NAME),如Package/$(PKG_NAME)。
SECTION表示包的類型,預(yù)留。
CATEGORY表示分類,在make menuconfig的菜單下將可以找到。
TITLE用于軟件包的簡(jiǎn)短描述。
DESCRIPTION用于軟件包的詳細(xì)描述,已放棄使用。如果使用DESCRIPTION將會(huì)提示“errorDESCRIPTION:=isobsolete,usePackage/PKG_NAME/description”。
URL表示軟件包的下載位置。
MAINTAINER表示維護(hù)者,選項(xiàng)。
DEPENDS表示與其他軟件的依賴。即如編譯或安裝需要其他軟件時(shí)需要說(shuō)明。如果存在多個(gè)依賴,則每個(gè)依賴需要用空格分開。依賴前使用+號(hào)表示默認(rèn)為顯示,即對(duì)象沒(méi)有選中時(shí)也會(huì)顯示,使用@則默認(rèn)為不顯示,即當(dāng)依賴對(duì)象選中后才顯示。
在用戶空間的應(yīng)用程序軟件包中沒(méi)有內(nèi)核驅(qū)動(dòng)模塊的AUTOLOAD參數(shù)。如果應(yīng)用軟件需要在boot時(shí)自動(dòng)運(yùn)行,則需要在/etc/init.d中增加相應(yīng)的腳本文件。腳本文件需要START參數(shù),說(shuō)明在boot時(shí)的優(yōu)先級(jí),如果在boot過(guò)程啟動(dòng)后再關(guān)閉,則需要進(jìn)一步設(shè)置STOP參數(shù)。
如果STOP參數(shù)存在,其值必須大于START。腳本文件需要start()和stop()兩個(gè)函數(shù),start()是執(zhí)行程序,stop()是關(guān)閉程序。關(guān)閉程序一般需要執(zhí)行killall命令。由/etc/rc.d/S10boot知道,裝載內(nèi)核驅(qū)動(dòng)模塊的優(yōu)先級(jí)為10,需要使用自己設(shè)計(jì)的內(nèi)核驅(qū)動(dòng)模塊的程序其START的值必須大于10。同樣由/etc/rc.d/S40network知道,使用網(wǎng)絡(luò)通信的程序其START的值必須大于40。
Package/$(PKG_NAME)/conffiles
本包安裝的配置文件,一行一個(gè)。如果文件結(jié)尾使用/,則表示為目錄。用于備份配置文件說(shuō)明,在sysupgrade命令執(zhí)行時(shí)將會(huì)用到。
Package/$(PKG_NAME)/description
軟件包的詳細(xì)描述,取代前面提到的DESCRIPTION詳細(xì)描述。
Build/Prepare
編譯準(zhǔn)備方法,對(duì)于網(wǎng)上下載的軟件包不需要再描述。對(duì)于非網(wǎng)上下載或自行開發(fā)的軟件包必須說(shuō)明編譯準(zhǔn)備方法。一般的準(zhǔn)備方法為:
defineBuild/Prepare
mkdir-p$(PKG_BUILD_DIR)
(CP)./src/*(PKG_BUILD_DIR)/
Endef
按OpenWrt的習(xí)慣,一般把自己設(shè)計(jì)的程序全部放在src目錄下。
Build/Configure
在Automake中需要進(jìn)行./configure,所以本配置方法主要針對(duì)需要配置的軟件包而設(shè)計(jì),一般自行開發(fā)的軟件包可以不在這里說(shuō)明。需要使用本定義的情況,可參考dropbear。
Build/Compile
編譯方法,沒(méi)有特別說(shuō)明的可以不予以定義。如果不定義將使用默認(rèn)的編譯方法
Build/Compile/Default。
自行開發(fā)的軟件包可以考慮使用下面的定義。
define Build/Compile
(MAKE)-C(PKG_BUILD_DIR)\\
(TARGET_CONFIGURE_OPTS)CFLAGS="(TARGET_CFLAGS)
-I$(LINUX_DIR)/include"
endef
Package/$(PKG_NAME)/install
軟件包的安裝方法,包括一系列拷貝編譯好的文件到指定位置。調(diào)用時(shí)會(huì)帶一個(gè)參數(shù),就是嵌入系統(tǒng)的鏡像文件系統(tǒng)目錄,因此$(1)表示嵌入系統(tǒng)的鏡像目錄。一般可以采用下面的方法:
definePackage/$(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意思是創(chuàng)建所屬用戶可讀寫和執(zhí)行,其他用戶可讀可執(zhí)行的目錄。
INSTALL_BIN:=install-m0755意思編譯好的文件存放到鏡像文件目錄。
如果用戶空間的應(yīng)用軟件在boot時(shí)要自動(dòng)運(yùn)行,則需要在安裝方法說(shuō)明中增加自動(dòng)運(yùn)行的腳本文件安裝和配置文件安裝方法。
例如:
definePackage/mountd/install
(INSTALL_DIR)(1)/sbin/(1)/etc/config/(1)/etc/init.d/
(INSTALL_BIN)(PKG_BUILD_DIR)/mountd$(1)/sbin/
(INSTALL_DATA)./files/mountd.config(1)/etc/config/mountd
(INSTALL_BIN)./files/mountd.init(1)/etc/init.d/mountd
endef
安裝文件放在files子目錄下,不要與源代碼文件目錄src混在一起,以提高可讀性。使用清晰的文件擴(kuò)展名,更方便安裝識(shí)別文件。
Package/$(PKG_NAME)/preinst
軟件包安裝前處理方法,使用腳本語(yǔ)言,因此定義的第一行需要下面的格式
#!/bin/sh //調(diào)用時(shí)帶入的參數(shù)為嵌入式系統(tǒng)的鏡像目錄。
Package/$(PKG_NAME)/postinst//軟件包安裝后處理方法,使用腳本語(yǔ)言。
Package/$(PKG_NAME)/prerm//軟件包刪除前處理方法,使用腳本語(yǔ)言。
Package/$(PKG_NAME)/postrm//軟件包刪除后處理方法,使用腳本語(yǔ)言。
2)內(nèi)核驅(qū)動(dòng)模塊包定義
Linux分為內(nèi)核空間和用戶空間。開發(fā)者開發(fā)的內(nèi)核部分可以直接加入Linux的Kernel程序,也可以生成內(nèi)核模塊以便需要時(shí)裝入內(nèi)核。OpenWrt一般希望開發(fā)者生成內(nèi)核模塊,在Linux啟動(dòng)后自動(dòng)裝載或手工使用insmod命令裝載。內(nèi)核模塊使用KernelPackage開頭,其他與一般應(yīng)用軟件包基本相同。
在內(nèi)核驅(qū)動(dòng)模塊定義中增加了:
SUBMENU表示子菜單位置,在**(INCLUDE)/kernel.mk對(duì)內(nèi)核模塊定義了CATEGORY為kernelmodules,所以內(nèi)核模塊在menuconfig中的主菜單為kernelmodules,然后有下一級(jí)子菜單**(SUBMENU)。在子菜單下可以看到以kmod-$(PKG_NAME)項(xiàng)目。
DEFAULT表示直接編入內(nèi)核或產(chǎn)生內(nèi)核模塊,y表示直接編入內(nèi)核,m表示產(chǎn)生內(nèi)核模塊。
AUTOLOAD表示自動(dòng)裝入內(nèi)核,一般表示方法為:
AUTOLOAD:=(callAutoLoad,(PRIORITY),$(AUTOLOAD_MODS))
AutoLoad的第一個(gè)參數(shù)**(PRIORITY)為優(yōu)先級(jí),01為最優(yōu)先,99為最后裝載。有關(guān)自動(dòng)裝載可以在/etc/modules.d目錄下看到,第二個(gè)參數(shù)**(AUTOLOAD_MODS)模塊名,每個(gè)模塊名以空格符分隔。即可同時(shí)裝載多個(gè)內(nèi)核模塊。
在開發(fā)過(guò)程最好不要使用自動(dòng)裝載,經(jīng)過(guò)嚴(yán)格調(diào)試后再使用,可以減輕調(diào)試的工作量。
2.4 使用定義
完成前面定義后,必須使用eval函數(shù)實(shí)現(xiàn)各種定義。其格式為:對(duì)于一般應(yīng)用軟件包
(eval(callPackage,$(PKG_NAME)))
或?qū)τ趦?nèi)核驅(qū)動(dòng)模塊
(eval(callKernelPackage,$(PKG_NAME)))
如果一個(gè)軟件包有多個(gè)程序,例如:一個(gè)應(yīng)用程序有自己的內(nèi)核驅(qū)動(dòng)模塊,上面使用的PKG_NAME需要靈活變通。eval函數(shù)可以設(shè)計(jì)多個(gè)。也可以當(dāng)成多個(gè)軟件包處理。
如果看到這里,覺得一頭霧水,還是不知道怎么使用。沒(méi)有關(guān)系,請(qǐng)繼續(xù)看后面的章節(jié),我們會(huì)舉大量的例子,來(lái)告訴大家如何使用這些語(yǔ)法。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19084瀏覽量
304484 -
Linux
+關(guān)注
關(guān)注
87文章
11261瀏覽量
209227 -
源代碼
+關(guān)注
關(guān)注
96文章
2944瀏覽量
66723 -
軟件包
+關(guān)注
關(guān)注
0文章
104瀏覽量
11590 -
OpenWrt
+關(guān)注
關(guān)注
10文章
130瀏覽量
39294
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論