ǰλã >> Android >> Android.mk添加?方jar或so库到apk->Android.mk用法
  ϸ

Android.mk添加?方jar或so库到apk->Android.mk用法

ȶȣ57   ʱ䣺2016-04-28 07:11:01.0
Android.mk添加?方jar或so库到apk-->Android.mk用法

Android.mk文档规范
Android.mk 编译文件?来向 Android NDK描述你的C,C++源代码文件的, ?这篇文档?/span>
述了它的?。在阅?下面的内容之前,假定你已经阅读了 docs/OVERVIEW.TXT 文件,了?/span>
了它?脚色和用途??/span>
?、??/span>
  ??Android.mk file 用来向编译系统描述你的源代码。具体来说:
  ??该文件是GNU Makefile的一小部分,会?编译系统解析?次或更?次的build系统?/span>
因?,您应尽量减少您声明的变量,不?认为某些变量在解析过程中不会?义??/span>
  ?)这?件的?允?把你的源代码组织成模块,??块属下列类型之一?/span>
  1)静态库 
  2)共?
  且只有共?将?安?/复制到您的应用软件包,虽然静态库能?用于生成共享库??/span>
  ?在每??Android.mk file ?义一?多个模块,你也可以在几个模块?用同??/span>
源代码文件??/span>
  编译系统为你处理许?细节??。例如,你不?要在你的 Android.mk?出头文件和依
赖文件?NDK 编译系统将会为你?处理这些??。这也意味着,在升级 NDK 后,你应?/span>
得到新的 toolchain/platform?,?且不需要改变你?Android.mk 文件?/span>
  注意,这??法同?发布的Android平台的开源代码很接近,然而编译系统实现他?
方式却是不同的,这是故意这样设?的,?让程序开发人员重用?部库的源代码更?易??/span>
  在描述?法细节之前,咱们来看??单的"helloworld"的例子,比?,下面的文件?/span>
 sources/helloworld/helloworld.c
 sources/helloworld/Android.mk
 'helloworld.c'??JNI 共享库,实现返回"helloworld"字?串的原生方法。相应的
Android.mk 文件会象下面这样?/span>
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE:= helloworld
 
LOCAL_SRC_FILES := helloworld.c
 
include $(BUILD_SHARED_LIBRARY)
 
  解释?下这几?代码?/span>
  LOCAL_PATH := $(call my-dir)
  ?个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树?找源文件?/span>
在这?子中?宏函数?my-dir?  由编译系统提供,用于返回当前?(即包含Android.mk file
文件的目??/span>
 
  include $(CLEAR_VARS)
  CLEAR_VARS 由编译系统提???android安??下的/build/core/config.mk 文件?/span>
到其定义,为 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk),指定? GNUMAKEFILE
为你清除许? LOCAL_XXX 变量 ( 例? LOCAL_MODULE ?LOCAL_SRC_FILES ,Android.mk 文档规范 2
LOCAL_STATIC_LIBRARIES,等等??,除 LOCAL_PATH。这?要的,因为所有的编译?/span>
制文件都在同??GNU MAKE 执?????有的变量都是全局的??/span>
 
  LOCAL_MODULE := helloworld
  LOCAL_MODULE 变量必须定义,以标识你在 Android.mk文件?述的每个模块。名?/span>
必须??的,而且不包?何空格?注意编译系统会?产生合?的前缀和后?,换句话
说,???命名?foo'的共?模块,将会生?libfoo.so'文件。注意:如果把库命名?/span>
‘libhelloworld’,编译系统将不会添加任何的 lib 前缀,也会生?libhelloworld.so,这?/span>
为了?来源?Android平台的源代码?Android.mk 文件?/span>
 
  LOCAL_SRC_FILES := helloworld.c
  LOCAL_SRC_FILES 变量必须包含将?编译打包进模块中?C 或C++源代码文件?不?/span>
在这里列出头文件和包?件,编译系统将会?找出依赖型的文件?/span>
【注意,默??C++源码文件的扩展名???cpp?。指定一?同的扩展名也?能的,只要定?/span>
LOCAL_DEFAULT_CPP_EXTENSION 变量,不要忘记开始的小圆?也就?义为 ?cxx?而不??cxx?】?/span>
 
  include $(BUILD_SHARED_LIBRARY)
  BUILD_SHARED_LIBRARY ?译系统提供的变量,指向一?GNUMakefile 脚本(应?
就是?build/core  ?下的 shared_library.mk),负责收集自从上次调?'include
$(CLEAR_VARS)'以来,定义在 LOCAL_XXX 变量??有信?并且决定编译?么,如何?/span>
?去做。并根据其?则生成静态库。同理?于静态库?/span>
 
  ?sources/samples?下有更?杂一点的例子,写有注释的 Android.mk文件?/span>
二?参?/span>
  这是?份你应??Android.mk ?赖或定义的变量列??定义其他变量为自己使?
但是 NDK编译系统保留下列变量名:
 -?LOCAL_?头的名字(例?LOCAL_MODULE?/span>
 -?PRIVATE_, NDK_ ?APP_?头的名字(内部使?
 -小写名字(内部使?例?‘my-dir’)
  如果为了方便?Android.mk ?义自己的变量,建?用MY_前缀,一?例子?/span>
MY_SOURCES := foo.c
 
ifneq ($(MY_CONFIG_BAR),)
 MY_SOURCES += bar.c
endif
 
LOCAL_SRC_FILES += $(MY_SOURCES)
 
1. GNU Make  变量
  这些 GNU Make  变量在你?Android.mk文件解析之前,就由编译系统定义好了?注意在
某些情况下,NDK?分析 Android.mk 几?,每?次某些变量的定义会有不同?/span>
  ?)CLEAR_VARS: 指向??译脚?几乎?有未定义?LOCAL_XXX 变量都在
"Module-description"节中列出。必须在?始一?模块之前包含这个脚本:include
$(CLEAR_VARS)
  ?)BUILD_SHARED_LIBRARY: 指向编译脚本,收集所有的?LOCAL_XXX 变量?
供的信息,并且决定?何把列出的源代码文件编译成一??。注意,必须至少在包?
?件之前定?LOCAL_MODULE ?LOCAL_SRC_FILES。使用例子: Android.mk 文档规范 3
include $(BUILD_SHARED_LIBRARY) 
#这将生成???lib$(LOCAL_MODULE).so 的文?/span>
 
??BUILD_STATIC_LIBRARY:  ??BUILD_SHARED_LIBRARY变量用于编译??
态库。静态库不会复制到的 project/packages ?但是能?用于编译共享库, (看下面描述?/span>
LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES)?使用例子:
include $(BUILD_STATIC_LIBRARY) 
#注意,这将会生成???lib$(LOCAL_MODULE).a 的文?/span>
 
  ?)TARGET_ARCH: ? CPU平台的名?  和android ?放源码中指定的那样??果是
arm,表示?生成 ARM 兼?的指令,?CPU架构的修订版无关?/span>
 
  ?)TARGET_PLATFORM: Android.mk 解析的时候,? Android平台的名?详情?
?development/ndk/docs/stable- apis.txt.
 android-3 -> Official Android 1.5system images
 android-4 -> Official Android 1.6system images
 android-5 -> Official Android 2.0system images
 
  ?)TARGET_ARCH_ABI:  暂时?持两个value,armeabi ?armeabi-v7a。在
现在的版???这两??简单的定义?arm?通过 android 平台内部对它重定义来获得?/span>
好的匹配。其他的 ABI 将在以后?NDK 版本?绍,它们会有不同的名字?注意所有基?/span>
ARM ?ABI都会?'TARGET_ARCH'定义成?arm’,但是会有不同的?TARGET_ARCH_ABI’??/span>
 
?7 ?TARGET_ABI:  ?平台?ABI 的组合,它事实上?义成
$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) ,在想?在真实的设??对一??
?系统进?测试时,会有用?在默?的情况下,它会是'android-3-arm'?/span>
2.  模块描述变量
 下面的变量用于向编译系统描述你的模块。你应?定义?include $(CLEAR_VARS)'
?include $(BUILD_XXXXX)'之间。?如前面描写的那样?(CLEAR_VARS)??
?清除?有这些变量,除非在描述中显式注明?/span>
  ??LOCAL_PATH: 这个变量用于给出当前文件的路径?必须在 Android.mk 的开头定
义,?这样使用?/span>
LOCAL_PATH := $(call my-dir)
 
  这个变量不会?(CLEAR_VARS)清除,因此每?Android.mk?要定义一?即使在一
?件中定义了几?块的情况??/span>
 
  ?)LOCAL_MODULE:这是模块的名字,它必须是?的,而且不能包含空格。必须在
包含任一?(BUILD_XXXX)脚本之前定义它?模块的名字决定了生成文件的名字。例如,?/span>
果一???模块的名字是,那么生成文件的名字就是 lib.so。但?在的 NDK 生成?/span>
件中(或??Android.mk 或??Application.mk),应该只涉及(引用)有?常名字的其他模块?/span>
 
  ?)LOCAL_SRC_FILES: 这是要编译的源代码文件列表?只要列出?传?给编译器的
文件,因为编译系统自动?算依赖?注意源代码文件名称都是相??LOCAL_PATH的,你可
以使用路径部分,例??/span>
LOCAL_SRC_FILES := foo.c
 toto/bar.c
 
 【注意:在生成文件中都?使用UNIX风格的斜?/).windows风格的反斜杠不会???处理。??Android.mk 文档规范 4
 
  ?)  LOCAL_CPP_EXTENSION:  这是??选变量,用来指定C++代码文件的扩展名?/span>
默??.cpp',但是?改变它,比??/span>
LOCAL_CPP_EXTENSION := .cxx
 
  ??LOCAL_C_INCLUDES: ?的可选配??根目录开始的?有源文件(C, C++
and Assembly)。比?
LOCAL_C_INCLUDES := sources/foo
或?:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
 
  ?要在任何包含 LOCAL_CFLAGS/LOCAL_CPPFLAGS 标志之前?/span>
 
  ?)LOCAL_CFLAGS:  ??的编译器?项,在编译C 代码文件的时候使用?这??
用的,指定一?加的包含?(相??NDK的顶层目?,宏定义,或者编译?项?/span>
  注意:不要在 Android.mk ??optimization/debugging级别,只要在 Application.mk ?/span>
指定合?的信息,就会自动地为你处理这个??,在调试期间,会?NDK?生成有用的数
?件??/span>
 
  ?)LOCAL_CXXFLAGS:  与LOCAL_CFLAGS 相同,针?C++源文件??/span>
 
  ?)LOCAL_CPPFLAGS:  与LOCAL_CFLAGS 相同,但?? C ?C++ source files都??/span>
用??/span>
 
  ?)LOCAL_STATIC_LIBRARIES: 应?链接到这?块的静?库列表(使用
BUILD_STATIC_LIBRARY 生成),这仅仅对共?模块才有意义?/span>
 
  ?0)LOCAL_SHARED_LIBRARIES: 这个模块在运行时要依赖的共享库模块列??/span>
链接时需要,在生成文件时嵌入的相应的信息。注意:这不会附加列出的模块到编译图,也
就是仍然?要在 Application.mk ?它们添加到程序?求的模块???/span>
 
  ?1)LOCAL_LDLIBS: 编译模块时?使用的附加的链接器?项。这对于使用?l’前?
传?指定库的名字是有用的?例如,下面将告诉链接器生成的模块?在加载时刻链接到
/system/lib/libz.so
LOCAL_LDLIBS := -lz
 
  ??docs/STABLE-APIS.TXT 获取使用NDK发?版能链接到的?放的系统库列表??/span>
 
  ?2)LOCAL_ALLOW_UNDEFINED_SYMBOLS:  默?情况下,在试图编译一??时,
任何?义的引用将?致一??未定义的?号?错??这对于在源代码文件?捉错??/span>
很大的帮助?然而,如果因为某些原因,需要不?这项?查,?这个变量设为‘true’??/span>
注意相应的共??在运行时加载失败?这个??量不要去设为 true)?/span>
 
  ?3?LOCAL_ARM_MODE: 默?情况下, arm?二进制会?thumb的形式生?16 ??/span>
你可以?过设置这个变量?arm如果你希望你?module ? 32 位指令的形式?/span>
'arm' (32-bit instructions) mode. E.g.:
LOCAL_ARM_MODE := arm
【注意:同样?在编译的时?告诉系统编译特定的类型?/span>
  Android.mk 文档规范 5
?4)LOCAL_SRC_FILES := foo.c bar.c.arm  这样就告诉系统?是将bar.c ?/span>
arm的模式编译,下面?GNU Make‘功能?宏,必须?过使用'$(call )'来求值,他们?/span>
回文?的信???/span>
 
  ?5)my-dir:返回当前 Android.mk ?在的??,相对于 NDK编译系统的顶层??/span>
这是有用的,?Android.mk 文件的开头?此定义:
LOCAL_PATH := $(call my-dir)
 
?6)all-subdir-makefiles: 返回??于当?my-dir'?的子?列表。例
如,看下面的?层??/span>
sources/foo/Android.mk
sources/foo/lib1/Android.mk
sources/foo/lib2/Android.mk
  如果 sources/foo/Android.mk 包含?行:
include $(call all-subdir-makefiles)
那么它就会自动包?sources/foo/lib1/Android.mk 和sources/foo/lib2/Android.mk。这项功
能用于向编译系统提供深层次嵌套的代码?层?。注意,在默认情况下,NDK 将会??/span>
?sources/*/Android.mk ?文件?/span>
 
?7)this-makefile:  返回当前Makefile的路?即这?数调用的地方)
 
?8)parent-makefile:  返回调用树中?Makefile ?。即包含当前Makefile ?/span>
Makefile ??/span>
 
?9)grand-parent-makefile
3. Android.mk 使用模板
  在一?Android.mk ?以生成??执?程序、动态库和静态库?/span>
?)编译应用程序的模板?/span>
#Test Exe
 
LOCAL_PATH := $(call my-dir)
 
#include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := main.c
 
LOCAL_MODULE := test_exe
 
#LOCAL_C_INCLUDES :=
 
#LOCAL_STATIC_LIBRARIES :=
 
#LOCAL_SHARED_LIBRARIES :=
 
include $(BUILD_EXECUTABLE)
  【注:??=’是赋?的意?,?’是引用某变量的值??/span>
LOCAL_SRC_FILES ?入源文件?,LOCAL_C_INCLUDES ?入所?要包??/span>
文件?,LOCAL_STATIC_LIBRARIES 加入??要链接的静?库(*.a)的名称,
LOCAL_SHARED_LIBRARIES ?入所?要链接的动?库(*.so)的名称,LOCAL_MODULEAndroid.mk 文档规范 6
表示模块?终的名称,BUILD_EXECUTABLE 表示以一?执?程序的方式进行编译??/span>
?)编译静态库的模板:
#Test Static Lib
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := \
 helloworld.c
 
LOCAL_MODULE:= libtest_static
 
#LOCAL_C_INCLUDES :=
 
#LOCAL_STATIC_LIBRARIES :=
 
#LOCAL_SHARED_LIBRARIES :=
 
include $(BUILD_STATIC_LIBRARY)
 
  和上面相似,BUILD_STATIC_LIBRARY 表示编译??态库?/span>
?)编译动态库的模板:
#Test Shared Lib
 
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := helloworld.c
 
LOCAL_MODULE := libtest_shared
 
TARGET_PRELINK_MODULES := false
 
#LOCAL_C_INCLUDES :=
 
#LOCAL_STATIC_LIBRARIES :=
 
#LOCAL_SHARED_LIBRARIES :=
 
include $(BUILD_SHARED_LIBRARY)
 
  和上面相似,BUILD_SHARED_LIBRARY 表示编译????/span>
  以上三?的生成结果分别在?下目录中,generic 依具?target 会变?/span>
out/target/product/generic/obj/EXECUTABLE
out/target/product/generic/obj/STATIC_LIBRARY
out/target/product/generic/obj/SHARED_LIBRARY
 
  每个模块的目标文件夹分别为:
 1)可执?程序:XXX_intermediates
 2)静态库?XXX_static_intermediates
 3)动态库?XXX_shared_intermediates
 
  另???Android.mk 文件? 还可以指定最后的?安???用LOCAL_MODULE_PATH Android.mk 文档规范 7
?LOCAL_UNSTRIPPED_PATH 来指定?不同的文件系统?用以下的宏进行?择?/span>
  TARGET_ROOT_OUT:表示根文件系统?/span>
   TARGET_OUT:表示system文件系统?/span>
   TARGET_OUT_DATA:表示data文件系统?/span>
用法如:
LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT)