Openwrt package Makefile
在"Openwrt main Makefile"章節(jié)里面有說道主Makefile會(huì)通過
include package/Makefile
調(diào)用package下的Makefile辆亏,package下的Makefile又會(huì)調(diào)用調(diào)用$(call subdir,package)
遍歷package子目錄下的Makefile兔甘。package下的Makefile是源碼里面就提供的,不會(huì)修改异袄,但package子目錄下的Makefile確是我們經(jīng)常要打交道的七咧,本章節(jié)將對(duì)其進(jìn)行說明。
我們隨便打開package下面的子目錄,通常會(huì)發(fā)現(xiàn)幾樣?xùn)|西:
- package/$(PKG_NAME)/Makefile [必備]
- package/$(PKG_NAME)/src/ [可選]
- package/$(PKG_NAME)/patches/ [可選]
- package/$(PKG_NAME)/files/ [可選]
src目錄、patches目錄斋陪、files目錄都是可選的,src目錄存放的是該功能模塊的源代碼置吓,pactches目錄通常包括bug修復(fù)和對(duì)可執(zhí)行文件體積的優(yōu)化无虚,files目錄通常是運(yùn)行腳本包括配置文件等。你也可能看到其它目錄衍锚,因?yàn)橹灰贛akefile文件中指明友题,目錄名字是可以任取的。
Makefile文件最關(guān)鍵戴质,一般來說它提供了下載度宦、編譯、安裝這個(gè)軟件包的步驟告匠。
當(dāng)我們打開package子目錄的Makefile文件戈抄,很難認(rèn)出這是一個(gè)Makefile。它的格式跟一般的Makefile不一樣后专,因?yàn)樗墓δ芨胀∕akefile就是不一樣的划鸽,它是一種編寫方便的模板。
這里戚哎,以package/bridge/Makefile文件為例:
include $(TOPDIR)/rules.mk
PKG_NAME:=bridge
PKG_VERSION:=1.0.6
PKG_RELEASE:=1
PKG_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:=zcat
include $(INCLUDE_DIR)/package.mk
define Package/bridge
SECTION:=base
CATEGORY:=Network
DEFAULT:=y
TITLE:=Ethernet bridging configuration utility
DESCRIPTION:=Ethernet bridging configuration utility\\\
Manage ethernet bridging; a way to connect networks together to\\\
form a larger network.
URL:=http://bridge.sourceforge.net/
endef
define Build/Configure
$(call Build/Configure/Default,--with-linux-headers=$(LINUX_DIR))
endef
define Package/bridge/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,bridge))
1.包含全局變量
首先在Makefile中的第一行一定要包含下面這個(gè)命令裸诽,這是Makefile的一些全局變量的相關(guān)定義
include $(TOPDIR)/rules.mk
2.軟件包變量
建立一個(gè)軟件包不需要太多工作;大部分工作都隱藏在其它的makefiles中型凳,編寫工作被抽象成對(duì)幾個(gè)變量的賦值丈冬。
PKG_NAME : 軟件包的名字, 在 menuconfig 和 ipkg 顯示
PKG_VERSION :軟件包的版本,主干分支的版本正是我們要下載的
PKG_RELEASE :這個(gè) makefile 的擦寫版本
PKG_BUILD_DIR :編譯軟件包的目錄
PKG_SOURCE :要下載的軟件包的名字甘畅,一般是由 PKG_NAME 和 PKG_VERSION 組成
PKG_SOURCE_URL :下載這個(gè)軟件包的鏈接
PKG_MD5SUM :軟件包的 MD5 值
PKG_CAT :解壓軟件包的方法 (zcat, bzcat, unzip)
PKG_BUILD_DEPENDS :需要預(yù)先構(gòu)建的軟件包埂蕊,但只是在構(gòu)建本軟件包時(shí),而不是運(yùn)行的時(shí)候疏唾。它的語法和下面的DEPENDS一樣蓄氧。
3.BuildPackage相關(guān)的宏定義
1.描述軟件包在menuconfig和ipkg中的信息,可以定義如下變量:
define Package/< PKG_NAME >
SECTION : 軟件包類型
CATEGORY : 軟件包在menuconfig里的位置荸实,如Network, Utilities
SUBMENU : menuconfig中軟件包所屬的二級(jí)目錄匀们,如dial-in/up
DEFAULT: 默認(rèn)的編譯模式,m=編譯成模塊准给,y=編譯到鏡像泄朴,n或者不加不編譯,[依賴
包 兩個(gè)之間通過空格分隔 前面加+為默認(rèn)顯示 選中該軟件包自動(dòng)選中依
賴包 不加+為默認(rèn)不顯示 選中依賴包才顯示]
TITLE : 軟件包標(biāo)題
DESCRIPTION : 軟件包的詳細(xì)說明露氮,由于存在bug祖灰,現(xiàn)在已經(jīng)放棄
URL : 軟件的原始位置,一般是軟件作者的主頁
MAINTAINER : (optional) 軟件包維護(hù)人員
DEPENDS : (optional) 依賴項(xiàng)畔规,運(yùn)行本軟件依賴的其他包
endif
2.配置說明
define Build/Configure (可選)
在Automake中需要進(jìn)行./configure局扶,所以本配置方法主要針對(duì)需要配置的軟件
包而設(shè)計(jì),一般自行開發(fā)的軟件包可以不在這里說明。
endif
3.軟件包安裝
define Package/install
軟件包的安裝方法三妈,包括一系列拷貝編譯好的文件到指定位置畜埋。調(diào)用時(shí)會(huì)帶一
個(gè)參數(shù),就是嵌入系統(tǒng)的鏡像文件系統(tǒng)目錄畴蒲,因此$(1)表示嵌入系統(tǒng)的鏡像目
錄悠鞍。一般可以采用下面的方法:
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/
endif
4.其他BuildPackage相關(guān)的宏定義
上面列出的三個(gè)是在bridge這個(gè)模塊下面用的宏定義,其他還有很多其他的定義模燥,我們也可以了解下咖祭,再其他情況可能也會(huì)用到。
1.編譯準(zhǔn)備
define Build/Prepare (可選)
對(duì)于網(wǎng)上下載的軟件包不需要再描述蔫骂,對(duì)于非網(wǎng)上下載或自行開發(fā)的軟件包
必須說明編譯準(zhǔn)備方法么翰,如下:
mkdir -p $(PKG_BUILD_DIR)
創(chuàng)建編譯目錄,也就是$(TOPDIR)/build_dir/target-<ARCH>*/$(PKG_NAME)-%(PKG_VERSION)
$(CP) ./src/* $(PKG_BUILD_DIR)/
將軟件包的src的源碼文件拷貝到編譯目錄去
endif
2.編譯源代碼
define Build/Compile (可選)
默認(rèn)是編譯源碼里面的Makefile辽旋,如果你想傳遞一些參數(shù)比如環(huán)
境變量什么的浩嫌,那就可以定義,編譯方法戴已,沒有特別說明的可以不予以定義固该。如果不
定義將使用默認(rèn)的編譯方法Build/Compile/Default
自行開發(fā)的軟件包可以考慮使用下面的定義。
$(MAKE) -C $(PKG_BUILD_DIR) \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) -I$(LINUX_DIR)/include"
endif
3.安裝之前執(zhí)行的腳本
define Package/ $(PKG_NAME)/ preinst (可選)
軟件安裝之前被執(zhí)行的腳本糖儡,別忘了在第一句加上#!/bin/sh伐坏,如果腳本執(zhí)行完畢要取消 安裝過程,直接讓它返回false即可握联。
#!/bin/sh
.........
exit 0
endif
4.安裝之后執(zhí)行的腳本
define Package/ $(PKG_NAME)/ postinst (可選)
軟件安裝之后被執(zhí)行的腳本桦沉,別忘了在第一句加上#!/bin/sh。
#!/bin/sh
.........
exit 0
endif
5.刪除之前被執(zhí)行的腳本
define Package/ $(PKG_NAME)/ prerm (可選)
軟件刪除之前被執(zhí)行的腳本金闽,別忘了在第一句加上#!/bin/sh纯露。如果腳本執(zhí)行完畢要取消 刪除過程,直接讓它返回false即可代芜。
#!/bin/sh
.........
exit 0
endif
6.刪除之后被執(zhí)行的腳本
define Package/ $(PKG_NAME)/ postrm (可選)
軟件刪除之后被執(zhí)行的腳本埠褪,別忘了在第一句加上#!/bin/sh。
#!/bin/sh
.........
exit 0
endif
為什么一些定義是"Package/"前綴挤庇,另一些定義卻是"Build"前綴钞速?這是因?yàn)镺penwrt支持一個(gè)特性:從單個(gè)源代碼構(gòu)建多個(gè)軟件包。OpenWrt工作在一個(gè)Makefile對(duì)應(yīng)一個(gè)源代碼的假設(shè)之上嫡秕,但是你可以把編譯生成的程序分割成任意多個(gè)軟件包渴语。因?yàn)榫幾g只要一次,所以使用全局的"Build"定義是最合適的昆咽。然后你可以增加很多“Package/"定義驾凶,為各軟件包分別指定安裝方法牙甫。
5.軟件包的實(shí)現(xiàn)
完成前面定義后,必須使用eval函數(shù)實(shí)現(xiàn)各種定義调违。這是最為關(guān)鍵的BuildPackage宏窟哺,它是在$(INCLUDE_DIR)/package.mk文件里定義的。BuildPackage宏只要求一個(gè)參數(shù)翰萨,即要編譯的軟件包名脏答,在本例中是"bridge"糕殉。
對(duì)于一般軟件包$(eval $(call Package,$(PKG_NAME)))
對(duì)于內(nèi)核模塊$(eval $(call KernelPackage,$(PKG_NAME)))
如果一個(gè)軟件包有多個(gè)程序亩鬼,eval函數(shù)也可以設(shè)計(jì)多個(gè)軟件包處理。
在編輯好Makefile文件阿蝶,并放到指定目錄后雳锋,這個(gè)新的軟件包將在下次執(zhí)行make menuconfig
時(shí)出現(xiàn),你可以選擇這個(gè)軟件包羡洁,保存退出玷过,編譯,就把一個(gè)軟件包成功移植到OpenWrt中了筑煮,具體例子將在“Openwrt add function module to package”章節(jié)就行說明辛蚊。
Openwrt package Makefile的分析就到這邊,有感悟時(shí)會(huì)持續(xù)會(huì)更新真仲。
注:以上內(nèi)容都是本人在學(xué)習(xí)過程積累的一些心得袋马,難免會(huì)有參考到其他文章的一些知識(shí),如有侵權(quán)秸应,請(qǐng)及時(shí)通知我虑凛,我將及時(shí)刪除或標(biāo)注內(nèi)容出處,如有錯(cuò)誤之處也請(qǐng)指出软啼,進(jìn)行探討學(xué)習(xí)桑谍。文章只是起一個(gè)引導(dǎo)作用,詳細(xì)的數(shù)據(jù)解析內(nèi)容還請(qǐng)查看Openwrt相關(guān)教程祸挪,感謝您的查閱锣披。