您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“OpenWRT中包的Makefile內容是什么”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“OpenWRT中包的Makefile內容是什么”這篇文章吧。
包里的 Makefile 內容如下:
include $(TOPDIR)/rules.mk PKG_NAME:=helloworld PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Helloworld -- prints a snarky message endef define Package/helloworld/description It's my first package demo. endef define Build/Prepare echo "Here is Package/Prepare" mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Package/helloworld/install echo "Here is Package/install" $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/ endef $(eval $(call BuildPackage,helloworld))
大概我們可以將簡代為如下的結構:
include $(TOPDIR)/rules.mk # 這里定義一系列的 PKG_XX include $(INCLUDE_DIR)/package.mk # 定義各種 Package, Build 宏 $(eval $(call BuildPackage,包名))
下面,我們來一一拆解。
首先,include $(TOPDIR)/rules.mk,也就是將 SDK/rules.mk 文件中的內容導入進來。
TOPDIR就是SDK的路徑。
在 SDK/rules.mk 文件中,定義了許多變量。
我們可以看出,在Makefile中,賦值是用 := ,而不是等號。
比如上面的 BUILD_DIR, INCLUDE_DIR 等,都在這里定義。還有:
還有關于 TARGET_CC, TARGET_CXX 等非常有用的變量定義。
還有 TAR, FIND, INSTALL_BIN, INSTALL_DIR, INSTALL_DATA等等非常重要的變量定義。
官網上指定有如下變量需要設置:
PKG_NAME - The name of the package, as seen via menuconfig and ipkg
PKG_VERSION - The upstream version number that we're downloading
PKG_RELEASE - The version of this package Makefile
PKG_LICENSE - The license(s) the package is available under, SPDX form.
PKG_LICENSE_FILE- file containing the license text
PKG_BUILD_DIR - Where to compile the package
PKG_SOURCE - The filename of the original sources
PKG_SOURCE_URL- Where to download the sources from (directory)
PKG_MD5SUM - A checksum to validate the download
PKG_CAT - How to decompress the sources (zcat, bzcat, unzip)
PKG_BUILD_DEPENDS - Packages that need to be built before this package, but are not required at runtime. Uses the same syntax as DEPENDS below.
PKG_INSTALL - Setting it to "1">
PKG_INSTALL_DIR - Where "make install" copies the compiled files
PKG_FIXUP - ???
PKG_SOURCE_PROTO - the protocol to use for fetching the sources (git, svn)
PKG_REV - the svn revision to use, must be specified if proto is "svn"
PKG_SOURCE_SUBDIR - must be specified if proto is "svn" or "git", e.g. "PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)"
PKG_SOURCE_VERSION - must be specified if proto is "git", the commit hash to check out
PKG_CONFIG_DEPENDS - specifies which config options depend on this package being selected
跟上面的 include $(TOPDIR)/rules.mk 是一樣的。就是把這個文件包含進來。
INCLUDE_DIR這個變量在 rules.mk 里已經定義了:
那就是 SDK/include/package.mk 文件了,打開看看。
主要有以下幾個功能:
如果某個變量我們沒有在上一部分里定義,那里在這個文件里,它就會被指定為默認值,比如:
上面的用 ?= 來表示給未定義的變量賦默認值。比如,如果沒有指定 PKG_MD5SUM,那么就默認為 unknow。
根據上部分用戶自定義的 PKG_XXXX 變量推導出更多相關的變量。
比如:
雖然我沒有看過相關的手冊,根據多年的從業經驗也能看出上面的意思來。
#如果定義了宏,就... ifdef 宏名 ... endif #如果宏相等 ifeq (宏1,宏2) ... endif strip $宏名 #將宏對應的值去除前后的空白字符 VAR += xxxx #在變量 VAR 后面追加 xxxx
我猜大概就是這樣,如果不對請指正。
再比如如下:
就這樣,它為我們提供了大量有價值的變量。
在 Makefile 中,宏的定義格式是:
define XXX/xxxx <宏的實體...> endef
package.mk會把大部分需要的宏都定義好。理想情況下,用戶只需要定義好了 PKG_XXX 之后,不需要再自定義宏,默認的宏就可以滿足需求。
比如Build/Prepare/Default的定義:
Build/Prepare宏是在編譯前進行的,是準備工作。
可以看出,它分了兩種情況:
A,定義了 USE_GIT_TREE,則按git的方式定義。
B,定義了 USB_SOURCE_DIR,則按源碼在本地的方案定義。
最重要的一個宏是 BuildPackage。它會在 Makefile 的最后一行被引用。它的實現也就是在 package.mk 文件里。如下為其源碼:
define BuildPackage $(Build/IncludeOverlay) $(eval $(Package/Default)) #定義在package-defaults.mk文件里 $(eval $(Package/$(1))) #調用用戶自定義的 Package/<包名> 宏 ifdef DESCRIPTION $$(error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description) endif #檢查有沒有定義 Package/<包名>/description宏,如果沒有定義,則以TITLE默認定義一個 ifndef Package/$(1)/description define Package/$(1)/description $(TITLE) endef endif BUILD_PACKAGES += $(1) $(STAMP_PREPARED): $$(if $(QUILT)$(DUMP),,$(call find_library_dependencies,$(DEPENDS))) #檢查 TITLE, CATEGORY, SECTION, VERSION 是否定義,如果沒有定義則報錯 $(foreach FIELD, TITLE CATEGORY SECTION VERSION, ifeq ($($(FIELD)),) $$(error Package/$(1) is missing the $(FIELD) field) endif ) #如果有定義DUMP,那就引入Dumpinfo/Package宏的內部。 #如果沒有,那么就引用 Packaget/<包名>/targets里面的每一個target,如果沒有定義Packaget/<包名>/targets宏,那么將PKG_TARGETS里的每個target取出來, #如果也沒有定義PKG_TARGETS,那就默認ipkg作為target。將每一個target,引用 BuildTarget/$(target)。 $(if $(DUMP), \ $(Dumpinfo/Package), \ $(foreach target, \ $(if $(Package/$(1)/targets),$(Package/$(1)/targets), \ $(if $(PKG_TARGETS),$(PKG_TARGETS), ipkg) \ ), $(BuildTarget/$(target)) \ ) \ ) $(if $(PKG_HOST_ONLY)$(DUMP),,$(call Build/DefaultTargets,$(1))) endef
總結一下語法:
$() 表示要執行的一條語句
$(if 條件, 成立執行, 失敗執行) if條件分支
$(foreach 變量, 成員列表, 執行體) 成員遍歷語句
可以看出,語句是可以嵌套使用的。
$(N) 表示第N個參數
我定要為我們的package定義特定的宏:
Package/<包名> #包的參數
在 Package/<包名> 宏中定義與包相關的信息。
如Package/helloworld宏:
define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Helloworld -- prints a snarky message endef
除了上面所列的 SECTION,CATEGORY,TITLE變量外,還可以定義:
SECTION - 包的種類
CATEGORY - 顯示在menuconfig的哪個目錄下
TITLE - 簡單的介紹
DESCRIPTION - (deprecated) 對包詳細的介紹
URL - 源碼所在的網絡路徑
MAINTAINER - (required for new packages) 維護者是誰(出錯了聯系誰)
DEPENDS - (optional) 需要依事的包,See below for the syntax.
USERID - (optional) a username:groupname pair to create at package installation time.
其它的宏可以選擇性地定義,通常沒必要自己重寫。但有些情況,package.mk中默認的宏不能滿足我們的需求。這時,我們就需要自己重定義宏。
比如,我們在為helloworld寫Makefile時,我們要求在編譯之前,將 SDK/package/helloworld/src/ 路徑下的文件復制到 PKG_BUILD_DIR 所指定的目錄下。
于是我們重新定義Build/Prepare宏:
define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef
如此以來,在我們 make V=s 時,make工具會在編譯之前執行 Build/Prepare 宏里的命令。
再比如,我們要指定包的安裝方法:
define Package/helloworld/install $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/ endef
上面的這個宏就是指定了包的安裝過程。其中 INSTALL_DIR 定義在 rules.mk 文件里。
INSTALL_DIR = install -d -m0755
INSTALL_BIN = install -m0755
$(1)為第一個參數是./configure時的--prefix參數,通常為""
展開之后就是:
define Package/helloworld/install install -d -m0755 /bin install -m0755 $(PKG_BUILD_DIR)/helloworld /bin/ endef
它的意思就一目了然了。
除了上面所列舉的這兩個宏外,在官網上也說明了其它可選的宏:
由該包安裝的配置文件的列表,一行一個文件。
對包描述的純文本
A set of commands to unpack and patch the sources. You may safely leave this undefined.
You can leave this undefined if the source doesn't use configure or has a normal config script, otherwise you can put your own commands here or use "$(call Build/Configure/Default,)">
How to compile the source; in most cases you should leave this undefined, because then the default is used, which calls make. If you want to pass special arguments to make, use e.g. "$(call Build/Compile/Default,FOO=bar)
How to install the compiled source. The default is to call make install. Again, to pass special arguments or targets, use $(call Build/Install/Default,install install-foo) Note that you need put all the needed make arguments here. If you just need to add something to the "install" argument, don't forget the 'install' itself.
For things needed to compile packages against it (static libs, header files), but that are of no use on the target device.
A set of commands to copy files into the ipkg which is represented by the $(1) directory. As source you can use relative paths which will install from the unpacked and compiled source, or $(PKG_INSTALL_DIR) which is where the files in the Build/Install step above end up.
The actual text of the script which is to be executed before installation. Dont forget to include the #!/bin/sh. If you need to abort installation have the script return false.
The actual text of the script which is to be executed after installation. Dont forget to include the #!/bin/sh.
The actual text of the script which is to be executed before removal. Dont forget to include the #!/bin/sh. If you need to abort removal have the script return false.
The actual text of the script which is to be executed after removal. Dont forget to include the #!/bin/sh.
之所以有些宏是以"Package/"開頭,有的又以"Build/",是因為在一個Makefile里生成多個包。OpenWrt默認認為一個Makefile里定義一個包,但我們也可以根據需要將其拆分成多個。所以說,如果我們只希望編譯一次,那么只要有一系列的"Build/"的宏定義就可以了。但是,我們也可以通過添加多個"Package/"宏定義,并調用 BuildPackage,來創建多個包。
在Makefile的最后一行是:
$(eval $(call BuildPackage,helloworld))
最重要的 BuildPackage定義在 package.mk 文件里。見上面 BuildPackage 宏定義。
以上是“OpenWRT中包的Makefile內容是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。