以ArduCopter为例
进入ArduCopter目录查找Makefile文件,只有一句话“include …/mk/apm.mk”,说明只需要看“mk/apm.mk”.
1. mk/apm.mk
//判断系统类型linux或windows,此处为linux
SYSTYPE := $(shell uname)
//判断windows还是linux
ifneq ($(findstring CYGWIN, $(SYSTYPE)),)
MK_DIR := $(shell cygpath -m ../mk) //win系统下,定义编译路径MK_DIR="../ardupilot/mk"
else
MK_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) //linux系统
endif
include $(MK_DIR)/environ.mk //包含../mk/environ.mk文件
//若输入make configure,则执行“../mk/configure.mk”文件,configure.mk是用于waf编译器的,由于configure.mk是空的,所有waf命令暂时不起作用
ifeq ($(MAKECMDGOALS),configure)
include $(MK_DIR)/configure.mk
else
//因此make编译器使用“../mk/help.mk”、“../mk/targets.mk”、“../mk/sketch_sources.mk”文件,解析MAKECMDGOALS
include $(MK_DIR)/help.mk
include $(MK_DIR)/targets.mk
include $(MK_DIR)/sketch_sources.mk
//如果不输入make clean
ifneq ($(MAKECMDGOALS),clean)
//HAL_BOARD=SITL,则执行“board_native.mk”
ifeq ($(HAL_BOARD),HAL_BOARD_SITL)
include $(MK_DIR)/board_native.mk
endif
//若HAL_BOARD=LINUX,则执行“board_linux.mk”
ifeq ($(HAL_BOARD),HAL_BOARD_LINUX)
include $(MK_DIR)/board_linux.mk
endif
//若HAL_BOARD=PX4,则执行“board_px4.mk”
ifeq ($(HAL_BOARD),HAL_BOARD_PX4)
include $(MK_DIR)/board_px4.mk
endif
//若HAL_BOARD=VRBRAIN,则执行“board_vrbrain.mk”
ifeq ($(HAL_BOARD),HAL_BOARD_VRBRAIN)
include $(MK_DIR)/board_vrbrain.mk
endif
//若HAL_BOARD=QURT,则执行“board_qurt.mk”
ifeq ($(HAL_BOARD),HAL_BOARD_QURT)
include $(MK_DIR)/board_qurt.mk
endif
endif
endif
总结:
编译管理目录:MK_DIR="…/ardupilot/mk"
make编译文件: environ.mk、help.mk、targets.mk、sketch_sources.mk
2. mk/environ.mk
SRCROOT := $(realpath $(dir $(firstword $(MAKEFILE_LIST))))
//MAKEFILE_LIST是makefile语法的变量,指make用到的makefile文件,由于我们是在ArduCopter中编译,根据ArduCopter/Makefile进行的,dir指返回路径,那么SRCROOT=../ardupilot/ArduCopter
ifeq ($(SKETCHBOOK),)
SKETCHBOOK := $(shell cd $(SRCROOT)/.. && pwd)
//SKETCHBOOK是SRCROOT的上一级目录,即/arudpilot”
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)
endif
endif
//ardupilot/ArduCopter存在config.mk文件,读取该文件
ifneq ($(wildcard $(SKETCHBOOK)/config.mk),)
$(info Reading $(SKETCHBOOK)/config.mk)
include $(SKETCHBOOK)/config.mk
endif
//ardupilot/ArduCopter存在developer.mk文件,读取该文件
ifneq ($(wildcard $(SKETCHBOOK)/developer.mk),)
$(info Reading $(SKETCHBOOK)/developer.mk)
include $(SKETCHBOOK)/developer.mk
endif
//SRCROOT=../ardupilot/ArduCopter,SKETCT=ArduCopter
SKETCH := $(lastword $(subst /, ,$(SRCROOT)))
# Workaround a $(lastword ) bug on cygwin
ifeq ($(SKETCH),)
WORDLIST := $(subst /, ,$(SRCROOT))
SKETCH := $(word $(words $(WORDLIST)),$(WORDLIST))
endif
//编译文件存放路径BUILDROOT=ArduCopter/Build.ArduCopter
BUILDROOT := $(SKETCHBOOK)/Build.$(SKETCH)
endif
//若编译目标为mavlink1
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
endif
//编译目标含有px4,则HAL_BOARD=PX4
ifneq ($(findstring px4, $(MAKECMDGOALS)),)
HAL_BOARD = HAL_BOARD_PX4
endif
//若编译目标为空,默认编译SITL
ifeq ($(HAL_BOARD),)
HAL_BOARD = HAL_BOARD_SITL
HAL_BOARD_SUBTYPE = HAL_BOARD_SUBTYPE_NONE
endif
总结:
主要定义以下环境变量:
编译源文件根目录SRCROOT="/ardupilot/AruCopter"
SKETCHBOOK=“/ardupilot”
SKETCT=ArduCopter
BUILDROOT=/ArduCopter/Build.ArduCopter
HAL_BOARD=PX4
3. mk/help.mk”
讲解了make编译命令。
5. mk/targets.mk”
6. mk/modules.mk
包含 check_modules.sh,可忽略
7. mk/mavgen.mk
关于mavlink
MAVLINK_DIR := $(SKETCHBOOK)/modules/mavlink/
MESSAGE_DEFINITIONS := $(SKETCHBOOK)/modules/mavlink/message_definitions/v1.0
MAVLINK_HEADERS := $(BUILDROOT)/libraries/GCS_MAVLink/include/mavlink/$(MAVLINK_SUBDIR)/ardupilotmega/mavlink.h $(wildcard $(BUILDROOT)/libraries/GCS_MAVLink/include/mavlink/$(MAVLINK_SUBDIR)/,*.h) $(wildcard $(BUILDROOT)/libraries/GCS_MAVLink/include/mavlink/$(MAVLINK_SUBDIR)/ardupilotmega,*.h)
MAVLINK_OUTPUT_DIR := $(BUILDROOT)/libraries/GCS_MAVLink/include/mavlink/$(MAVLINK_SUBDIR)
主要定义mavlink协议编译环境变量:
MAVLINK_DIR=/ardupilot/modules/mavlink/
MESSAGE_DEFINITIONS=/ardupilot/modules/mavlink/message_definitions/v1.0
MAVLINK_OUTPUT_DIR = /ArduCopter/Build.ArduCopter/libraries/GCS_MAVLink/include/mavlink/$(MAVLINK_SUBDIR)
8. /mk/sketch_sources.mk
SRCSUFFIXES = *.cpp //指定后缀为.cpp的所有文件
MAKE_INC=$(wildcard $(SRCROOT)/make.inc) //打开ArduCopter/make.inc文件
GLOBAL_MAKE_INC=$(wildcard $(SKETCHBOOK)/mk/make.inc) //ardupilot/mk/make.inc
SKETCHSRCS := $(wildcard $(addprefix $(SRCROOT)/,$(SRCSUFFIXES))) //ArduCopter下所有cpp文件
SKETCHCPP := $(SRCROOT)/$(SKETCH).cpp
//ArduCopter/ArduCopter.cpp
include $(MAKE_INC) //包含MAKE_INC
include $(GLOBAL_MAKE_INC) //包含GLOBAL_MAKE_INC
LIBTOKENS := $(LIBRARIES)
//若为SITL板,添加libraries/AP_HAL_SITL、libraries/SITL
ifeq ($(HAL_BOARD),HAL_BOARD_SITL)
LIBTOKENS += \
AP_HAL_SITL \
SITL
endif
//若为PX4板,添加libraries/AP_HAL_PX4
ifeq ($(HAL_BOARD),HAL_BOARD_PX4)
LIBTOKENS += \
AP_HAL_PX4
endif
//ardupilot/libraries/为LIBTIKENS的前缀
SKETCHLIBS := $(wildcard $(addprefix $(SKETCHBOOK)/libraries/,$(LIBTOKENS)))
主要:
指定ArduCopter下所有.cpp文件为编译源文件,makefile文件为ArduCopter/make.inc,顶层makefile文件为ardupilot/mk/make.inc,添加共享库文件为ardupilot/libraries。
9. 编译总结
(1) ArduCopter编译只涉及到ardupilot/ArduCopter中所有.cpp文件;
(2)ArduCopter中有一个make.inc文件,指定需链接的库文件目录为ardupilot/libraries,根据实际情况添加;
(3)ardupilot/mk/make.inc为公共的库文件
因此如果ardupilot/libraries目录下新增了某些文件夹,需要被ArduCopter使用,只需要在ArduCopter/make