Makefile的介绍与使用(二)
Makefile的介绍与使用(一)中,我简单总结了一下关于子目录下的Makefile的一些运用,而这次的Makefile的介绍与使用(二)中,就对Makefil顶层目录进行一个剖析,简单分析一下Makefile的构造。
就拿最近做的hello目录下的Makefile为示例
include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=hello PKG_VERSION=1 PKG_RELEASE:=1.0 PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/hello SECTION:=utils CATEGORY:=hello TITLE:=hello endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR) endef define Build/Compile $(MAKE) -C $(PKG_BUILD_DIR) \ $(TARGET_CONFIGURE_OPTS) \ CFLAGS="$(TARGET_CFLAGS)" \ CPPFLAGS="$(TARGET_CPPFLAGS)" \ LDFLAGS="$(TARGET_LDFLAGS)" endef define Package/hello/install $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/hello $(1)/bin/ endef $(eval $(call BuildPackage,hello))
首先是include部分
include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
这一小段,是声明调用。例如第二行include $(INCLUDE_DIR)/kernel.mk 说明,要调用目录include下的kerne.mk文件。而第一行的意思是调用OpenWRT根目录下的reles.mk文件。
接着是自定义PKG_xxxxx变量
PKG_NAME —— 通过menuconfig和ipkg可以看到的包的名称
PKG_VERSION —— 正下载的上游版本号
PKG_RELEASE —— 此包所生成的文件的版本
PKG_BUILD_DIR —— 此包编译的地址
官方说明如下:
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" will call the package's original "make install" with prefix set to PKG_INSTALL_DIR
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
接着分析各个define……endef
define Package/hello SECTION:=utils CATEGORY:=hello TITLE:=hello endef
panckage hello应是这样——package/$(PKG_NAME)对应的是上面的PKG_NAME,即这个包的名称;其中的函数的意义为:
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.
define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR) endef
一般情况下,调用的.mk文件里都有所需要使用的宏。但是也有例外,例如这个 Build/Prepare 就是需要我们自己重新定义的宏。
在这里,我们make V=s时,make工具会在编译之前执行 Build/Prepare 宏里的命令。
这里面的要求是创建一个目录在Build_dir目录中,而后将Build_dir目录下所有的东西复制进其中的src目录里。也可以说成是编译前所要做的准备。
define Package/hello/install $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/hello $(1)/bin/ endef
这一段和上面一段是一样的,都是自定义宏。作用是声明所生成的包的安装路径在/bin目录下。即指定了包的安装过程。
define Build/Compile $(MAKE) -C $(PKG_BUILD_DIR) \ $(TARGET_CONFIGURE_OPTS) \ CFLAGS="$(TARGET_CFLAGS)" \ CPPFLAGS="$(TARGET_CPPFLAGS)" \ LDFLAGS="$(TARGET_LDFLAGS)" endef
这一段Build/Compile说明这一段程序是编译包。不做多述。
最后一行代码$(eval $(call BuildPackage,hello)作用于package.mk中,使之生效。(非常重要)