android 编译系统

来源:互联网 发布:淘宝网套装春秋女装 编辑:程序博客网 时间:2024/06/11 06:48
样例:
---------- cut here ------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= helloworld
LOCAL_SRC_FILES := helloworld.c
include $(BUILD_SHARED_LIBRARY)
---------- cut here ------------------
********************************************************************************************************
LOCAL_MODULE := helloworld ->共享库被编译为libhelloworld.so #LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块,名称必须是唯一的,而且不包含任何空格。
##定义了本模块的模块名
LOCAL_SRC_FILES := helloworld.c ###LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。注意,默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始的小圆点(也就是定义为‘.cxx’,而不是‘cxx’)(当然这一步我们一般不会去改它)】
##用例:LOCAL_SRC_FILES += $(shell find $(LOCAL_SRC_DIR) -name '*.c' | sed s:^$(LOCAL_PATH)::g ),编译路径下的所有文件
##定义了本模块编译使用的源文件,采用的是基于LOCAL_PATH的相对路径
LOCAL_SHARED_LIBRARIES : ##会生成依赖关系,当库不存在时会去编译这个库
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LOCAL_LDLIBS : ###链接的库不产生依赖关系,一般用于不需要重新编译的库,如库不存在,则会报错找不到。且貌似只能链接那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库
##LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog,如果你的Android.mk文件中只有这么一行,那么将会采用动态链接
##故名思议,ldlibs,就是指定那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库。
##如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …  如果你的Android.mk文件中只有这么一行,那么将会采用动态链接这个类似于上面用gcc编译时直接指定库是一样的道理
LOCAL_LDFLAGS: ##这个编译变量传递给链接器一个一些额外的参数,比如想传递而外的库和库路径给ld,或者传递给ld linker的一些链接参数,-On,-EL{B}(大小端字节序),那么就要加到这个上面
##如:LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib/ -lHWrecog –EB{EL} –O{n} …
##或者直接加上绝对路径库的全名:LOCAL_LDFLAGS += $(LOCAL_PATH)/lib/libHWrecog.a –EB{EL} –O{n}
##注:如果是非系统的第三方库,貌似只能用LOCAL_LDFLAGS方式,LOCAL_LDLIBS方式不行
LOCAL_FORCE_STATIC_EXECUTABLE:####如果编译时候需要链接的动态库库存在静态库形式,那么在这个编译变量等于true的情况下,将会链接到对应的静态库而不是动态库。比如上面列出的libm,libz,libc,libcutils,libutils ,liblog等动静态库都存在,那么在该变量被置true的时候,将会链接对应的静态库。当然对于本来就是静态库的libHWrecog.a来说,该变量值不会影响它是被静态链接的。所以可以想到这个参数的设置是和前面用gcc编译时候指定-static参数一样的效果, 推荐只是编译特殊ELF文件才用
####通常这种情况只会在编译root/sbin目录下的应用才会用到应为通常他们执行的时间比较早,文件系统的其他部都没加载,所以动态库就会链接不上,这个时候静态链接是最好不过了。不过在android的系统中好像没有怎么用到因为linux一起来就是执行的init进程,就开始引导android系统了
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LOCAL_C_INCLUDES: ##额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录,像gcc的-I参数
##如:LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_CC: ##另外指定c编译器,不使用默认的。
LOCAL_CFLAGS: ##为C编译器传递额外的参数(如宏定义),举例:LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1
LOCAL_CPP_EXTENSION: ##如果你的C++文件不是以cpp为文件后缀,你可以通过LOCAL_CPP_EXTENSION指定C++文件后缀名
##如:LOCAL_CPP_EXTENSION := .cc注意统一模块中C++文件后缀必须保持一致。
LOCAL_CPPFLAGS: ##传递额外的参数给C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection -DLIBUTILS_NATIVE 
LOCAL_CXX: ##指定C++编译器
********************************************************************************************************
andriod 系统级 
********************************************************************************************************
通常在Android.mk开头都要包含:
LOCAL_PATH := $(call my-dir)##定义好LOCAL_PATH变量,它用于在开发树中查找源文件,在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../includes/ ##LOCAL_C_INCLUDES 表示了本模块需要引用的include文件


+++++++++++++++++++++++++++++++++++++++++++++++++++
每个编译模块由include $(CLEAR_VARS) 开始,由include $(BUILD_XXX) 结束
include $( CLEAR_VARS)##CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量,(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),
##是一个编译模块的开始,它会清空除LOCAL_PATH之外的所有LOCA_XXX变量
include $(BUILD_SHARED_LIBRARY) #BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU Makefile脚本(应该就是在build/core目录下的shared_library.mk),负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。并根据其规则生成静态库。同理对于静态库。
#[build/core,shared_library.mk]
#描述了编译目标
这两句,特别是include $(CLEAR_VARS)这个会清除上一个模块编译时候留下的所有LOCAL_变量,以准备给当前模块使用
+++++++++++++++++++++++++++++++++++++++++++++++++++
1.build/core/config.mk       ->定义BUILD_XXX的编译目标
编译目标 说明
BUILD_HOST_STATIC_LIBRARY主机上的静态库
BUILD_HOST_SHARED_LIBRARY主机上的动态库
BUILD_HOST_EXECUTABLE主机上的可执行文件
BUILD_STATIC_LIBRARY目标设备上的静态库
BUILD_SHARED_LIBRARY目标设备上的动态库
BUILD_EXECUTABLE目标设备上的可执行文件
BUILD_JAVA_LIBRARYJAVA库
BUILD_STATIC_JAVA_LIBRARY静态JAVA库
BUILD_HOST_JAVA_LIBRARY主机上的JAVA库
BUILD_PACKAGE APK程序
##定义,CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
2.core/definitions.mk ->my-dir函数的定义位于core/definitions.mk文件:
LOCAL_PATH := $(call my-dir)##LOCAL_PATH通过调用my-dir函数来获取当前的路径
##my-dir函数的定义位于core/definitions.mk文件:
##LOCAL_PATH的定义必须要放在任何include $(CLEAR_VARS)语句之前,如果不这么做的话,编译就直接报错,停止不干了
3.build/core/main.mk ->CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 定义于build/core/config.mk中;
##BUILD_SYSTEM的定义在build/core/main.mk文件中
+++++++++++++++++++++++++++++++++++++++++++++++++++
那么在android的编译过程中,需要了解以下一些编译变量
LOCAL_C_INCLUDES
LOCAL_CC
LOCAL_CFLAGS
LOCAL_CPP_EXTENSION
LOCAL_CPPFLAGS
LOCAL_CXX
LOCAL_LDLIBS
LOCAL_LDFLAGS
LOCAL_FORCE_STATIC_EXECUTABLE
这些LOCAL_开头的变量都是模块编译内的局部变量,在编译其他模块时会通过include $(CLEAR_VARS)来清除上一个模块编译时候留下的所有LOCAL_变量,以准备给当前模块使用
********************************************************************************************************


android 编译系统 简介:
1.打开shell进入android源码根目录,source build/envsetup.sh,该脚本文件被source的同时也会从vendor和device两个目录中
将制定的envsetup.sh也source到当前的shell中,从而获得厂商的产品配置信息
2.build/envsetup.sh也提供了一些重要的命令来编译android源代码:
lunch:
用于初始化编译环境,设置环境变量和指定目标产品型号。
设置TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_BUILD_TYPE和TARGET_BUILD_APPS等环境变量,用来指定目标产品类型和编译类型。
通过make命令执行build/core/config.mk脚本,并且通过加载另外一个脚本build/core/dumpvar.mk打印出当前的编译环境配置信息
build/core/config.mk脚本还会加载一个名称为BoradConfig.mk的脚本以及build/core/envsetup.mk脚本来配置目标产品型号的相关信息
3.编译指令:
m ->make
mm->如果是在Android源码根目录下执行,那么就相当于是执行make命令对整个源码进行编译。如果是在Android源码根目录下的某一个子目录执行,那么就在会在从该子目录开始,一直往上一个目录直至到根目录,寻找是否存在一个Android.mk文件。如果存在的话,那么就通过make命令对该Android.mk文件描述的模块进行编译
mmm->面可以跟一个或者若干个目录。如果指定了多个目录,那么目录之间以空格分隔,并且每一个目录下都必须存在一个Android,mk文件。如果没有在目录后面通过冒号指定模块名称,那么在Android.mk文件中描述的所有模块都会被编译,否则只有指定的模块会被编译。如果需要同时指定多个模块,那么这些模块名称必须以逗号分隔。它的语法如下所示
  mmm <dir-1> <dir-2> ... <dir-N>[:module-1,module-2,...,module-M] 
  该命令会通过make命令来执行Android源码根目录下的Makefile文件,该Makefile文件又会将build/core/main.mk加载进来。文件build/core/main.mk在加载的过程中,还会加载以下几个主要的文件:
       (1). build/core/config.mk
       该文件根据lunch命令所配置的产品信息在build/target/board、vendor或者device目录中找到对应的BoradConfig.mk文件,以及通过加载build/core/product_config.mk文件在build/target/product、vendor或者device目录中找到对应的AndroidProducts.mk文件,来进一步对编译环境进行配置,以便接下来编译指定模块时可以获得必要的信息。
       (2). build/core/definitions.mk
       该文件定义了在编译过程需要调用到的各种自定义函数。
       (3). 指定的Android.mk
       这些指定的Android.mk环境是由mmm命令通过环境变量ONE_SHOT_MAKEFILE传递给build/core/main.mk文件使用的。这些Android.mk文件一般还会通过环境变量BUILD_PACKAGE、BUILD_JAVA_LIBRARY、BUILD_STATIC_JAVA_LIBRARY、BUILD_SHARED_LIBRARY、BUILD_STATIC_LIBRARY、BUILD_EXECUTABLE和BUILD_PREBUILT将build/core/package.mk、build/core/java_library.mk、build/core/static_java_library.mk、build/core/shared_library.mk、build/core/static_library.mk、build/core/executable.mk和build/core/prebuilt.mk等编译片段模板文件加载进来,来表示要编译是APK、Java库、Linux动态库/静态库/可执行文件或者预先编译好的文件等等。
(4). build/core/Makefile
该文件包含了用来制作system.img、ramdisk.img、boot.img和recovery.img等镜像文件的脚本

Reference:http://weibo.com/shengyangluo
Android编译系统的环境初始化过程;
http://blog.csdn.net/luoshengyang/article/details/18928789
Android源代码编译命令m/mm/mmm/make分析:
http://blog.csdn.net/luoshengyang/article/details/19023609
Android系统镜像文件的打包过程分析:
http://blog.csdn.net/luoshengyang/article/details/20501657
android 集成第三方静态库的编译方法:
http://blog.csdn.net/lizhiguo0532/article/details/7219349
0 0