我们也说说Android.mk(6) - 案例教程

简介: 前面基础知识已经准备得差不多了,我们开始看几个例子巩固一下

我们也说说Android.mk(6) - 案例教程

userdata是如何生成的

我们先看看userdataimage的伪目标是如何定义的:

.PHONY: userdataimage
userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET)

ifneq (,$(filter userdataimage, $(MAKECMDGOALS)))
$(call dist-for-goals, userdataimage, $(BUILT_USERDATAIMAGE_TARGET))
endif

.PHONY: userdatatarball
userdatatarball: $(INSTALLED_USERDATATARBALL_TARGET)

INSTALLED_USERDATAIMAGE_TARGET

userdataimage依赖于INSTALLED_USERDATAIMAGE_TARGET,我们再看看INSTALLED_USERDATAIMAGE_TARGET是什么:

INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)

BUILT_USERDATAIMAGE_TARGET

我们再继续看BUILT_USERDATAIMAGE_TARGET:

BUILT_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img

OK,这一支明白了,就是userdata.img嘛。

# A global variable to remember all dist'ed src:dst pairs.
# So if a src:dst is already dist'ed by another goal,
# we should just establish the dependency and don't really call the
# copy-one-dist-file to avoid multiple rules for the same target.
_all_dist_src_dst_pairs :=
# Other parts of the system should use this function to associate
# certain files with certain goals.  When those goals are built
# and "dist" is specified, the marked files will be copied to DIST_DIR.
#
# $(1): a list of goals  (e.g. droid, sdk, pdk, ndk)
# $(2): the dist files to add to those goals.  If the file contains ':',
#       the text following the colon is the name that the file is copied
#       to under the dist directory.  Subdirs are ok, and will be created
#       at copy time if necessary.
define dist-for-goals
$(foreach file,$(2), \
  $(eval fw := $(subst :,$(space),$(file))) \
  $(eval src := $(word 1,$(fw))) \
  $(eval dst := $(word 2,$(fw))) \
  $(eval dst := $(if $(dst),$(dst),$(notdir $(src)))) \
  $(if $(filter $(_all_dist_src_dst_pairs),$(src):$(dst)),\
    $(eval $(call add-dependency,$(1),$(DIST_DIR)/$(dst))),\
    $(eval $(call copy-one-dist-file,\
      $(src),$(DIST_DIR)/$(dst),$(1)))\
      $(eval _all_dist_src_dst_pairs += $(src):$(dst))\
  )\
)
endef

userdata的中间文件

我们再来看看userdata的中间文件是如何生成的:

userdataimage_intermediates := \
    $(call intermediates-dir-for,PACKAGING,userdata)

这个好,直接调用一个函数。所谓函数,就是一个大宏,我们看看它是如何定义的:

###########################################################
## The intermediates directory.  Where object files go for
## a given target.  We could technically get away without
## the "_intermediates" suffix on the directory, but it's
## nice to be able to grep for that string to find out if
## anyone's abusing the system.
###########################################################

# $(1): target class, like "APPS"
# $(2): target name, like "NotePad"
# $(3): if non-empty, this is a HOST target.
# $(4): if non-empty, force the intermediates to be COMMON
# $(5): if non-empty, force the intermedistes to be for the 2nd arch
define intermediates-dir-for
$(strip \
    $(eval _idfClass := $(strip $(1))) \
    $(if $(_idfClass),, \
        $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \
    $(eval _idfName := $(strip $(2))) \
    $(if $(_idfName),, \
        $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
    $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \
    $(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \
    $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
        $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
      ,$(if $(filter $(_idfClass),SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP),\
          $(eval _idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) \
       ,$(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \
       ) \
     ) \
    $(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \
)
endef

虽然逻辑并不是一目了然,但是所用的特性,我们前面都讲过了。

目录
相关文章
|
3月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
2595 2
|
2月前
|
Java Android开发 Spring
Android Spingboot 实现SSE通信案例
【7月更文挑战第14天】以下是使用Android和Spring Boot实现SSE(Server-Sent Events)通信的案例摘要: 在`MainActivity`中: - 初始化界面元素并设置按钮点击事件。 - `startSseRequest`方法创建`WebClient`对象,设置请求头,发送请求,并处理响应和错误。 请确保将`your-server-url`替换为实际的服务器地址。
67 14
|
3月前
|
JSON Java API
【Android】使用 Retrofit2 发送异步网络请求的简单案例
**摘要:** Retrofit是Android和Java的HTTP客户端库,简化了RESTful API交互。它通过Java接口定义HTTP请求,并提供注解管理参数、HTTP方法等。要使用Retrofit,首先在AndroidManifest.xml中添加`INTERNET`权限,然后在`build.gradle`中引入Retrofit和Gson依赖。创建服务器响应数据类和描述接口的接口,如`Result`和`Api`。通过Retrofit.Builder配置基础URL并构建实例,之后调用接口方法创建Call对象并发送异步请求。
113 1
|
3月前
|
存储 编解码 Android开发
58. 【Android教程】音频录制:MediaRecord
58. 【Android教程】音频录制:MediaRecord
37 2
|
3月前
|
Android开发
杨老师课堂_安卓教程第一篇之入门
杨老师课堂_安卓教程第一篇之入门
30 0
|
3月前
|
Java Linux 数据库
59. 【Android教程】多线程
59. 【Android教程】多线程
32 0
|
3月前
|
API Android开发
57. 【Android教程】相机:Camera
57. 【Android教程】相机:Camera
53 0
|
3月前
|
API Android开发 UED
56. 【Android教程】媒体播放器:MediaPlayer
56. 【Android教程】媒体播放器:MediaPlayer
62 0
|
3月前
|
API Android开发
55. 【Android教程】位图:Bitmap
55. 【Android教程】位图:Bitmap
34 0
|
3月前
|
XML Java API
54. 【Android教程】图片资源:Drawable
54. 【Android教程】图片资源:Drawable
45 0