关于Pixhawk中 .mk 文件的解读(一)

刚开始接触到 .mk 文件时,一脸懵逼。。。。

但是,渐渐地,我发现,,,

通过不断地search NET、reading Books、对makefile文件有了进一步理解。。。

这里面涉及到了许多Linux知识,而且我将源码拆开,将比较重要的句子在Ubuntu上通过不同形式运行,从而知道语法的意思。。。

希望这篇文章能对初入门者有帮助。。。

E-mail: lizw_jAccount@sjtu.edu.cn
Wechat: lizwgo

注:全文分析均以源码ArduPilot/ardupilot源码包为例,
源码地址: https://github.com/ArduPilot/ardupilot
首先,从 ArduPilot/ardupilot/ArduCopter/Makefile 文件开始执行,其内容是:

include ../mk/apm.mk

所以,我们转入apm.mk文件,下面开始来理解apm.mk文件:

apm.mk (ArduPilot/ardupilot/mk/apm.mk)

# find the mk/ directory, which is where this makefile fragment
# lives. (patsubst strips the trailing slash.)

SYSTYPE         :=  $(shell uname)

将系统的的类型名称赋值给SYSTYPE(uname 是查找电脑全部信息,
包括处理器信息、操作系统信息等等)
-----------------------------------------------------

ifneq ($(findstring CYGWIN, $(SYSTYPE)),) 

判断系统类型是否是CYGWINCygwin 是一个用于 Windows 
的类 UNIX shell)
---------------------------------------------------

  MK_DIR := $(shell cygpath -m ../mk)


若是CYGWIN,在默认情况下,cygpath产生 UNIX 路径名称
-----------------------------------

else
  MK_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))


gun make会自动将所读取得makefile文件的路径都加入到
MAKEFILE_LIST变量中,而且是按照读取的先后顺序添加。
 MAKEFILE_LIST = Makefile(ArduPilot/ardupilot/ArduCopter/Makefile) apm.mk(ArduPilot/ardupilot/mk/apm.mk) 
将当前所读apm.mk文件路径目录部分,并将/用空格代替 
MK_DIR = ArduPilot/ardupilot/mk
------------------------------------------------------------------------

endif

include $(MK_DIR)/environ.mk

转去执行mk/environ.mk文件,执行完后再转回来继续执行apm.mk文件
(***具体请看environ.mk文件分析(见下面)***)
-----------------------------------------------------------------

# short-circuit build for the configure target
ifeq ($(MAKECMDGOALS),configure)
include $(MK_DIR)/configure.mk

else

# short-circuit build for the help target
include $(MK_DIR)/help.mk

# common makefile components
include $(MK_DIR)/targets.mk
include $(MK_DIR)/sketch_sources.mk

ifneq ($(MAKECMDGOALS),clean)

# board specific includes
ifeq ($(HAL_BOARD),HAL_BOARD_SITL)
include $(MK_DIR)/board_native.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_LINUX)
include $(MK_DIR)/board_linux.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_PX4)
include $(MK_DIR)/board_px4.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_VRBRAIN)
include $(MK_DIR)/board_vrbrain.mk
endif

ifeq ($(HAL_BOARD),HAL_BOARD_QURT)
include $(MK_DIR)/board_qurt.mk
endif

endif

endif

environ.mk文件分析

# find key paths and system type
# Save the system type for later use.
SYSTYPE         :=  $(shell uname)

GIT_VERSION ?= $(shell git rev-parse HEAD | cut -c1-8)

获得git版本(具体查询git命令)
------------------

EXTRAFLAGS += -DGIT_VERSION="\"$(GIT_VERSION)\""

# Add missing parts from libc and libstdc++ for all boards
EXTRAFLAGS += -I$(SKETCHBOOK)/libraries/AP_Common/missing

# force LANG to C so awk works sanely on MacOS
export LANG=C

#
# Locate the sketch sources based on the initial Makefile's path
#
SRCROOT         :=  $(realpath $(dir $(firstword $(MAKEFILE_LIST))))

SRCROOT为firstword(ardupilot/ArduCopter/Makefile)的绝对真实路径即为ArduPilot/ardupilot/ArduCopter。
------------------------------------------------------------------------

ifneq ($(findstring CYGWIN, $(SYSTYPE)),)
  # Workaround a $(realpath ) bug on cygwin
  ifeq ($(SRCROOT),)
    SRCROOT :=  $(shell cygpath -m ${CURDIR})
    $(warning your realpath function is not working)
    $(warning > setting SRCROOT to $(SRCROOT))

如果找不到Makefile的绝对路径,就要新建一个,并且发出警告。
---------------------------------

  endif
endif

#
# We need to know the location of the sketchbook.  If it hasn't been overridden,
# try the parent of the current directory.  If there is no libraries directory
# there, assume that we are in a library's examples directory and try backing up
# further.
#
ifeq ($(SKETCHBOOK),) 

判断如果SKETCHBOOK为空(SKETCHBOOK未定义是缺省是空)
------------------------------------

  SKETCHBOOK        :=  $(shell cd $(SRCROOT)/.. && pwd)

找出并显示SKETCHBOOK为SRCROOT(Makefile)的上一层目录,
即为ArduPilot/ardupilot
-------------------------------------------------------------

  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    $(error ERROR: cannot determine sketchbook location - please specify on the commandline with SKETCHBOOK=<path>)
  endif
else
  ifeq ($(wildcard $(SKETCHBOOK)/libraries),)
    $(warning WARNING: sketchbook directory $(SKETCHBOOK) contains no libraries)

上面几行代码都是判断SKETCHBOOK路径下是否存在libraries文件夹
---------------------------------------

  endif
endif
ifneq ($(findstring CYGWIN, $(SYSTYPE)),)
    # Convert cygwin path into a windows normal path
    SKETCHBOOK  := $(shell cygpath ${SKETCHBOOK})
endif

ifneq ($(wildcard $(SKETCHBOOK)/config.mk),)
$(info Reading $(SKETCHBOOK)/config.mk)

输出信息“Reading $(SKETCHBOOK)/config.mk”
-------------------------------------

include $(SKETCHBOOK)/config.mk
endif

ifneq ($(wildcard $(SKETCHBOOK)/developer.mk),)
$(info Reading $(SKETCHBOOK)/developer.mk)
include $(SKETCHBOOK)/developer.mk
endif

#
# Work out the sketch name from the name of the source directory.
#
SKETCH          :=  $(lastword $(subst /, ,$(SRCROOT)))

将SRCROOT路径中/用空格代替即为 ArduPilot ardupilot ArduCopter,
取其最后一个单词,即 SKETCH= ArduCopter
------------------------------------------------------------------------

# Workaround a $(lastword ) bug on cygwin
ifeq ($(SKETCH),)
  WORDLIST      :=  $(subst /, ,$(SRCROOT))
#WORDLIST= ArduPilot    ardupilot     ArduCopter

  SKETCH        :=  $(word $(words $(WORDLIST)),$(WORDLIST))

取SKETCH为WORDLIST最后一个单词ArduCopter
--------------------------------

endif

#
# Work out where we are going to be building things
#
TMPDIR          ?=  /tmp

ifneq ($(findstring px4, $(MAKECMDGOALS)),)

注:make 在执行时会设置一个特殊变量 -- "MAKECMDGOALS" ,该变量记录了命令
行参数指定的终极目标列表,没有通过参数指定终极目标时此变量为空。
------------------------------------------------------------------------

# when building px4 we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it

BUILDROOT       :=  $(SKETCHBOOK)/Build.$(SKETCH)
endif

ifneq ($(findstring vrbrain, $(MAKECMDGOALS)),)
# when building vrbrain we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT       :=  $(SKETCHBOOK)/Build.$(SKETCH)
endif

ifneq ($(findstring vrubrain, $(MAKECMDGOALS)),)
# when building vrbrain we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT       :=  $(SKETCHBOOK)/Build.$(SKETCH)
endif

ifneq ($(findstring vrcore, $(MAKECMDGOALS)),)
# when building vrcore we need all sources to be inside the sketchbook directory
# as the NuttX build system relies on it
BUILDROOT       :=  $(SKETCHBOOK)/Build.$(SKETCH)
endif

ifeq ($(BUILDROOT),)
BUILDROOT       :=  $(abspath $(TMPDIR)/$(SKETCH).build)
endif

ifneq ($(findstring CYGWIN, $(SYSTYPE)),)
  # Workaround a $(abspath ) bug on cygwin
  ifeq ($(BUILDROOT),)
    BUILDROOT   :=  C:$(TMPDIR)/$(SKETCH).build
    $(warning your abspath function is not working)
    $(warning > setting BUILDROOT to $(BUILDROOT))
  else
    BUILDROOT   :=  $(shell cygpath ${BUILDROOT})
  endif
endif

以上几行代码是算出要build的哪里,建立BUILDROOT目录
--------------------------------

ifneq ($(findstring mavlink1, $(MAKECMDGOALS)),)
EXTRAFLAGS += -DMAVLINK_PROTOCOL_VERSION=1
MAVLINK_SUBDIR=v1.0
MAVLINK_WIRE_PROTOCOL=1.0
else
EXTRAFLAGS += -DMAVLINK_PROTOCOL_VERSION=2
MAVLINK_SUBDIR=v2.0
MAVLINK_WIRE_PROTOCOL=2.0

以上几行代码是判断mavlink类型
------------------

endif

ifneq ($(APPDIR),)
# this is a recusive PX4 build
HAL_BOARD = HAL_BOARD_PX4
endif

# handle target based overrides for board type

下面所有代码均是根据开发板类型选择编译目标
---------------------

ifneq ($(findstring px4, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_PX4
endif

ifneq ($(findstring sitl, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_SITL
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring linux, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_NONE
endif

ifneq ($(findstring erleboard, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
endif

ifneq ($(findstring zynq, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_ZYNQ
endif

ifneq ($(findstring pxf, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_PXF
endif

ifneq ($(findstring bebop, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_BEBOP
endif


ifneq ($(findstring navio, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_NAVIO
endif

ifneq ($(findstring raspilot, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_RASPILOT
endif

ifneq ($(findstring erlebrain2, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2
endif

ifneq ($(findstring bbbmini, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_BBBMINI
endif

ifneq ($(findstring minlure, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_MINLURE
endif

ifneq ($(findstring vrbrain, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_VRBRAIN
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring vrubrain, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_VRBRAIN
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring vrcore, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_VRBRAIN
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring bhat, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_BH
endif

ifneq ($(findstring qflight, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
endif

ifneq ($(findstring qurt, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_QURT
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring pxfmini, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_PXFMINI
endif

# default to SITL
ifeq ($(HAL_BOARD),)
HAL_BOARD = HAL_BOARD_SITL
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif

ifneq ($(findstring navio2, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_LINUX
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_LINUX_NAVIO2
endif

总之:


“`
environ.mk文件里实现的是查找SKETCHBOOK的位置,根据源文件路径判断
SKETCH名称,算出要build的哪里,建立BUILDROOT目录,判断mavlink类型,根
据编译参数确定HAL_BOARD类型,等等为系统实现做基础工作。当执行完environ.mk
文件后,由转回去执行apm.mk文件。

接下来在 关于Pixhawk中 .mk 文件的解读(二)中会继续解读。。。。。。。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值