android.mk语法详解


(一)概要


在android系统源码中,还是需要在系统环境下编译的应用程序,都可以见到android.mk的文件,该文件就是编译源代码所需要的编译文件。

下面就来分析下android.mk文件

该文件其实是GNU Makefile的一小部分,它用来对Android程序进行编译Android.mk把源码组织成不同的模块,每个模块可以是一个静态库也可以是一个动态库。动态库才会被拷贝到安装包中,静态库只能用于编译生成动态库。同一个Android.mk文件可以定义多个模块,不同的模块可以共用同一个Android.mk文件。

一个Android.mk文件可以编译多个模块,每个模块属下列类型之一
  1)APK程序
  一般的Android程序,编译打包生成apk文件
  2)JAVA库
  java类库,编译打包生成jar文件
  3)C\C++应用程序
 可执行的C\C++应用程序
  4)C\C++静态库 
编译生成C\C++静态库,并打包成.a文件
  5)C\C++共享库
编译生成共享库(动态链接库),并打包成.so文, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。

编译打包的5中方式:
(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 文件是这个模块的编译脚本,内容如下:

[plain]  view plain copy
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE    := hello-jni  
  6. LOCAL_SRC_FILES := hello-jni.c  
  7.   
  8. 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。


(三)自定义变量


 以下是在 Android.mk中依赖或定义的变量列表, 可以定义其他变量为自己使用,但是NDK编译系统保留下列变量名:
 -以 LOCAL_开头的名字(例如 LOCAL_MODULE)
 -以 PRIVATE_, NDK_ 或 APP_开头的名字(内部使用)
 -小写名字(内部使用,例如‘my-dir’)

   如果为了方便在 Android.mk 中定义自己的变量,建议使用 MY_前缀,一个小例子
MY_SOURCES := foo.c
ifneq ($(MY_CONFIG_BAR))
 MY_SOURCES += bar.c
endif
LOCAL_SRC_FILES += $(MY_SOURCES)
注意:‘:=’是赋值的意思;'+='是追加的意思;‘$’表示引用某变量的值。

(四)GNU Make系统变量

  这些 GNU Make变量在你的 Android.mk 文件解析之前,就由编译系统定义好了。

注意在某些情况下,NDK可能分析 Android.mk 几次,每一次某些变量的定义会有不同。

  (1)CLEAR_VARS:   指向一个编译脚本,几乎所有未定义的 LOCAL_XXX 变量都在"Module-description"节中列出。必须在开始一个新模块之前包含这个脚本:
           include $( CLEAR_VARS ),用于重置除LOCAL_PATH变量外的,所有LOCAL_XXX系列变量。
  (2)BUILD_SHARED_LIBRARY:   指向编译脚本,根据所有的在 LOCAL_XXX 变量把列出的源代码文件编译成一个共享库。
          注意,必须至少在包含这个文件之前定义 LOCAL_MODULE 和 LOCAL_SRC_FILES。
          include $( BUILD_SHARED_LIBRARY )
(3) BUILD_STATIC_LIBRARY:   一个BUILD_STATIC_LIBRARY变量用于编译一个静态库。静态库不会复制到的APK包中,但是能够用于编译共享库。
          示例:include $( BUILD_STATIC_LIBRARY) 
          注意,这将会生成一个名为  lib$(LOCAL_MODULE).a 的文件
  (4)TARGET_ARCH:  目标 CPU平台的名字,  和 android 开放源码中指定的那样。如果是 arm,表示要生成 ARM 兼容的指令,与 CPU架构的修订版无关。
  (5)TARGET_PLATFORM:  Android.mk 解析的时候,目标 Android 平台的名字. 详情可参考/development/ndk/docs/stable- apis.txt.
          android-3 -> Official Android 1.5 system images
          android-4 -> Official Android 1.6 system images
          android-5 -> Official Android 2.0 system images
  (6)TARGET_ARCH_ABI:   暂时只支持两个 value,armeabi 和 armeabi-v7a。在现在的版本中一般把这两个值简单的定义为 arm, 通过 android  平台内部对它重定义来获得更好的匹配。其他的 ABI 将在以后的 NDK 版本中介绍,它们会有不同的名字。注意虽然所有基于 ARM的ABI都会把 'TARGET_ARCH'定义成‘arm’, 但是会有不同的‘TARGET_ARCH_ABI’。 
( 7 ) TARGET_ABI:   目标平台和 ABI 的组合,它事实上被定义成$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)  ,在想要在真实的设备中针对一个特别的目标系统进行测试时,会有用。在默认的情况下,它会是'android-3-arm'。

(五)模块描述变量

下面这些变量用于对模块进行描述,这些变量应该在 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之后,输出文件名就是这个变量指定的名字,例如:

[plain]  view plain copy
  1. LOCAL_MODULE := foo-version-1  
  2. LOCAL_MODULE_FILENAME := libfoo  
注意: LOCAL_MODULE_FILENAME不支持文件路径(所以不能有斜杠),不要写扩展名(文件路径和文件扩展名是由编译工具自动加上的)

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:指该模块在所有版本下都编译


LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)  编译打包后,指定模块最后的目标存放路径
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模块的声明如下:

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo  
  3. LOCAL_SRC_FILES := foo/foo.c  
  4. LOCAL_EXPORT_CFLAGS := -DFOO=1  
  5. include $(BUILD_STATIC_LIBRARY)  
bar模块依赖foo模块,声明如下:

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := bar  
  3. LOCAL_SRC_FILES := bar.c  
  4. LOCAL_CFLAGS := -DBAR=2  
  5. LOCAL_STATIC_LIBRARIES := foo  
  6. include $(BUILD_SHARED_LIBRARY)  
因此在编译bar模块的时候,它的编译器标志就是 “-DFOO=1 -DBAR=2”。 导出的flags 加上本模块的 LOCAL_CFLAGS,成为最后传给编译器的flags。这样修改起来就很容易。这种依赖关系是可传递的,例如,如果zoo依赖bar,bar依赖foo,那么zoo就会同时有bar和foo的导出flags。

注意,编译模块自身时,不会使用它所导出的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 可以用于导出该依赖:

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo  
  3. LOCAL_SRC_FILES := foo/foo.c  
  4. LOCAL_EXPORT_LDLIBS := -llog  
  5. include $(BUILD_STATIC_LIBRARY)  
  6.   
  7. include $(CLEAR_VARS)  
  8. LOCAL_MODULE := bar  
  9. LOCAL_SRC_FILES := bar.c  
  10. LOCAL_STATIC_LIBRARIES := foo  
  11. include $(BUILD_SHARED_LIBRARY)  
此处在编译bar模块的时候,它的链接器标志将加上一个 -llog,表示它依赖于系统提供的 liblog.so,因为它依赖 foo 模块。

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文件。

换句话说,如果你定义:

[plain]  view plain copy
  1. LOCAL_SRC_FILES  := foo.c bar.S  
  2. LOCAL_FILTER_ASM := myasmfilter  
则foo.c首先传给编译器(gcc),得到 foo.S.orignal,然后这个 foo.S.original 被传给你指定的过滤器(LOCAL_ASM_FILTER),得到 foo.S,然后再传给汇编器(例如as),得到 foo.o。 bar.S 直接传给过滤器得到 bar.S.new,然后再传给汇编器,得到 bar.o。即在从*.S到*.o的编译流程中增加了一个过滤的环节。

过滤器必须是独立的shell命令,输入文件作为它的第一个命令行参数,输出文件作为第二个命令行参数,例如:

[plain]  view plain copy
  1.     myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S  
  2.     myasmfilter bar.S $OBJS_DIR/bar.S  


(六)GNU Make‘功能’宏

GNU Make‘功能’宏,必须通过使用'$(call  )'来调用 ,调用他们将返回文本化的信息。
(1)my-dir: 返回当前 Android.mk 所在的目录的路径,相对于 NDK 编译系统的顶层。这是有用的,在 Android.mk 文件的开头如此定义:
LOCAL_PATH := $(call my-dir)
(2)all-subdir-makefiles:  返回一个位于当前'my-dir'路径的子目录中的所有Android.mk的列表
例如,看下面的目录层次:
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 将会只搜索在 sources/*/Android.mk 中的文件。
(3)this-makefile:   返回当前Makefile 的路径(即这个函数调用的地方)
(4)parent-makefile:   返回调用树中父 Makefile 路径。即包含当前Makefile的Makefile 路径。
(5)grand-parent-makefile: 返回调用树中父Makefile的父Makefile的路径


(七)参考模板


(1)在android里在编译一个java应用时,如果这个应用需要引入一个第三方的jar包,那么就需要将这个三方的jar包通过mk文件将其编译到apk里,下面是将一个三方的jar包编译到apk包里的方法.

  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_MODULE_TAGS :eng  
  5.   
  6. LOCAL_SRC_FILES := $(call all-subdir-java-files)  
  7.   
  8. #在该模块中使用预编译好的静态jar包  
  9. LOCAL_STATIC_JAVA_LIBRARIES :android-support-v4  hiconfigserviceapi  hitv  
  10.   
  11. LOCAL_PACKAGE_NAME :HiConfigService  
  12.   
  13. LOCAL_PROGUARD_ENABLED :disabled  
  14.   
  15. LOCAL_CERTIFICATE :platform  
  16. #指定编译该模块为apk  
  17. include $(BUILD_PACKAGE)  
  18.   
  19.   
  20. include $(CLEAR_VARS)  
  21. #预编译静态jar包。形式为:随便取的名字 :jar包的真实路径  
  22. LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=android-support-v4:libs/android-support-v4.jar\  
  23. hiconfigserviceapi:libs/hiconfigserviceapi.jar\  
  24. hitv:libs/hitv.jar  
  25.   
  26. 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

  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE_TAGS :optional  
  4.   
  5. LOCAL_SRC_FILES := $(call all-java-files-under, src)  
  6.   
  7. LOCAL_PACKAGE_NAME :TestJNI  
  8.   
  9. #就是把so文件放到apk文件里的libs/armeabi里  
  10. LOCAL_JNI_SHARED_LIBRARIES :libHimediaAnimation  
  11.   
  12. LOCAL_CERTIFICATE :platform  
  13.   
  14.   
  15. include $(BUILD_PACKAGE)  
  16. #为了编译so文件  
  17. 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。基本也一样。

请参考NDK官方开发指南翻译之 Android.mk


在android系统源码中,根目录下有个Makefile 文件,内容为include build/core/main.mk。这是android系统编译的开始,由此也就开始分析android源码的编译。

请参考 android makefile 编译分析及 android.mk分析



上面只是涉及了简单的android.mk,开发者要怎么看懂系统中的android.mk,就需要对makefile文件的语法和规则有个了解。

请参考(学习中。。。)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这些都是 Android NDK 内部的 `Android.mk` 文件。其中,`./android-ndk-r25c/sources/android/native_app_glue/Android.mk` 是用于编译 Native Activity 示例应用程序的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/support/Android.mk` 是包含一些 Android 支持库的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/ndk_helper/Android.mk` 是包含一些辅助函数和类的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/cpufeatures/Android.mk` 是用于编译 `cpufeatures` 库的 `Android.mk` 文件,该库提供了一些 CPU 相关的信息和功能;`./android-ndk-r25c/sources/cxx-stl/llvm-libc++abi/Android.mk` 和 `./android-ndk-r25c/sources/cxx-stl/llvm-libc++/Android.mk` 是用于编译 C++ STL 库的 `Android.mk` 文件,分别对应 libc++abi 和 libc++ 两个 STL 库;`./android-ndk-r25c/sources/third_party/googletest/Android.mk` 是用于编译 Google Test 测试框架的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/Android.mk` 是用于编译 Shaderc 编译器的 `Android.mk` 文件,该编译器可以将 GLSL 代码编译成 SPIR-V 代码;`./android-ndk-r25c/sources/third_party/shaderc/libshaderc/Android.mk` 是用于编译 Shaderc 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/libshaderc_util/Android.mk` 是用于编译 Shaderc Util 库的 `Android.mk` 文件,该库提供了一些辅助函数和类;`./android-ndk-r25c/sources/third_party/shaderc/third_party/Android.mk` 是用于编译 Shaderc 编译器依赖的第三方库的 `Android.mk` 文件,包括 glslang 和 spirv-tools 两个库;`./android-ndk-r25c/sources/third_party/shaderc/third_party/glslang/Android.mk` 是用于编译 glslang 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/third_party/spirv-tools/Android.mk` 是用于编译 spirv-tools 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/vulkan/src/build-android/jni/Android.mk` 是用于编译 Vulkan 库的 `Android.mk` 文件。 如果您要在 Android NDK 中编写自己的 `Android.mk` 文件,可以参考这些示例文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值