https://www.cnblogs.com/reality-soul/p/6893248.html
一、Android.mk介绍
Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。
它的基本格式如下:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- ................
- LOCAL_xxx := xxx
- LOCAL_MODULE := hello-jni
- LOCAL_SRC_FILES := hello-jni.c
- LOCAL_xxx := xxx
- ................
- include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH变量制定了该.mk的路径,$(call my-dir)调用NDK内部的函数获得当前.mk文件的路径
include $(CLEAR_VARS)清空了除了LOCAL_PATH之外的所有LOCAL_xxx变量的值
省略号中间就是对于模块参数的设置,主要包括:模块名字、模块源文件、模块类型、编译好的模块存放位置、以及编译的平台等
include $(BUILD_xxx_xxx)执行NDK的默认脚本,它会收集include $(CLEAR_VARS)脚本后所有定义的LOCAL_xxx变量,然后根据它们来生成模块。
二、Android.mk语法详解
LOCAL_PATH := $(call my-dir)
每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。宏my-dir 则由Build System提供。返回包含Android.mk的目录路径。
include $(CLEAR_VARS)
CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.
这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
LOCAL_MODULE := hello-jni
LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so. 但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀
LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT) 指定最后生成的模块的目标地址
TARGET_ROOT_OUT:根文件系统,路径为out/target/product/generic/root
TARGET_OUT:system文件系统,路径为out/target/product/generic/system
TARGET_OUT_DATA:data文件系统,路径为out/target/product/generic/data
除了上面的这些,NDK还提供了很多其他的TARGET_XXX_XXX变量,用于将生成的模块拷贝到输出目录的不同路径
默认是TARGET_OUT
LOCAL_SRC_FILES := hello-jni.c
LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码。不必列出头文件,build System 会自动帮我们找出依赖文件。缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。
它负责收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。
BUILD_STATIC_LIBRARY :编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE :编译为Native C可执行程序
BUILD_PREBUILT :该模块已经预先编译
NDK还定义了很多其他的BUILD_XXX_XXX变量,它们用来指定模块的生成方式。
三、使用示例
- #编译静态库
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE = libhellos
- LOCAL_CFLAGS = $(L_CFLAGS)
- LOCAL_SRC_FILES = hellos.c
- LOCAL_C_INCLUDES = $(INCLUDES)
- LOCAL_SHARED_LIBRARIES := libcutils
- LOCAL_COPY_HEADERS_TO := libhellos
- LOCAL_COPY_HEADERS := hellos.h
- include $(BUILD_STATIC_LIBRARY)
- #编译动态库
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE = libhellod
- LOCAL_CFLAGS = $(L_CFLAGS)
- LOCAL_SRC_FILES = hellod.c
- LOCAL_C_INCLUDES = $(INCLUDES)
- LOCAL_SHARED_LIBRARIES := libcutils
- LOCAL_COPY_HEADERS_TO := libhellod
- LOCAL_COPY_HEADERS := hellod.h
- include $(BUILD_SHARED_LIBRARY)
- #使用静态库
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := hellos
- LOCAL_STATIC_LIBRARIES := libhellos
- LOCAL_SHARED_LIBRARIES :=
- LOCAL_LDLIBS += -ldl
- LOCAL_CFLAGS := $(L_CFLAGS)
- LOCAL_SRC_FILES := mains.c
- LOCAL_C_INCLUDES := $(INCLUDES)
- include $(BUILD_EXECUTABLE)
- #使用动态库
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := hellod
- LOCAL_MODULE_TAGS := debug
- LOCAL_SHARED_LIBRARIES := libc libcutils libhellod
- LOCAL_LDLIBS += -ldl
- LOCAL_CFLAGS := $(L_CFLAGS)
- LOCAL_SRC_FILES := maind.c
- LOCAL_C_INCLUDES := $(INCLUDES)
- include $(BUILD_EXECUTABLE)
- #拷贝文件到指定目录
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := bt_vendor.conf
- LOCAL_MODULE_CLASS := ETC
- LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
- LOCAL_MODULE_TAGS := eng
- LOCAL_SRC_FILES := $(LOCAL_MODULE)
- include $(BUILD_PREBUILT)
- #拷贝动态库到指定目录
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- #the data or lib you want to copy
- LOCAL_MODULE := libxxx.so
- LOCAL_MODULE_CLASS := SHARED_LIBRARIES
- LOCAL_MODULE_PATH := $(ANDROID_OUT_SHARED_LIBRARIES)
- LOCAL_SRC_FILES := lib/$(LOCAL_MODULE )
- OVERRIDE_BUILD_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)
- include $(BUILD_PREBUILT)
参考文章:
http://www.cnblogs.com/wainiwann/p/3837936.html
(一)概要
在android系统源码中,还是需要在系统环境下编译的应用程序,都可以见到android.mk的文件,该文件就是编译源代码所需要的编译文件。
下面就来分析下android.mk文件
该文件其实是GNU Makefile的一小部分,它用来对Android程序进行编译。Android.mk把源码组织成不同的模块,每个模块可以是一个静态库也可以是一个动态库。动态库才会被拷贝到安装包中,静态库只能用于编译生成动态库。同一个Android.mk文件可以定义多个模块,不同的模块可以共用同一个Android.mk文件。
(1)APK程序
一般的Android程序,编译打包生成apk文件
(out/target/product/generic/obj/APPS/XXX_intermediates)
(2)JAVA库
java类库,编译打包生成jar文件
(out/target/product/generic/obj/JAVA_LIBRARIES/XXX_intermediates)
(3)C\C++应用程序
可执行的C\C++应用程序
(out/target/product/generic/obj/EXECUTABLE/XXX_intermediates)
(4)C\C++静态库
编译生成C\C++静态库,并打包成.a文件
(out/target/product/generic/obj/STATIC_LIBRARY/XXX_static_intermediates)
(5)C\C++共享库
编译生成共享库(动态链接库),并打包成.so文, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。
(out/target/product/generic/obj/SHARED_LIBRARY/XXX_shared_intermediates)
代码:
include $(BUILD_PACKAGE)
编译打包成APK文件
include $(BUILD_STATIC_JAVA_LIBRARY)
用它来编译生成JAVA库(打包成.jar文件)
include $(BUILD_EXECUTABLE)
编译C/C++应用程序
include $(BUILD_STATIC_LIBRARY)
用它来编译生成C\C++静态库(打包成.a文件)
include $(BUILD_SHARED_LIBRARY)
指向一个 GNU Makefile 脚本(应该就是在 build/core目录下的 shared_library.mk),用它来编译生成共享库(动态链接库.so)
注意,NDK所使用的Android.mk文件的语法与Android操作系统的开放源码中的Android.mk的语法非常接近,但是编译系统实现他们的方式却是不同的,这是为了方便应用程序开发人员复用以前的代码。
(二)简单示例
jni/Android.mk 文件是这个模块的编译脚本,内容如下:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := hello-jni
- LOCAL_SRC_FILES := hello-jni.c
- include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
每个Android.mk文件都必须在开头定义 LOCAL_PATH 变量。这个变量被用来寻找C/C++源文件。在该例中,my-dir 是一个由编译系统提供的宏函数,用于返回Android.mk所在目录的路径。
include $(CLEAR_VARS)
CLEAR_VARS是编译系统预定义的一个变量,它指向一个特殊的Makefile,这个Makefile负责清除 LOCAL_xxx 的变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES 等)但不会清除 LOCAL_PATH。之所以需要清理这些变量是因为所有的编译控制文件是在一趟make执行过程中完成的,而所有的变量都是全局的,会对其他Android.mk文件产生影响。
LOCAL_MODULE := hello-jni
LOCAL_MODULE 用来给每个模块定义一个名字,不同模块的名字不能相同,不能有空格。这里的名字会传给NDK编译系统,然后加上lib前缀和.so后缀 (例如,变成libhello-jni.so)。注意,如果你在LOCAL_MODULE定义中自己加上了lib前缀,则ndk在处理的时候就不会再加上lib前缀了(为了兼容Android系统的一些源码)。
LOCAL_SRC_FILES := hello-jni.c
在LOCAL_SRC_FILES 变量里面列举出对应于同一个模块的、要编译的那些文件,这里不要把头文件加进来,编译系统可以自动检测头文件依赖关系。默认情况下,C++源码文件的扩展名应该是cpp,如果想修改的话,将变量LOCAL_CPP_EXTENSION修改为你想要的扩展名,注意句点。例如:LOCAL_CPP_EXTENSION := .cxx
include $(BUILD_SHARED_LIBRARY)
这个 BUILD_SHARED_LIBRARY也是预定义的变量,也是指向一个Makefile,负责将你在 LOCAL_XXX 等变量中定义信息收集起来,确定要编译的文件,如何编译。如果要编译的是静态库而不是动态库,则可以用 BUILD_STATIC_LIBRARY。
(三)自定义变量
下面这些变量用于对模块进行描述,这些变量应该在 include $(CLEAR_VARS) 和 include $(BUILD_XXXX) 之间定义好。
LOCAL_PATH (必须)
这个变量表示当前文件(一般是Android.mk)所在的路径,该变量很重要,必须定义(在Android.mk文件的开头处定义)。常见写法如下:
LOCAL_PATH := $(call my-dir)
宏函数‘my-dir’, 由编译系统提供, 用于返回当前路径(即包含Android.mk file文件的目录)。(第7部分会详细介绍)
该变量不会被 include $(CLEAR_VARS) 清空,所以不论Android.mk定义了几个模块,一个Android.mk只需要在开头定义一次即可。
include $(CLEAR_VARS)
CLEAR_VARS是一个GNU Make系统变量,指向一个编译脚本。该脚本功能为你清除许多 LOCAL_XXX 变量 ( 例如 LOCAL_MODULE , LOCAL_SRC_FILES ,LOCAL_STATIC_LIBRARIES,等等…),除 LOCAL_PATH外。
( android 安装目录下的/build/core/config.mk 文件看到其定义)
LOCAL_MODULE (必须)
该变量定义当前模块的名字,名字必须唯一,不能有空格。这个变量必须在 include $(BUILD_XXX) 之前定义好。默认情况下,这里的名字会用来得到输出文件的名字。例如模块名为foo,则得到的输出文件为libfoo.so。但是,如果你要在其他模块的Android.mk文件或Application.mk中引用这个模块,应该用foo这个模块名,而不要用libfoo.so这个文件名。
LOCAL_MODULE_FILENAME (可选)
该变量可以用来重定义输出文件的名字。默认情况下,foo模块得到的静态库的名字为 libfoo.a,动态库的名字为libfoo.so(UNIX规范)。当定义了LOCAL_MODULE_FILENAME之后,输出文件名就是这个变量指定的名字,例如:
- LOCAL_MODULE := foo-version-1
- LOCAL_MODULE_FILENAME := libfoo
LOCAL_SRC_FILES (必须)
该变量用来指定该模块对应的源文件,只把需要传给编译器的源文件名加进LOCAL_SRC_FILES,编译系统会自动处理头文件依赖。这里的文件名都是以 LOCAL_PATH 作为当前目录的(即相对于LOCAL_PATH目录),例如:
LOCAL_SRC_FILES := foo.c \ #如果要换行,用反斜杠
bar.c
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE_TAGS
LOCAL_MODULE_TAGS :=user eng tests optional samples shell_ash shell_mksh
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:表示system文件系统。
TARGET_OUT_DATA:表示data文件系统。
LOCAL_CPP_EXTENSION (可选)
用来定义C++代码文件的扩展名。必须以句点开头(即 “.”),默认值是“.cpp”,可以修改,例如:
LOCAL_CPP_EXTENSION := .cxx
从 NDK r7 这个版本开始,该变量可以支持多个扩展名了,例如:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES (可选)
该变量用来指定C++代码所依赖的特殊C++特性。例如,如果要告诉编译器你的C++代码使用了RTTI(RunTime Type Information):
LOCAL_CPP_FEATURES := rtti
如果要指定你的C++代码使用了C++异常,则:
LOCAL_CPP_FEATURES := exceptions
该变量可以同时指定多个特性。例如: LOCAL_CPP_FEATURES := rtti features
这个变量的作用就是在编译模块的时候,开启相应的编译器/链接器标志。对于预编译的文件,该变量表明该预编译的库依赖了这些特性,从而确保最后的链接工作正确进行。与该变量等价的做法是在LOCAL_CPPFLAGS中写上 -frtti -fexceptions 等标志选项。但是,推荐用这里的方法。
LOCAL_C_INCLUDES
一个路径的列表,是NDK根目录的相对路径(LOCAL_SRC_FILES中的文件相对于LOCAL_PATH)。当编译C/C++、汇编文件时,这些路径将被追加到头文件搜索路径列表中。例如:
LOCAL_C_INCLUDES := sources/foo
或者, LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
这里的搜索路径会放在LOCAL_CFLAGS/LOCAL_CPPFALGS等标志的前面。 当使用ndk-gdb的时候,LOCAL_C_INCLUDES中的路径也会被用到。
LOCAL_CFLAGS
指定当编译C/C++源码的时候,传给编译器的标志。它一般用来指定其他的编译选项和宏定义。
注意:尽量不要在Android.mk中修改优化/调试等级,因为在Application.mk中定义了相关信息之后编译系统会自动处理这些问题。
LOCAL_CXXFLAGS (废除, LOCAL_CPPFLAGS的别名)
LOCAL_CPPFLAGS (可选)
编译C++代码的时候传递给编译器的选项(编译C代码不会用这里的选项)。最后得到的命令行选项中,这里指定的选项在 LOCAL_CFLAGS 指定的选项的后面。
LOCAL_STATIC_LIBRARIES
指定应该链接到当前模块的静态库(可指定多个)。当前模块是动态库时,该选项才有意义。
LOCAL_SHARED_LIBRARIES
指定的是运行时该模块所依赖共享库(可指定多个)。这些信息是链接阶段必须的。
LOCAL_WHOLE_STATIC_LIBRARIES
它是LOCAL_STATIC_LIBRARIES的变体,用来表示它对应的模块对于linker来说应该是一个“whole archive”(见GNU linker 文档,关于 --whole-archive的资料)。当静态库之间有循环依赖时,会用到这个选项。注意,当编译动态库时,这个选项会强行把所有的对象文件组装到一起;不过,在编译可执行文件的时候情况不是这样的。
LOCAL_LDLIBS
用来指定模块编译时的其余连接器标志。例如:
LOCAL_LDLIBS := -lz
告诉链接器在加载该共享库的时候必须链接 /system/lib/libz.so 这个共享库。
如果想知道Android系统中有哪些共享库可以链接,参考 Stable APIs。
LOCAL_ALLOW_UNDEFINED_SYMBOLS
默认情况下,当编译一个共享库的时候,遇到未定义符号引用就会报告一个“undefined symbol”错误。这有助于修复你的代码中存在的bug。
如果因为某种原因,必须禁止该检测,可以把这个变量设置为true。注意,编译出的共享库有可能在加载的时候就报错导致程序退出。
LOCAL_ARM_MODE
LOCAL_ARM_NEON
LOCAL_DISABLE_NO_EXECUTE
Android NDK r4增加了对“NX bit“安全特性的支持。它是默认开启的,如果你确定自己不需要该特性,你可以将它关闭,即:
LOCAL_DISABLE_NO_EXECUTE := true
该变量不会修改ABI,只会在 ARMv6以上的CPU的内核上启用。开启该特性编译出的代码无需修改可运行在老的CPU上(也就是说所有ARM的CPU都能运行)。
参考信息:
http://en.wikipedia.org/wiki/NX_bit
http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
LOCAL_EXPORT_CFLAGS
这个变量定义一些C/C++编译器flags。这些flags(标志)会被追加到使用了这个模块(利用LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES)的模块的LOCAL_CFLAGS 定义中去。
假如foo模块的声明如下:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo
- LOCAL_SRC_FILES := foo/foo.c
- LOCAL_EXPORT_CFLAGS := -DFOO=1
- include $(BUILD_STATIC_LIBRARY)
- include $(CLEAR_VARS)
- LOCAL_MODULE := bar
- LOCAL_SRC_FILES := bar.c
- LOCAL_CFLAGS := -DBAR=2
- LOCAL_STATIC_LIBRARIES := foo
- include $(BUILD_SHARED_LIBRARY)
注意,编译模块自身时,不会使用它所导出的flags。例如在编译上面的foo模块时, -DFOO=1 不会传递给编译器。
LOCAL_EXPORT_CPPFLAGS
与 LOCAL_EXPORT_CFLAGS 相同,是跟C++相关的标志。
LOCAL_EXPORT_C_INCLUDES
与 LOCAL_EXPORT_CFLAGS 相同,但是只用于头文件搜索路径。当你的共享库有多个模块,而且互相之间有头文件依赖时有用。用法详见 Import Module。
LOCAL_EXPORT_LDLIBS
与 LOCAL_EXPORT_CFLAGS 相同,但是只用于连接器的flag。注意这里被导人的链接器标志将追加到模块的 LOCAL_LDLIBS。
例如当foo模块是一个静态库并且代码依赖于系统库时,该变量非常有用。 LOCAL_EXPORT_LDLIBS 可以用于导出该依赖:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo
- LOCAL_SRC_FILES := foo/foo.c
- LOCAL_EXPORT_LDLIBS := -llog
- include $(BUILD_STATIC_LIBRARY)
- include $(CLEAR_VARS)
- LOCAL_MODULE := bar
- LOCAL_SRC_FILES := bar.c
- LOCAL_STATIC_LIBRARIES := foo
- include $(BUILD_SHARED_LIBRARY)
LOCAL_FILTER_ASM
这个变量指定一个shell命令,用于过滤LOCAL_SRC_FILES 中列出的汇编文件或者LOCAL_SRC_FILES列出的文件所编译出的汇编文件。定义该变量后,将导致以下行为:
1)所有的C/C++源码首先翻译为临时汇编文件(如果不定义LOCAL_FILTER_ASM,则C/C++源码直接编译为 obj 文件)
2)这些汇编文件被传给 LOCAL_FILTER_ASM 所指定的shell命令处理,得到一批新的汇编文件。
3)这些新的汇编文件再被编译成obj文件。
换句话说,如果你定义:
- LOCAL_SRC_FILES := foo.c bar.S
- LOCAL_FILTER_ASM := myasmfilter
过滤器必须是独立的shell命令,输入文件作为它的第一个命令行参数,输出文件作为第二个命令行参数,例如:
- myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
- myasmfilter bar.S $OBJS_DIR/bar.S
(七)参考模板
(1)在android里在编译一个java应用时,如果这个应用需要引入一个第三方的jar包,那么就需要将这个三方的jar包通过mk文件将其编译到apk里,下面是将一个三方的jar包编译到apk包里的方法.
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE_TAGS := eng
- LOCAL_SRC_FILES := $(call all-subdir-java-files)
- #在该模块中使用预编译好的静态jar包
- LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 hiconfigserviceapi hitv
- LOCAL_PACKAGE_NAME := HiConfigService
- LOCAL_PROGUARD_ENABLED := disabled
- LOCAL_CERTIFICATE := platform
- #指定编译该模块为apk
- include $(BUILD_PACKAGE)
- include $(CLEAR_VARS)
- #预编译静态jar包。形式为:随便取的名字 :jar包的真实路径
- LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=android-support-v4:libs/android-support-v4.jar\
- hiconfigserviceapi:libs/hiconfigserviceapi.jar\
- hitv:libs/hitv.jar
- include $(BUILD_MULTI_PREBUILT)
重要的语句
LOCAL_STATIC_JAVA_LIBRARIES := googlemap(别名)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := googlemap:libs/armeabi/maps.jar (格式是:别名:JAR路径)
BUILD_MULTI_PREBUILT
Android提供了Prebuilt编译方法,两个文件prebuilt.mk和multi_prebuilt.mk,对应的方法宏是BUILD_PREBUILT和 BUILD_MULTI_PREBUILT。
prebuilt.mk就是prebuilt的具体实现,它是针对独立一个文件的操作,multi_prebuilt.mk是针对多个文件的,它对多个文件进行判断,然后调用prebuilt对独立一个文件进行处理。
如果直接用prebuilt.mk的话还是比较麻烦的,得仔细看好需要的宏,如果使用multi_prebuilt.mk会更方便些,很多它都帮忙处理了。
(2)
做JNI开发,需要把jni编译生成的so文件一起打包成apk
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE_TAGS := optional
- LOCAL_SRC_FILES := $(call all-java-files-under, src)
- LOCAL_PACKAGE_NAME := TestJNI
- #就是把so文件放到apk文件里的libs/armeabi里
- LOCAL_JNI_SHARED_LIBRARIES := libHimediaAnimation
- LOCAL_CERTIFICATE := platform
- include $(BUILD_PACKAGE)
- #为了编译so文件
- include $(LOCAL_PATH)/jni/Android.mk
重点:
include $(LOCAL_PATH)/jni/Android.mk 编译生成so文件在out/target/product/***/system/lib目录下
然后,LOCAL_JNI_SHARED_LIBRARIES := libHimediaAnimation 引用该目录下的libHimediaAnimation.so共享文件
自动拷贝到libs/armeabi里,随apk一起打包
在源码下,只需要在工程目录mm,就可以编译整个JNI工程了。
(3)编译一个需要platform key签名的APK
LOCAL_PACKAGE_NAME := LocalPackage (apk名)
LOCAL_CERTIFICATE := platform (后面是签名文件的文件名)
关于NDK开发时也使用到了android.mk。基本也一样。
在android系统源码中,根目录下有个Makefile 文件,内容为include build/core/main.mk。这是android系统编译的开始,由此也就开始分析android源码的编译。
请参考 android makefile 编译分析及 android.mk分析
上面只是涉及了简单的android.mk,开发者要怎么看懂系统中的android.mk,就需要对makefile文件的语法和规则有个了解。
请参考(学习中。。。)