++++++++++++++++++++++++++++++++++++++++++

本文系本站原创,欢迎转载! 转载请注明出处:

http://blog.csdn.net/mr_raptor/article/details/7540066

++++++++++++++++++++++++++++++++++++++++++

Android编译系统详解(一):http://blog.csdn.net/mr_raptor/article/details/7539978

Android编译系统详解(二):http://blog.csdn.net/mr_raptor/article/details/7540066

Android编译系统详解(三):http://blog.csdn.net/mr_raptor/article/details/7540730

通过上篇文章,我们分析了编译android时source build/envsetup.sh和lunch命令,在执行完上述两个命令后, 我们就可以进行编译android了。


1. make

执行make命令的结果就是去执行当前目录下的Makefile文件,我们来看下它的内容:

[html] view plain copy
  1. 1###DONOTEDITTHISFILE###
  2. 2includebuild/core/main.mk
  3. 3###DONOTEDITTHISFILE###

呵呵,看到上面 的内容,我们都会笑,这是我见过最简单的Makefile了,我们再看下build/core/main.mk

main.mk文件里虽然脚本不多,但是却定义了整个Android的编译关系,它主要引入了下列几个重要的mk文件:

49 include $(BUILD_SYSTEM)/config.mk

55 include $(BUILD_SYSTEM)/cleanbuild.mk

142 include $(BUILD_SYSTEM)/definitions.mk

当然每个mk文件都有自己独特的意义,我一并将主线流程通过下面这个图各表现出来,先有个整体的概念,然后再细化了解。

Android编译系统详解 配置文件_第1张图片

所有的Makefile都通过build/core/main.mk这个文件组织在一起,它定义了一个默认goals:droid,当我们在TOP目录下,敲Make实际上就等同于我们执行make droid。

当Make include所有的文件,完成对所有make我文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img。其中,config.mk,envsetup.mk,product_config.mk文件是编译用户指定平台系统的关键文件。上图中红色部分是用户指定平台产品的编译主线,我们先来看下config.mk的主要作用。


2.build/core/config.mk

该文件被main.mk包含。

定义了以下环境变量:

[plain] view plain copy
  1. 16SRC_HEADERS:=\
  2. 17$(TOPDIR)system/core/include\
  3. 18$(TOPDIR)hardware/libhardware/include\
  4. 19$(TOPDIR)hardware/libhardware_legacy/include\
  5. 20$(TOPDIR)hardware/ril/include\
  6. 21$(TOPDIR)dalvik/libnativehelper/include\
  7. 22$(TOPDIR)frameworks/base/include\
  8. 23$(TOPDIR)frameworks/base/opengl/include\
  9. 24$(TOPDIR)external/skia/include
  10. 25SRC_HOST_HEADERS:=$(TOPDIR)tools/include
  11. 26SRC_LIBRARIES:=$(TOPDIR)libs
  12. 27SRC_SERVERS:=$(TOPDIR)servers
  13. 28SRC_TARGET_DIR:=$(TOPDIR)build/target
  14. 29SRC_API_DIR:=$(TOPDIR)frameworks/base/api
[plain] view plain copy
  1. .....然后定义了下面的重要的编译命令
[plain] view plain copy
  1. 43CLEAR_VARS:=$(BUILD_SYSTEM)/clear_vars.mk
  2. 44BUILD_HOST_STATIC_LIBRARY:=$(BUILD_SYSTEM)/host_static_library.mk
  3. 45BUILD_HOST_SHARED_LIBRARY:=$(BUILD_SYSTEM)/host_shared_library.mk
  4. 46BUILD_STATIC_LIBRARY:=$(BUILD_SYSTEM)/static_library.mk
  5. 47BUILD_RAW_STATIC_LIBRARY:=$(BUILD_SYSTEM)/raw_static_library.mk
  6. 48BUILD_SHARED_LIBRARY:=$(BUILD_SYSTEM)/shared_library.mk
  7. 49BUILD_EXECUTABLE:=$(BUILD_SYSTEM)/executable.mk
  8. 50BUILD_RAW_EXECUTABLE:=$(BUILD_SYSTEM)/raw_executable.mk
  9. 51BUILD_HOST_EXECUTABLE:=$(BUILD_SYSTEM)/host_executable.mk
  10. 52BUILD_PACKAGE:=$(BUILD_SYSTEM)/package.mk
  11. 53BUILD_HOST_PREBUILT:=$(BUILD_SYSTEM)/host_prebuilt.mk
  12. 54BUILD_PREBUILT:=$(BUILD_SYSTEM)/prebuilt.mk
  13. 55BUILD_MULTI_PREBUILT:=$(BUILD_SYSTEM)/multi_prebuilt.mk
  14. 56BUILD_JAVA_LIBRARY:=$(BUILD_SYSTEM)/java_library.mk
  15. 57BUILD_STATIC_JAVA_LIBRARY:=$(BUILD_SYSTEM)/static_java_library.mk
  16. 58BUILD_HOST_JAVA_LIBRARY:=$(BUILD_SYSTEM)/host_java_library.mk
  17. 59BUILD_DROIDDOC:=$(BUILD_SYSTEM)/droiddoc.mk
  18. 60BUILD_COPY_HEADERS:=$(BUILD_SYSTEM)/copy_headers.mk
  19. 61BUILD_KEY_CHAR_MAP:=$(BUILD_SYSTEM)/key_char_map.mk

上述命令变量其实是对应的mk文件名,几乎所有的Android.mk文件里基本上都包含上述命令变量,如:

CLEAR_VARS:用来清除之前定义的环境变量

BUILD_SHARED_LIBRARY:用来指定编译动态库过程

[plain] view plain copy
  1. 109#---------------------------------------------------------------
  2. 110#Definemostoftheglobalvariables.Thesearetheonesthat
  3. 111#arespecifictotheuser'sbuildconfiguration.
  4. ###evnsetup.mk文件里定义了大部分的全局变量,用户使用这些变量来编译系统
  5. 112include$(BUILD_SYSTEM)/envsetup.mk
  6. 113
  7. 114#Boardsmaybedefinedunder$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)
  8. 115#orundervendor/*/$(TARGET_DEVICE).Searchinbothplaces,but
  9. 116#makesureonlyoneexists.
  10. 117#RealboardsshouldalwaysbeassociatedwithanOEMvendor.
  11. ###板级配置信息通常定义在$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)或vendor/*/$(TARGET_DEVICE)下面,从这两个地方搜索,但是只能有一个地方存在板级配置信息(TARGET_DEVICE变量在上面的envsetup.mk里定义)
  12. ###wildcard命令用于在某个目录下查找匹配的文件,将找到的文件列表返回
  13. 118board_config_mk:=\
  14. 119$(strip$(wildcard\
  15. 120$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk\
  16. 121vendor/*/$(TARGET_DEVICE)/BoardConfig.mk\
  17. 122))
  18. ###如果没有找到,提示出错
  19. 123ifeq($(board_config_mk),)
  20. 124$(errorNoconfigfilefoundforTARGET_DEVICE$(TARGET_DEVICE))
  21. 125endif
  22. ###如果找到了1个以上时,提示出错
  23. 126ifneq($(words$(board_config_mk)),1)
  24. 127$(errorMultipleboardconfigfilesforTARGET_DEVICE$(TARGET_DEVICE):$(board_config_mk))
  25. 128endif
  26. 129include$(board_config_mk)#将板级配置信息包含进来
  27. 130TARGET_DEVICE_DIR:=$(patsubst%/,%,$(dir$(board_config_mk)))
  28. 131board_config_mk:=
112行又包含了另外一个重要的mk文件envsetup.mk,我们来看一下。


3. envsetup.mk

[plain] view plain copy
  1. 25ifeq($(TARGET_PRODUCT),)#如果TARGET_PRODUCT为空
  2. 26ifeq($(TARGET_SIMULATOR),true)#编译为模拟器
  3. 27TARGET_PRODUCT:=sim
  4. 28else
  5. 29TARGET_PRODUCT:=generic#默认产品名字为generic
  6. 30endif
  7. 31endif
第25行,判断 TARGET_PRODUCT是否为空,根据上一节分析可知, TARGET_PRODUCT=fs100
[plain] view plain copy
  1. 34#thevariant--thesetoffilesthatareincludedforabuild
  2. 35ifeq($(strip$(TARGET_BUILD_VARIANT)),)#如果编译版本型号变量为空
  3. 36TARGET_BUILD_VARIANT:=eng
  4. 37endif
  5. 38
  6. 39#ReadtheproductspecssoweangetTARGET_DEVICEandother
  7. 40#variablesthatweneedinordertolocatetheoutputfiles.
  8. ##product_config.mk文件,读取产品配置信息,从而得到目标设备,将其导出到TARGET_DEVICE变量里,后面的定义的OUT变量的值,也依赖于目标设备TARGET_DEVICE,用于指定目标代码的输出目录
  9. 41include$(BUILD_SYSTEM)/product_config.mk
在41行又包含了 product_config.mk文件,等会我们再分析它,先看下面的 [plain] view plain copy
  1. 148#---------------------------------------------------------------
  2. 149#figureouttheoutputdirectories
  3. 150
  4. 151ifeq(,$(strip$(OUT_DIR)))
  5. 152OUT_DIR:=$(TOPDIR)out
  6. 153endif
  7. 154
  8. 155DEBUG_OUT_DIR:=$(OUT_DIR)/debug
  9. 156
  10. 157#Movethehostortargetunderthedebug/directory
  11. 158#ifnecessary.
  12. 159TARGET_OUT_ROOT_release:=$(OUT_DIR)/target
  13. 160TARGET_OUT_ROOT_debug:=$(DEBUG_OUT_DIR)/target
  14. 161TARGET_OUT_ROOT:=$(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))
  15. 162
  16. ...
  17. ###这个重要的OUT变量,依赖于目标设备名TARGET_DEVICE
  18. 184PRODUCT_OUT:=$(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
  19. 187
  20. 188HOST_OUT_EXECUTABLES:=$(HOST_OUT)/bin
  21. 189HOST_OUT_SHARED_LIBRARIES:=$(HOST_OUT)/lib
  22. 190HOST_OUT_JAVA_LIBRARIES:=$(HOST_OUT)/framework
  23. 191HOST_OUT_SDK_ADDON:=$(HOST_OUT)/sdk_addon
  24. ...
  25. 200TARGET_OUT_INTERMEDIATES:=$(PRODUCT_OUT)/obj
  26. 201TARGET_OUT_HEADERS:=$(TARGET_OUT_INTERMEDIATES)/include
  27. 202TARGET_OUT_INTERMEDIATE_LIBRARIES:=$(TARGET_OUT_INTERMEDIATES)/lib
  28. 203TARGET_OUT_COMMON_INTERMEDIATES:=$(TARGET_COMMON_OUT_ROOT)/obj
  29. 204
  30. ###后面的OUT变量都要间接依赖于TARGET_DEVICE
  31. 205TARGET_OUT:=PRODUCT_OUT)/system
  32. 206TARGET_OUT_EXECUTABLES:=$(TARGET_OUT)/bin
  33. 207TARGET_OUT_OPTIONAL_EXECUTABLES:=$(TARGET_OUT)/xbin
  34. 208TARGET_OUT_SHARED_LIBRARIES:=$(TARGET_OUT)/lib
  35. 209TARGET_OUT_JAVA_LIBRARIES:=$(TARGET_OUT)/framework
  36. 210TARGET_OUT_APPS:=$(TARGET_OUT)/app
  37. 211TARGET_OUT_KEYLAYOUT:=$(TARGET_OUT)/usr/keylayout
  38. 212TARGET_OUT_KEYCHARS:=$(TARGET_OUT)/usr/keychars
  39. 213TARGET_OUT_ETC:=$(TARGET_OUT)/etc
  40. 214TARGET_OUT_STATIC_LIBRARIES:=$(TARGET_OUT_INTERMEDIATES)/lib
  41. 215TARGET_OUT_NOTICE_FILES:=$(TARGET_OUT_INTERMEDIATES)/NOTICE_FILES
  42. 216
  43. 217TARGET_OUT_DATA:=$(<strong>PRODUCT_OUT</strong>)/data
  44. 218TARGET_OUT_DATA_EXECUTABLES:=$(TARGET_OUT_EXECUTABLES)
  45. 219TARGET_OUT_DATA_SHARED_LIBRARIES:=$(TARGET_OUT_SHARED_LIBRARIES)
  46. 220TARGET_OUT_DATA_JAVA_LIBRARIES:=$(TARGET_OUT_JAVA_LIBRARIES)
  47. 221TARGET_OUT_DATA_APPS:=$(TARGET_OUT_DATA)/app
  48. 222TARGET_OUT_DATA_KEYLAYOUT:=$(TARGET_OUT_KEYLAYOUT)
  49. 223TARGET_OUT_DATA_KEYCHARS:=$(TARGET_OUT_KEYCHARS)
  50. 224TARGET_OUT_DATA_ETC:=$(TARGET_OUT_ETC)
  51. 225TARGET_OUT_DATA_STATIC_LIBRARIES:=$(TARGET_OUT_STATIC_LIBRARIES)
  52. 226
  53. 227TARGET_OUT_UNSTRIPPED:=$(<strong>PRODUCT_OUT</strong>)/symbols
  54. 228TARGET_OUT_EXECUTABLES_UNSTRIPPED:=$(TARGET_OUT_UNSTRIPPED)/system/bin
  55. 229TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED:=$(TARGET_OUT_UNSTRIPPED)/system/lib
  56. 230TARGET_ROOT_OUT_UNSTRIPPED:=$(TARGET_OUT_UNSTRIPPED)
  57. 231TARGET_ROOT_OUT_SBIN_UNSTRIPPED:=$(TARGET_OUT_UNSTRIPPED)/sbin
  58. 232TARGET_ROOT_OUT_BIN_UNSTRIPPED:=$(TARGET_OUT_UNSTRIPPED)/bin
  59. 233
  60. 234TARGET_ROOT_OUT:=$(<strong>PRODUCT_OUT</strong>)/root
  61. 235TARGET_ROOT_OUT_BIN:=$(TARGET_ROOT_OUT)/bin
  62. 236TARGET_ROOT_OUT_SBIN:=$(TARGET_ROOT_OUT)/sbin
  63. 237TARGET_ROOT_OUT_ETC:=$(TARGET_ROOT_OUT)/etc
  64. 238TARGET_ROOT_OUT_USR:=$(TARGET_ROOT_OUT)/usr
  65. 239
  66. 240TARGET_RECOVERY_OUT:=$(<strong>PRODUCT_OUT</strong>)/recovery
  67. 241TARGET_RECOVERY_ROOT_OUT:=$(TARGET_RECOVERY_OUT)/root
  68. 242
  69. 243TARGET_SYSLOADER_OUT:=$(<strong>PRODUCT_OUT</strong>)/sysloader
  70. 244TARGET_SYSLOADER_ROOT_OUT:=$(TARGET_SYSLOADER_OUT)/root
  71. 245TARGET_SYSLOADER_SYSTEM_OUT:=$(TARGET_SYSLOADER_OUT)/root/system
  72. 246
  73. 247TARGET_INSTALLER_OUT:=$(<strong>PRODUCT_OUT</strong>)/installer
  74. 248TARGET_INSTALLER_DATA_OUT:=$(TARGET_INSTALLER_OUT)/data
  75. 249TARGET_INSTALLER_ROOT_OUT:=$(TARGET_INSTALLER_OUT)/root
  76. 250TARGET_INSTALLER_SYSTEM_OUT:=$(TARGET_INSTALLER_OUT)/root/system
上面的代码是指定了目标输出代码的位置和主机输出代码的位置,重要的几个如下: [plain] view plain copy
  1. TARGET_OUT=$(<strong>PRODUCT_OUT</strong>)/system
  2. TARGET_OUT_EXECUTABLES=$(PRODUCT_OUT)/system/bin
  3. TARGET_OUT_SHARED_LIBRARIES=$(PRODUCT_OUT)/system/lib
  4. TARGET_OUT_JAVA_LIBRARIES=$(PRODUCT_OUT)/system/framework
  5. TARGET_OUT_APPS=$(PRODUCT_OUT)/system/app
  6. TARGET_OUT_ETC=$(PRODUCT_OUT)/system/etc
  7. TARGET_OUT_STATIC_LIBRARIES=$(PRODUCT_OUT)/obj/lib
  8. TARGET_OUT_DATA=$(PRODUCT_OUT)/data
  9. TARGET_OUT_DATA_APPS=$(PRODUCT_OUT)/data/app
  10. TARGET_ROOT_OUT=$(PRODUCT_OUT)/root
  11. TARGET_ROOT_OUT_BIN=$(PRODUCT_OUT)/bin
  12. TARGET_ROOT_OUT_SBIN=$(PRODUCT_OUT)/system/sbin
  13. TARGET_ROOT_OUT_ETC=$(PRODUCT_OUT)/system/etc
  14. TARGET_ROOT_OUT_USR=$(PRODUCT_OUT)/system/usr

总结下:

envsetup.mk文件主要包含了product_config.mk文件,然后指定了编译时要输出的所有文件的OUT目录,这些OUT目录变量依赖于TARGET_DEVICE变量。


4. build/core/product_config.mk [plain] view plain copy
  1. 157include$(BUILD_SYSTEM)/product.mk
  2. ...
  3. 160#ReadinalloftheproductdefinitionsspecifiedbytheAndroidProducts.mk
  4. 161#filesinthetree.
  5. 162#
  6. 163#TODO:whenwestartallowingdirectpointerstoproductfiles,
  7. 164#guaranteethatthey'reinthislist.
  8. 165$(callimport-products,$(get-all-product-makefiles))
  9. 166$(check-all-products)
  10. ...
  11. 170#Convertashortnamelike"sooner"intothepathtotheproduct
  12. 171#filedefiningthatproduct.
  13. 172#
  14. 173INTERNAL_PRODUCT:=$(callresolve-short-product-name,$(TARGET_PRODUCT))
  15. ...
  16. 176#Findthedevicethatthisproductmapsto.
  17. 177TARGET_DEVICE:=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
157行,我靠,又包含了product.mk文件

165行,调用函数import-products, $(get-all-product-makefiles),这儿我们看上面的注释:

Read in all of the product definitions specified by the AndroidProducts.mkfiles in the tree.
TODO: when we start allowing direct pointers to product files,guarantee that they're in this list.

意思是说:读取厂商目录下(vendor/*/products/AndroidProducts.mk)所有的AndrodProducts.mk文件中定义的产品信息

其实get-all-product-makefiles返回厂商全部产品文件xxx.mk

import-products函数去验证这些产品配置文件是否都包含有必须的配置信息,细节后面分析。

173行调用了resolve-short-product-name函数,它将根据产品TARGET_PRODUCT,返回该产品配置文件的完整路径,并赋给INTERNAL_PRODUCT

例如TARGET_PRODUCT=fs100,则:

INTERNAL_PRODUCT =vendor/farsight/products/fs100.mk

TARGET_DEVICE = fs100

如果调试看其结果,可以在167行,将#$(dump-product)取消注释

然后在175行添加: $(info $(INTERNAL_PRODUCT))

在178行添加:$(info $(TARGET_DEVICE)),查看调试结果。

总结一下:

接合前面的图,product_config.mk主要读取vendor目录下不同厂商自己定义的AndrodProducts.mk文件(vendor/*/products/AndroidProducts.mk),从该文件里取得所有产品的配置文件,然后再根据lunch选择的编译项TARGET_PRODUCT,找到与之对应的配置文件,然后读取产品配置文件,找到里面的PRODUCT_DEVICE的值,设置给TARGET_DEVICE变量,用于后续编译。


5.build/core/product.mk

[plain] view plain copy
  1. 17#
  2. 18#FunctionsforincludingAndroidProducts.mkfiles
  3. 19#
  4. 20
  5. 21#
  6. 22#ReturnsthelistofallAndroidProducts.mkfiles.
  7. 23#$(call)isn'tnecessary.
  8. 24#
  9. 25define<strong>_find-android-products-files</strong>
  10. 26$(shelltest-dvendor&&findvendor-maxdepth6-nameAndroidProducts.mk)\
  11. 27$(SRC_TARGET_DIR)/product/AndroidProducts.mk
  12. 28endef
  13. 29
  14. 30#
  15. 31#ReturnsthesortedconcatenationofallPRODUCT_MAKEFILES
  16. 32#variablessetinallAndroidProducts.mkfiles.
  17. 33#$(call)isn'tnecessary.
  18. 34#
  19. 35define<strong>get-all-product-makefiles</strong>
  20. 36$(sort\
  21. 37$(foreachf,$(_find-android-products-files),\
  22. 38$(evalPRODUCT_MAKEFILES:=)\
  23. 39$(evalLOCAL_DIR:=$(patsubst%/,%,$(dir$(f))))\
  24. 40$(evalinclude$(f))\
  25. 41$(PRODUCT_MAKEFILES)\
  26. 42)\
  27. 43$(evalPRODUCT_MAKEFILES:=)\
  28. 44$(evalLOCAL_DIR:=)\
  29. 45)
  30. 46endef
通过注释可知,本文件中主要是一些用来处理AndroidProduct.mk的函数
_find-android-products-files:

用来获得vendor目录下,所有名字为AndroidProduct.mk的文件列表。
get-all-product-makefiles:

用来获得所有AndroidProduct.mk文件里定义的PRODUCT_MAKEFILES的值(其实是产品文件路径名)。


在vendor目录下,每个厂商子目录下都会存在一个AndroidProduct.mk文件,这个文件是用来定义这个厂商的产品列表,每个产品用<product_name>.mk来表示
如Android给的示例:

[plain] view plain copy
  1. vendor/sample/products/AndroidProduct.mk
其内容如下:
[plain] view plain copy
  1. 1#
  2. 2#ThisfileshouldsetPRODUCT_MAKEFILEStoalistofproductmakefiles
  3. 3#toexposetothebuildsystem.LOCAL_DIRwillalreadybesetto
  4. 4#thedirectorycontainingthisfile.
  5. 5#
  6. 6#Thisfilemaynotrelyonthevalueofanyvariableotherthan
  7. 7#LOCAL_DIR;donotuseanyconditionals,anddonotlookupthe
  8. 8#valueofanyvariablethatisn'tsetinthisfileorinafilethat
  9. 9#itincludes.
  10. 10#
  11. 11
  12. 12PRODUCT_MAKEFILES:=\
  13. 13$(LOCAL_DIR)/sample_addon.mk
里面只定义了一个产品配置文件,即当前目录下的sample_addon.mk:
[plain] view plain copy
  1. 1#Listofappsandoptionallibraries(Javaandnative)toputintheadd-onsystemimage.
  2. 2PRODUCT_PACKAGES:=\
  3. 3PlatformLibraryClient\
  4. 4com.example.android.platform_library\
  5. 5libplatform_library_jni
上述文件里(sample_addon.mk)定义了产品相关个性化信息,如,PRODUCT_PACKAGES表示要在当前产品里添加一些安装包。
由此可见,get-all-product-makefiles函数,其实就是返回了当前公司里全部的产品对应的mk文件列表。


总结:

如果用户想个性定制自己的产品,应该有以下流程,包含上一节内容:

注:#表示shell提示符

1.创建厂商目录

#mkdir vendor/farsight

2. 创建一个vendorsetup.sh文件,将当前产品编译项添加到lunch里,让lunch能找到用户产品编译项

#echo "add_lunch_combo fs100-eng" > vendor/farsight/vendorsetup.sh

注:我们增加一个用户产品编译项,fs100-eng

3. 仿着Android示例代码,在厂商目录下创建products目录

#mkdir -p vendor/farsight/products

4.仿着Android示例代码,在products目录下创建两个mk文件

#touch vendor/farsight/products/AndroidProduct.mk vendor/farsight/products/fs100.mk

注:其中AndroidProduct.mk是当前厂商产品列表文件,fs100.mk表示当前厂商的一款产品配置文件

在AndroidProduct.mk里添加如下内容:

[plain] view plain copy
  1. PRODUCT_MAKEFILES:=$(LOCAL_DIR)/fs100.mk
注:表示只有一个产品fs100,它对应的配置文件在当前目录下的fs100.mk。

5. 在产品配置文件里添加最基本信息

[plain] view plain copy
  1. 1
  2. 2PRODUCT_PACKAGES:=\
  3. 3IM\
  4. 4VoiceDialer
  5. 5
  6. 6$(callinherit-product,build/target/product/generic.mk)##从某一默认配置开始派生余下内容参考派生起点
  7. 7
  8. 8#Overrides
  9. 9PRODUCT_MANUFACTURER:=farsight
  10. 10PRODUCT_NAME:=fs100
  11. 11PRODUCT_DEVICE:=fs100

一定要注意:

PRODUCT_NAME:表示产品名字,它要和最终出现的编译项产品名一致,也就是说fs100-eng

PRODUCT_DEVICE:表示设备名字,它要和将来创建的设备目录名字一致。

更多相关文章

  1. Android 数据存储(数据库、文件、参数)操作实例
  2. Android中手机文件储存路径
  3. Android zip文件压缩
  4. AndroidManifest.xml文件详解(supports-screens)
  5. Android获取SDcard目录及创建文件夹;
  6. Android中遇到问题:file.delete()不能删除文件
  7. [android]system.img文件的打包和解包
  8. android打开文件及打开方式(打开程序列表)
  9. Android ndk开发之在c文件里打印log

随机推荐

  1. android svg
  2. php解析非标准json、非规范json的方式实
  3. 仿写PHP中文网首页
  4. Tomcat 介绍及使用教程
  5. JSP forward用法分析实例代码分析
  6. JSP request(return String)用法详例
  7. JSP JavaBean的setProperty属性
  8. PHP基于进程控制函数实现多线程
  9. 如何画角色透视?人物透视动态绘画步骤!
  10. JSP errorPage设置方法