OpenWRT开发之——研究包的Makefile及原理

本文将与大家一起来研究OpenWrt包的Makefile格式以及其工作原理


上面一篇博文中,博主尝试创建一个非常简单的helloworld包,

本文将带大家一起深入地学习一下OpenWrt包的 Makefile。我们不仅要知其然,还要知其所以然。

在上篇博文里,包里的 Makefile 内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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))

大概我们可以将简代为如下的结构:

?
1
2
3
4
5
6
7
8
9
include $(TOPDIR) /rules .mk
 
# 这里定义一系列的 PKG_XX 
 
include $(INCLUDE_DIR) /package .mk
 
# 定义各种 Package, Build 宏
 
$( eval  $(call BuildPackage,包名))

下面,我们来一一拆解。


include $(TOPDIR)/rules.mk

首先,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_XXXX 变量



include $(INCLUDE_DIR)/package.mk

跟上面的 include $(TOPDIR)/rules.mk 是一样的。就是把这个文件包含进来。

INCLUDE_DIR这个变量在 rules.mk 里已经定义了:

那就是 SDK/include/package.mk 文件了,打开看看。

主要有以下几个功能:

(1)它会配置默认的变量

如果某个变量我们没有在上一部分里定义,那里在这个文件里,它就会被指定为默认值,比如:


上面的用 ?= 来表示给未定义的变量赋默认值。比如,如果没有指定 PKG_MD5SUM,那么就默认为 unknow。


(2)推导其它变量

根据上部分用户自定义的 PKG_XXXX 变量推导出更多相关的变量。

比如:


虽然我没有看过相关的手册,根据多年的从业经验也能看出上面的意思来。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
#如果定义了宏,就...
ifdef 宏名
   ...
endif
 
#如果宏相等
ifeq (宏1,宏2)
   ...
endif
 
strip $宏名      #将宏对应的值去除前后的空白字符
 
VAR += xxxx     #在变量 VAR 后面追加 xxxx

我猜大概就是这样,如果不对请指正。

再比如如下:


就这样,它为我们提供了大量有价值的变量。


(3)包含其它mk文件


(4)定义默认宏

在 Makefile 中,宏的定义格式是:

?
1
2
3
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 文件里。如下为其源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
define BuildPackage
   $(Build /IncludeOverlay )
   $( eval  $(Package /Default ))
   $( eval  $(Package/$(1)))
 
   ifdef DESCRIPTION
     $$(error DESCRIPTION:= is obsolete, use Package /PKG_NAME/description )
   endif
 
   ifndef Package/$(1) /description
     define Package/$(1) /description
       $(TITLE)
     endef
   endif
 
   BUILD_PACKAGES += $(1)
   $(STAMP_PREPARED): $$( if  $(QUILT)$(DUMP),,$(call find_library_dependencies,$(DEPENDS)))
 
   $(foreach FIELD, TITLE CATEGORY SECTION VERSION,
     ifeq ($($(FIELD)),)
       $$(error Package/$(1) is missing the $(FIELD) field)
     endif
   )
 
   $( 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 条件, )


自定义宏

<明天待续>


使之生效

$(eval $(call BuildPackage,helloworld))

http://sourceforge.net/u/fehgtehr/profile/index.html
https://www.python.org/users/rethjtjhdhtrh/index.html
http://xifyy3.sourceforge.net/index.html
http://sourceforge.net/projects/xifyy3/index.html
http://vfghsdb.sourceforge.net/index.html
http://sourceforge.net/projects/vfghsdb/index.html
http://sourceforge.net/u/fehgtehr/profile/
https://www.python.org/users/rethjtjhdhtrh/
http://xifyy3.sourceforge.net/
http://sourceforge.net/projects/xifyy3/
http://vfghsdb.sourceforge.net/
http://sourceforge.net/projects/vfghsdb/

https://www.python.org/users/ghtejjtj534645/

https://www.python.org/users/ghtejjtj534645/
https://www.python.org/users/bffg543rretr/
https://www.python.org/users/hytikjyjyrjt/
https://www.python.org/users/dgertherh/
https://www.python.org/users/%E6%96%87%E6%98%8C%E5%93%AA%E9%87%8C%E6%9C%89%E5%AD%A6%E7%94%9F%E5%A6%B9%E6%9C%8D%E5%8A%A1/
https://www.python.org/users/%E6%96%87%E6%98%8C%E6%89%BE%E7%BE%8E%E5%A5%B3%E6%9C%8D%E5%8A%A1/

http://www.python.org/users/ghtejjtj534645/
http://www.python.org/users/ghtejjtj534645/
http://www.python.org/users/bffg543rretr/
http://www.python.org/users/hytikjyjyrjt/
http://www.python.org/users/dgertherh/
http://www.python.org/users/%E6%96%87%E6%98%8C%E5%93%AA%E9%87%8C%E6%9C%89%E5%AD%A6%E7%94%9F%E5%A6%B9%E6%9C%8D%E5%8A%A1/
http://www.python.org/users/%E6%96%87%E6%98%8C%E6%89%BE%E7%BE%8E%E5%A5%B3%E6%9C%8D%E5%8A%A1/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值