后面引用$$等导致乱码,进入编辑模式没有问题
https://github.com/breakerthb/LinuxPrograming/blob/master/MakefileDebug.md (怎样打印makefile log)
http://www.ruanyifeng.com/blog/2015/02/make.html (自动化变量的意思)
https://blog.csdn.net/shareyao/article/details/5610638 (为什么引入*.d文件)
https://blog.csdn.net/fengbingchun/article/details/80960916 (编译参数的意思)
引入shell 调用makefile否则有些变量的内容
google_hexagonv66_slpi-see, hidl-gen
make: *** No rule to make target 'hidl-gen'. Stop.
$(MAKECMDGOALS)变量的内容变为hidl-gen,导致失败,引入shell没有问题,原因不懂。
静下心来想想,makefile好像也不难。关键要学会打印log. makefile 中需要写的大多是 -I(头文件搜索路径), -D(变量的定义)
添加要编译的源文件,其他只需配置一次就OK。
makefile由变量、rule和命令组成。
makefile中源文件由变量表示,变量包含所有的源文件,源文件使用patsubset等函数处理成对应目标文件、depend文件等;
然后使用自动推动规则进行编译、链接等。
其中编译链接的参数需要传入到compiler and linker.
shell中export CHRE_VARIANT_MK_INCLUDES = xxx就是对变量CHRE_VARIANT_MK_INCLUDES赋值, shell中调用的makefile可以使用、展开改变量。
首先设置环境变量,设置当前路径为后面编译等文件的基础描述路径;
然后包含编译chre variant的makefile,根据variant makefile的内容或者编译环境等如host os 设置common_flags
# Optional audio support.
ifeq ($(CHRE_AUDIO_SUPPORT_ENABLED), true)
COMMON_CFLAGS += -DCHRE_AUDIO_SUPPORT_ENABLED
endif
# Symbols required by the runtime for conditional compilation.
COMMON_CFLAGS += -DCHRE_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG
COMMON_CFLAGS += -DNANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG
为什么叫common 这里说的common是对不同chre变体而言的?是的,对不同的变体控制audio 是否enabled都是使用-DCHRE_AUDIO_SUPPORT_ENABLED, 主makefile只是设置COMMON_CFLAGS的一部分。
defs.mk定义了变量$OUT和$BR_TO_LE_SCRIPT
java层是大端而slpi dsp上是小端,BR_TO_LE_SCRIPT何时使用?native(android)是大端还是小端?
Environment Checks就是检查变量是否定义如:$OPT_LEVEL, $OUTPUT_NAME
common.mk中又包含了clean.mk和tools_config.mk. clean.mk很简单就是rm -rf $OUT; tools_config.mk是定义一些公共选项如
cxx/c的版本和是否包含debug信息等。
nanopb.mk怎样由pb文件生成xxx.pb.c源文件
apps只是包含各个nanoapp的makfile,下面看其中的hello_world.mk
# Common Compiler Flags ########################################################
# Include paths.其实这里并没有apps/hello_world/include,这是提供可能的头文件搜索路径
COMMON_CFLAGS += -Iapps/hello_world/include
# Common Source Files ##########################################################
COMMON_SRCS += apps/hello_world/hello_world.cc
ash是个什么功能?看它以来的源码是slpi/smgr/ash.cc smgr相关,smgr被see替代,就不关注ash了
编译过程输出chre版本号和设置COMMON_CFLAGS += -I
$(PRINT_CURRENT_CHRE_API_VERSION_BIN): $(PRINT_CURRENT_CHRE_API_VERSION_SRCS)
mkdir -p $(OUT)
$(CHRE_HOST_CC) -I$(CHRE_PREFIX)/chre_api/include/chre_api $^ -o $@
什么时候调用的PRINT_CURRENT_CHRE_API_VERSION_BIN?
这是chre的核心代码且和platform没有关系,这个makefile定义了COMMON_CFLAGS += -I 和 COMMON_SRCS +=
如果不支持某个硬件可通过变量控制如audio support.
pal 的makefile中只有COMMON_CFLAGS += -I
include $(CHRE_PREFIX)/external/flatbuffers/flatbuffers.mk
# Common Compiler Flags ########################################################
# Include paths.
COMMON_CFLAGS += -Iplatform/include
# Common Source Files ##########################################################
COMMON_SRCS += platform/shared/platform_sensor_util.cc
所有platform相关的flags. I, srcs都在这个文件中,只是变量名字不同。
cflag相关的参数数+=Ixxx,其中包含slpi相关和slpi的一种实现方式see的+=Ixxx; slpi相关又分为chre部分代码和slpo_proc部分代码两者情况。
源码相关部分也是分为slpi_src 和slpi_see_src两部分
就是清空$1...$11变量的值
# TARGET_NAME_ar - An archive of the code compiled by this template.
# TARGET_NAME_so - A shared object of the code compiled by this template.
# TARGET_NAME - A convenience target that depends on the above archive and
# shared object targets.
#
# Argument List:
# $1 - TARGET_NAME - The name of the target being built.
# $2 - TARGET_CFLAGS - The compiler flags to use for this target.
# $3 - TARGET_CC - The C/C++ compiler for the target variant.
# $4 - TARGET_SO_LDFLAGS - The linker flags to use for this target.
# $5 - TARGET_LD - The linker for the target variant.
# $6 - TARGET_ARFLAGS - The archival flags to use for this target.
# $7 - TARGET_AR - The archival tool for the targer variant.
# $8 - TARGET_VARIANT_SRCS - Source files specific to this variant.
# $9 - TARGET_BUILD_BIN - Build a binary. Typically this means that the
# source files provided include an entry point.
# $10 - TARGET_BIN_LDFLAGS - Linker flags that are passed to the linker
# when building an executable binary.
# $11 - TARGET_SO_EARLY_LIBS - Link against a set of libraries when building
# a shared object or binary. These are placed
# before the objects produced by this build.
# $12 - TARGET_SO_LATE_LIBS - Link against a set of libraries when building
# a shared object or binary. These are placed
# after the objects produced by this build.
# $13 - TARGET_PLATFORM_ID - The ID of the platform that this nanoapp
# build targets.
函数call 唯一后面可带参数,函数内使用参数可用$(1, 2,..)表示 $$等以迭代的方式展开可用info替代eval看第一次展开后的样子,函数内打印的方式如果已经用info展开函数,还想打印出函数的参数,直接
test_1 = $(1)
test_common_cflags = $(COMMON_CFLAGS)
test_debug_cflags = $(COMMON_DEBUG_CFLAGS)
test_debug_cflags_local= $(TARGET_CFLAGS_LOCAL)
test_debug_cflags_local_debug= $(TARGET_DEBUG_CFLAGS)
test_2 = $(2)
使用展开就行了,再次使用info反而不会输出,另外为什么不直接用等作为函数的参数?
在加一层函数参数更灵活如对参数2: $(COMMON_CFLAGS) $(TARGET_CFLAGS)两者合起来作为参数2.
# Template Invocation ##########################################################
$(eval $(call BUILD_TEMPLATE, $(TARGET_NAME), \
$(COMMON_CFLAGS) $(TARGET_CFLAGS), \
$(TARGET_CC), \
$(TARGET_SO_LDFLAGS), \
$(TARGET_LD), \
$(TARGET_ARFLAGS), \
$(TARGET_AR), \
$(TARGET_VARIANT_SRCS), \
$(TARGET_BUILD_BIN), \
$(TARGET_BIN_LDFLAGS), \
$(TARGET_SO_EARLY_LIBS), \
$(TARGET_SO_LATE_LIBS), \
$(TARGET_PLATFORM_ID)))
# Source files.从COMMON_SRCS,TARGET_VARIANT_SRCS中filter出.cc/cpp/.c/.S文件到对应变量
函数filter的作用是从输入中filter出%.xx的文件
$(1)_CC_SRCS = $(filter %.cc, $(COMMON_SRCS) $(8))
$(1)_CPP_SRCS = $(filter %.cpp, $(COMMON_SRCS) $(8))
$(1)_C_SRCS = $(filter %.c, $(COMMON_SRCS) $(8))
$(1)_S_SRCS = $(filter %.S, $(COMMON_SRCS) $(8))
# Object files.有source文件得到对应的 .o文件变量
$$(1)_OBJS_DIR = $(1)_objs
函数patsubst的作用是对源文件%.cc --> %.o
$$(1)_CC_OBJS = $$(patsubst %.cc, $(OUT)/$$($$(1)_OBJS_DIR)/%.o, \
$$($$(1)_CC_SRCS))
$$(1)_CPP_OBJS = $$(patsubst %.cpp, $(OUT)/$$($$(1)_OBJS_DIR)/%.o, \
$$($$(1)_CPP_SRCS))
$$(1)_C_OBJS = $$(patsubst %.c, $(OUT)/$$($$(1)_OBJS_DIR)/%.o, \
$$($$(1)_C_SRCS))
$$(1)_S_OBJS = $$(patsubst %.S, $(OUT)/$$($$(1)_OBJS_DIR)/%.o, \
$$($$(1)_S_SRCS))
# Automatic dependency resolution Makefiles. 生成目标的依赖关系
patsubst对源文件%.cc --> %.d
$$(1)_CC_DEPS = $$(patsubst %.cc, $(OUT)/$$($$(1)_OBJS_DIR)/%.d, \
$$($$(1)_CC_SRCS))
$$(1)_CPP_DEPS = $$(patsubst %.cpp, $(OUT)/$$($$(1)_OBJS_DIR)/%.d, \
$$($$(1)_CPP_SRCS))
$$(1)_C_DEPS = $$(patsubst %.c, $(OUT)/$$($$(1)_OBJS_DIR)/%.d, \
$$($$(1)_C_SRCS))
$$(1)_S_DEPS = $$(patsubst %.S, $(OUT)/$$($$(1)_OBJS_DIR)/%.d, \
$$($$(1)_S_SRCS))
# Add object file directories.生成路径变量如out/google_hexagonv66_slpi-see_debug_objs/core
$$$(1)_DIRS = $$(sort $$(dir $$($$(1)_CC_OBJS) \
$$($$(1)_CPP_OBJS) \
$$($$(1)_C_OBJS) \
$$($$(1)_S_OBJS)))
# Shared Object
$$(1)_SO = $(OUT)/$$$(1)/$(OUTPUT_NAME).so
# Static Archive
$$(1)_AR = $(OUT)/$$$(1)/$(OUTPUT_NAME).a
# Nanoapp Header
$$(1)_HEADER = $$(if $(IS_NANOAPP_BUILD), $(OUT)/$$$(1)/$(OUTPUT_NAME).napp_header, )
# Optional Binary
$$(1)_BIN = $$(if $(9), $(OUT)/$$$(1)/$(OUTPUT_NAME), )
到此前面都是定义、赋值变量,没有rule和命令
# Define the phony target.
.PHONY: $(1)_ar
$(1)_ar: $$($$(1)_AR)
.PHONY: $(1)_so
$(1)_so: $$($$(1)_SO)
.PHONY: $(1)_bin
$(1)_bin: $$($$(1)_BIN)
.PHONY: $(1)_header
$(1)_header: $$($$(1)_HEADER)
.PHONY: $(1)
$(1): $(1)_ar $(1)_so $(1)_bin $(1)_header
$$($$(1)_CPP_OBJS): $(OUT)/$$($$(1)_OBJS_DIR)/%.o: %.cpp
$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
-o $$@
$($(1)_CPP_OBJS): out/$($(1)_OBJS_DIR)/%.o: %.cpp
/home/ws/buildtool/fusion/tools/HEXAGON_Tools/8.3.06/Tools/bin/hexagon-clang ($3)
-std=c++11 -fno-exceptions -fno-rtti ($(COMMON_CXX_CFLAGS))
-DCHRE_FILENAME=\"$(notdir $<)\" ( $(2) )
-I. -I/home/ws/code/msm8250-bsp/system/chre/util/include
-g
-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4000
-fpic -mllvm -disable-hsdr -G0
-D'__QAIC_SKEL_EXPORT=__attribute__((visibility("default")))'
-D__V_DYNAMIC__ -DQDSP6 -mv66 -O0 -D_DEBUG -DCHRE_PLATFORM_ID=0x476f6f676c000005
-c $<[$< 指代第一个前置条件] -o $@[$@指代当前目标]
$$($$(1)_CC_OBJS): $(OUT)/$$($$(1)_OBJS_DIR)/%.o: %.cc
$(3) $(COMMON_CXX_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
-o $$@
$$($$(1)_C_OBJS): $(OUT)/$$($$(1)_OBJS_DIR)/%.o: %.c
$(3) $(COMMON_C_CFLAGS) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
-o $$@
$$($$(1)_S_OBJS): $(OUT)/$$($$(1)_OBJS_DIR)/%.o: %.S
$(3) -DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< \
-o $$@
$$($$(1)_SO): $$(OUT)/$$$(1) $$($$$(1)_DIRS) $$($$(1)_CC_DEPS) \
$$($$(1)_CPP_DEPS) $$($$(1)_C_DEPS) $$($$(1)_S_DEPS) \
$$($$(1)_CC_OBJS) $$($$(1)_CPP_OBJS) $$($$(1)_C_OBJS) \
$$($$(1)_S_OBJS)
$(5) $(4) -o $$@ $(11) $$(filter %.o, $$^) $(12)
$($(1)_SO): $(OUT)/$ google_hexagonv66_slpi-see_debug $($ google_hexagonv66_slpi-see_debug_DIRS) $($(1)_CC_DEPS) $($(1)_CPP_DEPS) $($(1)_C_DEPS) $($(1)_S_DEPS) $($(1)_CC_OBJS) $($(1)_CPP_OBJS) $($(1)_C_OBJS) $($(1)_S_OBJS)
/home/ws/buildtool/fusion/tools/HEXAGON_Tools/8.3.06/Tools/bin/hexagon-link ($(5):linker)
--gc-sections -shared -call_shared -Bsymbolic --wrap=malloc --wrap=calloc --wrap=free --wrap=realloc --wrap=memalign --wrap=__stack_chk_fail --no-threads (linker flags)
-o $@ (输出当前目标)
/home/ws/buildtool/fusion/tools/HEXAGON_Tools/8.3.06/Tools/target/hexagon/lib/v66/G0/pic/initS.o (SO_EARLY_LIBS)
$(filter %.o, $^) ( $^指代所有前置条件)
/home/ws/code/msm8250-bsp/system/chre/build/app_support/google_slpi/libchre_slpi_skel.so(SO_LATE_LIBS)
/home/ws/buildtool/fusion/tools/HEXAGON_Tools/8.3.06/Tools/target/hexagon/lib/v66/G0/pic/finiS.o
$$($$(1)_BIN): $$(OUT)/$$$(1) $$($$$(1)_DIRS) $$($$(1)_CC_DEPS) \
$$($$(1)_CPP_DEPS) $$($$(1)_C_DEPS) $$($$(1)_S_DEPS) \
$$($$(1)_CC_OBJS) $$($$(1)_CPP_OBJS) $$($$(1)_C_OBJS) \
$$($$(1)_S_OBJS)
$(3) -o $$@ $(11) $$(filter %.o, $$^) $(12) $(10)
$$($$$(1)_DIRS):
mkdir -p $$@
$$(OUT)/$$$(1):
mkdir -p $$@
类似编译命令只是多了$(DEP_CFLAGS)
$$($$(1)_CC_DEPS): $(OUT)/$$($$(1)_OBJS_DIR)/%.d: %.cc
mkdir -p $$(dir $$@)
$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \
-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
$($(1)_CC_DEPS): out/$($(1)_OBJS_DIR)/%.d: %.cc
mkdir -p $(dir $@)
/home/ws/buildtool/fusion/tools/HEXAGON_Tools/8.3.06/Tools/bin/hexagon-clang
-MM -MG -MP -MF $(basename $@).d ($(DEP_CFLAGS))
-std=c++11 -fno-exceptions -fno-rtti
-DCHRE_FILENAME=\"$(notdir $<)\"
-I. -I/home/ws/code/msm8250-bsp/system/chre/util/include
-DNANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG
-c $< -o $@
$$($$(1)_CPP_DEPS): $(OUT)/$$($$(1)_OBJS_DIR)/%.d: %.cpp
mkdir -p $$(dir $$@)
$(3) $(DEP_CFLAGS) $(COMMON_CXX_CFLAGS) \
-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
$$($$(1)_C_DEPS): $(OUT)/$$($$(1)_OBJS_DIR)/%.d: %.c
mkdir -p $$(dir $$@)
$(3) $(DEP_CFLAGS) $(COMMON_C_CFLAGS) \
-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
$$($$(1)_S_DEPS): $(OUT)/$$($$(1)_OBJS_DIR)/%.d: %.S
mkdir -p $$(dir $$@)
$(3) $(DEP_CFLAGS) \
-DCHRE_FILENAME=\"$$(notdir $$<)\" $(2) -c $$< -o $$@
nanoApp的编译要到nanoapp路径下执行make xxx_target(写shell, shell 中调用make)
和上面的chre makefile比较,少了chre implementation,少了很多代码,但最终调用的和chre 一样都是build_template.mk
只是输入参数不同。