精华内容
下载资源
问答
  • Android.mk中有很多变量都是在其他地方传过来的,有时候找不到对应关系,就不知道当前的Android.mk里面的变量的值到底是多少? 在Android.mk中是可以添加打印的,那么就可以实现将Android.mk中的变量打印出来。...

    Android.mk中有很多变量都是在其他地方传过来的,有时候找不到对应关系,就不知道当前的Android.mk里面的变量的值到底是多少?

     

    在Android.mk中是可以添加打印的,那么就可以实现将Android.mk中的变量打印出来。如下:

    遵循gnu make的语法规则,查看gun make手册可知,gnu make提供了两个函数用来输出打印信息或者控制make的执行过程,分别是:
    
    $(error "TEXT......")
    
    这个函数被执行的时候,会输出:TEXT......,并且终止make的执行。
    
    $(warning "TEXT......")
    
    这个函数被执行的时候,会输出:TEXT......,但是make会继续执行下去。
    
    其中“TEXT.....”可以替换为对变量的取值来输出变量的信息,例如:$(warning $(VAR)),那么该函数执行的时候会输出变量VAR的值。

     

    展开全文
  •     Android.bp入门指南之Android.mk转换成Android.bp 前言   在前面的篇章初识Android.bp和Android.bp入门指南之语法初识我们对Android.bp是啥和基本语法都有了一个初步层次的认识。Android的妈咪谷歌当然也...

        Android.bp入门指南之Android.mk转换成Android.bp


    Android源码编译系列博客:

    Android.bp你真的了解吗
    Android.bp入门指南之Android.mk转换成Android.bp
    Android.bp入门指南之浅析Android.bp语法
    Android.bp正确姿势添加宏控制编译指南
    Android高版本P/Q/R源码编译指南
    如何在线查看Android源码自带学习文档docs



    引言

      在前面的篇章初识Android.bpAndroid.bp入门指南之语法初识我们对Android.bp是啥和基本语法都有了一个初步层次的认识。Android的妈咪谷歌当然也考虑到了,从Android.mk切换到Android,mk需要一定的时间,从而为我们精心开发了一个工具androidmk,但是这个工具不是很完善,对于一些Android.mk中的宏开关就无从处理了。本篇今天就带领大伙认识一下androidmk工具的使用。

    注意:本篇是以Android 9的工程来进行讲解的。




    一 初探androidmk

    1.1 androidmk的源码和位置

    首先让我们从androidmk的框架和源码如下来说起,我们知道Android的最新编译系统的文件架构如下:
    在这里插入图片描述

    xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ ls -l build
    total 16
    drwxr-xr-x 14 xxx pd 4096 Feb 17 14:18 blueprint
    lrwxrwxrwx  1 xxx pd   25 Feb 20 11:17 buildspec.mk.default -> make/buildspec.mk.default
    lrwxrwxrwx  1 xxx pd   17 Feb 20 11:17 CleanSpec.mk -> make/CleanSpec.mk
    lrwxrwxrwx  1 xxx pd    9 Feb 20 11:17 core -> make/core
    lrwxrwxrwx  1 xxx pd   16 Feb 20 11:17 envsetup.sh -> make/envsetup.sh
    drwxr-xr-x  5 xxx pd 4096 Feb 17 14:18 kati
    drwxr-xr-x  6 xxx pd 4096 Feb 20 15:05 make
    drwxr-xr-x 21 xxx pd 4096 Feb 20 15:08 soong
    lrwxrwxrwx  1 xxx pd   11 Feb 20 11:17 target -> make/target
    lrwxrwxrwx  1 xxx pd   10 Feb 20 11:17 tools -> make/tools
    
    

    而我们的androidmk的源码目录位置如下:
    在这里插入图片描述

    xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ ls -l build/soong/androidmk/
    total 12
    -rw-r--r-- 1 xxx pd 1302 Feb 17 14:18 Android.bp
    drwxr-xr-x 3 xxx pd 4096 Feb 17 14:18 cmd
    drwxr-xr-x 2 xxx pd 4096 Feb 17 14:18 parser
    
    

    编译Android源码以后,最好androidmk生成的位置如下:
    在这里插入图片描述

    xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ find .  -name androidmk -type f
    ./out/soong/host/linux-x86/bin/androidmk
    
    

    1.2 androidmk的用法

    在前面的章节,我们降解了androidmk的源码位置和编译完成之后的执行文件的路径,在这个章节我们将要讲解androidmk的使用,如下:
    在这里插入图片描述

    xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ androidmk 
    usage: androidmk [flags] <inputFile>
    
    androidmk parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)
    xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$
    

    用一句通俗的话来讲就是androidmk Android.mk > Android.bp


    1.3 androidmk的实际使用

    好了,前面说了这么多,都是为了实际运行,那么我们通过几个实例来看看androidmk究竟有啥魔力。

    1.3.1 生成App

    让我们先来看看生成App的Android.mk文件如下:

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE_TAGS := optional
    
    LOCAL_JAVA_LIBRARIES := services
    LOCAL_SRC_FILES := $(call all-java-files-under, src)
    LOCAL_SRC_FILES += \
        src/android/bluetooth/IXxxBtPrinter.aidl \
    
    #LOCAL_SDK_VERSION := current
    LOCAL_PRIVATE_PLATFORM_APIS := true
    LOCAL_PACKAGE_NAME := XxxBtPrinter
    #LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    
    #add this for generate and print barcode
    LOCAL_STATIC_JAVA_LIBRARIES := zxing_api
    LOCAL_DEX_PREOPT := false
    LOCAL_CERTIFICATE := platform
    
    include $(BUILD_PACKAGE)
    
    # Use the folloing include to make our test apk.
    include $(call all-makefiles-under,$(LOCAL_PATH))
    
    include $(CLEAR_VARS)
    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := zxing_api:libs/core_3.2.0.jar
    include $(BUILD_MULTI_PREBUILT)
    

    执行转换命令:

    
    //注意生成的不一定要叫做Android.bp可以叫做其它的
    androidmk  Android.mk  > Android.bp
    
    

    让我们先来看看生成Android.bp内容如下:

    android_app {
    
        libs: ["services"],
        srcs: ["src/**/*.java"] + ["src/android/bluetooth/IXxxBtPrinter.aidl"],
    
        //LOCAL_SDK_VERSION := current
        // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_PRIVATE_PLATFORM_APIS
        // LOCAL_PRIVATE_PLATFORM_APIS := true
    
        name: "XxxBtPrinter",
        //LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    
        //add this for generate and print barcode
        static_libs: ["zxing_api"],
        dex_preopt: {
            enabled: false,
        },  
        certificate: "platform",
    
    }
    
    // Use the folloing include to make our test apk.
    
    // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
    // LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := zxing_api:libs/core_3.2.0.jar
    
    // ANDROIDMK TRANSLATION ERROR: unsupported include
    // include $(BUILD_MULTI_PREBUILT)
    
    

    这里可以看到预编译的转换是没有成功的,所以androidmk还是有一些不是很智能的,需要手动去修改。

    1.3.2 生成可执行文件

    先让我们看看生成可执行文件的Android.mk的定义:

    
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := nativetest
    LOCAL_SRC_FILES := apitest.c
    LOCAL_CFLAGS += -Wno-error=implicit-function-declaration
    
    LOCAL_SHARED_LIBRARIES :=  libcutils liblog     \   
    libutils \
    libxxxdevice \
    libxxxapi \
    libxxxcfg \
    libxxxspdev \
    libxxxlog\
    libxxxadapter
    
    
    LOCAL_C_INCLUDES +=  xxxdroid/external/xxx/device/include    \   
        xxxdroid/external/xxx/lib/libxxxapiclient  \
        xxxdroid/external/xxx/lib/libspdev \
        xxxdroid/external/xxx/lib/libxxxlog 
    
    LOCAL_C_INCLUDES += $(LOCAL_PATH)
    LOCAL_SHARED_LIBRARIES += libcutils
    include $(BUILD_EXECUTABLE)
    

    转换后的Android.bp文件如下:

    cc_binary {
    
        name: "nativetest",
        srcs: ["apitest.c"],
        cflags: ["-Wno-error=implicit-function-declaration"],
    
        shared_libs: [
            "libcutils",
            "liblog",
            "libutils",
            "libxxxdevice",
            "libxxxapi",
            "libxxxcfg",
            "libxxxspdev",
            "libxxxlog",
            "libxxxadapter",
        ] + ["libcutils"],
        include_dirs: [
            "xxxdroid/external/xxx/device/include",
            "xxxdroid/external/xxx/lib/libxxxapiclient",
            "xxxdroid/external/xxx/lib/libspdev",
            "xxxdroid/external/xxx/lib/libxxxlog",
        ],  
    
        local_include_dirs: ["."],
    
    }
    

    1.3.3 生成动态库

    先让我们看看生成动态库的的Android.mk的定义:

    LOCAL_PATH := $(call my-dir)
    
    src_files := xxxmisc.c
    
    src_files += default_misc.c
    
    # Share Library
    include $(CLEAR_VARS)
    LOCAL_C_INCLUDES += xxxdroid/external/systool/include
    
    LOCAL_SRC_FILES := \
        ${src_files}
    
    LOCAL_MODULE := libxxxmisc
    LOCAL_SHARED_LIBRARIES := liblog libcutils
    LOCAL_MODULE_TAGS := optional
    include $(BUILD_SHARED_LIBRARY)
    
    # Static Library
    include $(CLEAR_VARS)
    LOCAL_C_INCLUDES += xxxdroid/external/systool/include
    
    LOCAL_SRC_FILES := \
        ${src_files}
    
    LOCAL_MODULE := libxxxmisc
    LOCAL_STATIC_LIBRARIES := liblog libcutils
    LOCAL_MODULE_TAGS := optional
    include $(BUILD_STATIC_LIBRARY)
    

    转换后的Android.bp文件如下:

    src_files = ["xxxmisc.c"]
    
    src_files += ["default_misc.c"]
    
    // Share Library
    cc_library_shared {
        include_dirs: ["xxxdroid/external/systool/include"],
    
        srcs: src_files,
    
        name: "libxxxmisc",
        shared_libs: [
            "liblog",
            "libcutils",
        ],  
    
    }
    
    // Static Library
    cc_library_static {
        include_dirs: ["xxxdroid/external/systool/include"],
    
        srcs: src_files,
    
        name: "libxxxmisc",
        static_libs: [
            "liblog",
            "libcutils",
        ],  
    
    }
    

    1.3.4 带宏开关转换失败

    在这个Android.mk里面我们带上了宏编译:
    在这里插入图片描述

    include $(CLEAR_VARS)
    
    LOCAL_MODULE_TAGS := optional
    
    LOCAL_JAVA_LIBRARIES := services
    LOCAL_SRC_FILES := $(call all-java-files-under, src)
    
    ifeq (1,$(strip $(shell expr $(PLATFORM_SDK_VERSION) \>= 28)))
    LOCAL_SRC_FILES += compat/android-v28-later/XXUtilCompat.java
    else
    LOCAL_SRC_FILES += compat/default/XXUtilCompat.java
    endif
    
    LOCAL_SRC_FILES += \
        src/com/xxx/aidl/XxxSystemUtil.aidl \
        src/com/xxx/aidl/PhysicalKey.aidl \
        src/android/bluetooth/IXxxBtPrinter.aidl 
    
        
        
    LOCAL_STATIC_JAVA_LIBRARIES := litepal
    
    
    LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
    #LOCAL_SDK_VERSION := current
    LOCAL_PRIVATE_PLATFORM_APIS := true
    LOCAL_PACKAGE_NAME := XxxManager
    
    LOCAL_CERTIFICATE := platform
    
    

    执行androidmk命令进行转换:

    android_app {
    
        libs: ["services"],
        srcs: ["src/**/*.java"] + ["compat/android-v28-later/SPUtilCompat.java"] + ["compat/default/SPUtilCompat.java"] + [ // ANDROIDMK            TRANSLATION ERROR: unsupported conditional
        // ifeq (1,$(strip $(shell expr $(PLATFORM_SDK_VERSION) \>= 28)))
    
            // ANDROIDMK TRANSLATION ERROR: else from unsupported contitional
            // else
    
            // ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
            // endif
            "src/com/xxx/aidl/XxxSystemUtil.aidl",
    
            //LOCAL_SDK_VERSION := current
            "src/com/xxx/aidl/PhysicalKey.aidl",
            // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_PRIVATE_PLATFORM_APIS
            "src/android/bluetooth/IXxxBtPrinter.aidl",
            // LOCAL_PRIVATE_PLATFORM_APIS := true
        ],  
    
        //the jni callback error!!!!! zhuxy
        static_libs: ["litepal"],
    
        optimize: {
            proguard_flag_files: ["proguard.cfg"],
    
            enabled: false,
        },  
        name: "XxxManager",
    
    

    可以看出androidmk对宏的处理是不对的,这个就需要手动处理了,后续章节会重点说到这个的




    结语

    修行至此,恭喜读者你已经对Android.mk转换成Android.bp有一定了解了,行走江湖是不可能的了,还需多多磨练才行,在后续篇章中让我们一起学习。这里的androidmk不是万能的,有些情况是不行的,譬如有宏或者预编译的情况。


    写在最后

      各位读者看官朋友们,Android.mk转换成Android.bp,希望能吸引你,激发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。

    展开全文
  • Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。 它的基本格式如下:


    https://www.cnblogs.com/reality-soul/p/6893248.html

    一、Android.mk介绍

    Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。

    它的基本格式如下:

    1. LOCAL_PATH := $(call my-dir)  
    2. include $(CLEAR_VARS)  
    3. ................  
    4. LOCAL_xxx       := xxx  
    5. LOCAL_MODULE    := hello-jni  
    6. LOCAL_SRC_FILES := hello-jni.c  
    7. LOCAL_xxx       := xxx  
    8. ................  
    9. 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变量,它们用来指定模块的生成方式。

    三、使用示例

    1. #编译静态库    
    2. LOCAL_PATH := $(call my-dir)    
    3. include $(CLEAR_VARS)    
    4. LOCAL_MODULE = libhellos    
    5. LOCAL_CFLAGS = $(L_CFLAGS)    
    6. LOCAL_SRC_FILES = hellos.c    
    7. LOCAL_C_INCLUDES = $(INCLUDES)    
    8. LOCAL_SHARED_LIBRARIES := libcutils    
    9. LOCAL_COPY_HEADERS_TO := libhellos    
    10. LOCAL_COPY_HEADERS := hellos.h    
    11. include $(BUILD_STATIC_LIBRARY)    
    12.     
    13. #编译动态库    
    14. LOCAL_PATH := $(call my-dir)    
    15. include $(CLEAR_VARS)    
    16. LOCAL_MODULE = libhellod    
    17. LOCAL_CFLAGS = $(L_CFLAGS)    
    18. LOCAL_SRC_FILES = hellod.c    
    19. LOCAL_C_INCLUDES = $(INCLUDES)    
    20. LOCAL_SHARED_LIBRARIES := libcutils    
    21. LOCAL_COPY_HEADERS_TO := libhellod    
    22. LOCAL_COPY_HEADERS := hellod.h    
    23. include $(BUILD_SHARED_LIBRARY)    
    24.     
    25. #使用静态库    
    26. LOCAL_PATH := $(call my-dir)    
    27. include $(CLEAR_VARS)    
    28. LOCAL_MODULE := hellos    
    29. LOCAL_STATIC_LIBRARIES := libhellos    
    30. LOCAL_SHARED_LIBRARIES :=    
    31. LOCAL_LDLIBS += -ldl    
    32. LOCAL_CFLAGS := $(L_CFLAGS)    
    33. LOCAL_SRC_FILES := mains.c    
    34. LOCAL_C_INCLUDES := $(INCLUDES)    
    35. include $(BUILD_EXECUTABLE)    
    36.     
    37. #使用动态库    
    38. LOCAL_PATH := $(call my-dir)    
    39. include $(CLEAR_VARS)    
    40. LOCAL_MODULE := hellod    
    41. LOCAL_MODULE_TAGS := debug    
    42. LOCAL_SHARED_LIBRARIES := libc libcutils libhellod    
    43. LOCAL_LDLIBS += -ldl    
    44. LOCAL_CFLAGS := $(L_CFLAGS)    
    45. LOCAL_SRC_FILES := maind.c    
    46. LOCAL_C_INCLUDES := $(INCLUDES)    
    47. include $(BUILD_EXECUTABLE)    
    48.   
    49.   
    50. #拷贝文件到指定目录  
    51. LOCAL_PATH := $(call my-dir)  
    52. include $(CLEAR_VARS)  
    53. LOCAL_MODULE := bt_vendor.conf  
    54. LOCAL_MODULE_CLASS := ETC  
    55. LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth  
    56. LOCAL_MODULE_TAGS := eng  
    57. LOCAL_SRC_FILES := $(LOCAL_MODULE)  
    58. include $(BUILD_PREBUILT)  
    59.   
    60.   
    61. #拷贝动态库到指定目录  
    62. LOCAL_PATH := $(call my-dir)  
    63. include $(CLEAR_VARS)  
    64. #the data or lib you want to copy  
    65. LOCAL_MODULE := libxxx.so  
    66. LOCAL_MODULE_CLASS := SHARED_LIBRARIES  
    67. LOCAL_MODULE_PATH := $(ANDROID_OUT_SHARED_LIBRARIES)  
    68. LOCAL_SRC_FILES := lib/$(LOCAL_MODULE )  
    69. OVERRIDE_BUILD_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)  
    70. include $(BUILD_PREBUILT)  


    参考文章:

    http://www.cnblogs.com/wainiwann/p/3837936.html

    http://blog.csdn.net/ly131420/article/details/9619269

    http://blog.csdn.net/mawl2002/article/details/6118522







    (一)概要


    在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 plaincopy
    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 plaincopy
    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 plaincopy
    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 plaincopy
    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 plaincopy
    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 plaincopy
    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 plaincopy
    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文件的语法和规则有个了解。

    请参考(学习中。。。)


    展开全文
  • 1. Android.mk 是什么? Android.mk 文件用来告知 NDK Build 系统关于Source的信息。Android.mk是GNU Makefile 的一部分,并且将Build System解析一次或者多次。但是尽量少的在Android.mk中声明变量,也不要假定任何...
    1. Android.mk 是什么?
          Android.mk 文件用来告知 NDK Build 系统关于Source的信息。Android.mk是GNU Makefile 的一部分,并且将Build System解析一次或者多次。但是尽量少的在Android.mk中声明变量,也不要假定任何东西不会在解析过程中定义。            
          Android.mk文件语法允许我们将Source打包成一个‘modules’,‘modules’可以是:动态库,静态库。只有动态库可以被 install/copy到应用程序包(APK),静态库则可以被链接入动态库。可以在一个Android.mk中定义一个或多个modules;也可以将同一份source 加进多个modules。
         Build System帮我们处理了很多细节而不需要我们再关心。例如:你不需要在Android.mk中列出头文件和外部依赖文件。NDK Build System自动帮我们提供这些信息。这也意味着,当用户升级NDK后,你将可以受益于新的toolchain/platform而不必再去修改Android.mk.

    2. Android.mk 的语法

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. # Module name should match apk name to be installed
    4. LOCAL_MODULE := XXXXXX
    5. LOCAL_MODULE_TAGS := optional
    6. LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
    7. LOCAL_MODULE_CLASS := APPS
    8. LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
    9. LOCAL_PRIVILEGED_MODULE := true
    10. LOCAL_CERTIFICATE := PRESIGNED
    11. LOCAL_PREBUILT_JNI_LIBS := \
    12.     @lib/armeabi/libbutterfly.so \
    13.     @lib/armeabi/libluajava.so \
    14.     @lib/armeabi/libNinepatch.so \
    15.     @lib/armeabi/libSogouAgc_v1.so \
    16.     @lib/armeabi/libsogouupdcore.so \
    17.     @lib/armeabi/libweibosdkcore.so
    18. LOCAL_MULTILIB := 32
    19. include $(BUILD_PREBUILT)


    语法讲解:

    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 := XXXXXX
    LOCAL_MODULE 必须定义,以表示Android.mk中的每一个模块,名字必须唯一,不能包含空格。

    LOCAL_MODULE_TAGS := optional
    LOCAL_MODULE_TAGS  是指定在什么版下才会编译这个Android.mk
    user: 指该模块只在user版本下才编译
    eng: 指该模块只在eng版本下才编译
    tests: 指该模块只在tests版本下才编译
    optional:指该模块在所有版本下都编译

    LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
    LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码,这里将模块打包为apk包

    LOCAL_MODULE_CLASS := APPS
    LOCAL_MODULE_CLASS 标识了所编译模块最后放置的位置,如果不指定,不会放到系统中,之后放在最后的obj目录下的对应目录中。

    LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
    指定当前模块的后缀。一旦指定,系统在产生目标文件时,会以模块名加后缀来创建目标文件

    LOCAL_PRIVILEGED_MODULE := true
    LOCAL_PRIVILEGED_MODULE 是Android ROM编译时的一个变量,其与编译、安装、权限管理等几个方面都有关系。对于Android系统应用,LOCAL_PRIVILEGED_MODULE 决定了其编译后的在ROM中的安装位置: 如果不设置或者设为false,安装位置为system/app; 如果设置为true,安装位置为system/priv-app。

    LOCAL_CERTIFICATE := PRESIGNED
    LOCAL_CERTIFICATE指apk的签名,可以有:
    media    使用media签名文件签名
    platform 使用平台签名文件签名
    shared   使用shared签名文件签名
    PRESIGNED 如果文件已经签过名,不需要重新签名,则使用PRESIGNED。

    LOCAL_PREBUILT_JNI_LIBS := \ XXXX  、LOCAL_MULTILIB :=32  
    因为Android5.1 是64位编译环境,因此需要将32位的so库提取出来,使用的32位的lib库,提取出来的lib库,放在/system/priv-app/app文件名/下

    include $(BUILD_PREBUILT)
    BUILD_PREBUILT               :该模块已经预先编译
    它负责收集自从上次调用 include $(CLEAR_VARS)  后的所有LOCAL_XXX信息。并决定编译为什么。
    BUILD_STATIC_LIBRARY     :编译为静态库。 
    BUILD_SHARED_LIBRARY    :编译为动态库 
    BUILD_EXECUTABLE           :编译为Native C可执行程序  
    BUILD_SHARED_LIBRARY    :是Build System提供的一个变量,指向一个GNU Makefile Script。
    NDK还定义了很多其他的BUILD_XXX_XXX变量,它们用来指定模块的生成方式。
    展开全文
  • android.mk转换为android.bp

    万次阅读 2018-05-09 20:00:29
    android.mk大家都很熟悉了,就是android下编译模块的配置文件,可以理解为android makefile。从android N之后,我们发现好多模块下面没有了android.mk文件,多了一个android.bp文件。这个是google在android N之后新...
  • 1.Android.mk文件 1.简介: Android.mk文件用来告知NDK Build 系统关于Source的信息。 Android.mk将是GNU Makefile的一部分,且将被Build System解析一次或多次。所以,请尽量少的在Android.mk中声明变量,也不要...
  • Android.bp与Android.mk

    千次阅读 2018-11-16 18:13:56
    从AndroidO开始,Android开始使用Android.bp来管理代码的编译,Android通过soong和blueprint将Android.bp转换为ninja文件(保存在out/soong/build.ninja),通过ckati将Android.mk转换为ninja文件(保存在out/buil-$...
  • Android.mk include $(BUILD_SHARED_LIBRARY) Android.bp cc_library_shared { … } 编译成 Native 静态库 Android.mk include $(BUILD_STATIC_LIBRARY) Android.bp cc_library_static { … } 编译成 Native 执行...
  • 1、Android.mk文件概述 Android.mk文件用来告诉NDK编译系统,应该如何编译这些源码。更确切地说,该文件其实就是一个小型的Makefile。该文件会被NDK的编译工具解析多次,所以要注意不要过多使用环境变量,以免第...
  • android.mk转换为android.bp android.mk大家都很熟悉了,就是android下编译模块的配置文件,可以理解为android makefile。从android N之后,我们发现好多模块下面没有了android.mk文件,多了一个android.bp文件。这...
  • Android.mk和Application.mk配置参数详解

    千次阅读 2017-12-06 23:38:27
    每次看Android.mk或者Application.mk文件的时候,都会被其中的变量搞得头晕,本文专门针对这种情况尽量全面地介绍一下Android.mk和Application.mk中各种变量的含义。 Android.mk介绍TARGET_ARCH:CUP架构,比如,...
  • 首先,介绍一下在Android.mk文件中常用的模块描述变量 1. LOCAL_PATH: 当前文件的路径,必须在 Android.mk 的开头定义,不会被include $(CLEAR_VARS)清除。一般这样定义:LOCAL_PATH := $(call my-di
  • 源码链接 添加个cpp文件后要Refresh Linked C++ Projects 用gradle-ndk-build: import org.apache.tools.ant.taskdefs.condition...android { compileSdkVersion versionCompiler buildToolsVer...
  • Android.mk中依赖子目录中的Android.mk include $(call all-subdir-makefiles)
  • Android NDK编程之Android.mk和Application.mk

    千次阅读 2014-11-12 23:22:30
    Android编程使用NDK必须创建一个jni文件夹,并且jni文件里一般包含有C/C++的源码文件、Android..mk文件、Application.mk文件(可选),Android.mk文件的编写是重点。
  • Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := vc LOCAL_SRC_FILES := VideoChat.cpp \ VideoChat_jni.cpp \ ...
  • Android.mk 转换为 Android.bp简介

    千次阅读 2019-04-10 10:15:08
    There is a tool called androidmk to generate Android.bp file out of Android.mk file androidmk工具在编译后生成所在目录out/soong/host/linux-x86/bin/androidmk 工具使用方法: 1. cdout/soong/host/linux-...
  • Android.mk转Android.bp

    2020-04-24 11:34:02
    1. 保证androidmk文件存在,正常来说编译完成整个Android系统这个文件就会生成好,位置在: out/soong/host/linux-x86/bin/androidmk 2. 使用该工具进行转换 ...androidmk Android.mk > A...
  • Android.mk 用于将 C 和 C++ 源文件粘合至 Android NDK 。 Application.mk 用于描述应用需要的原生模块。 模块可以是静态库、共享库或可执行文件。 Android.mk # 此变量表示源文件在开发树中的位置 # 在...
  • mtk android.mk --> android.bp

    千次阅读 2018-01-09 16:14:01
    mtk android.mk --> android.bp 例如\frameworks\base\media\jni 由7.0的android.mk转换成android.bp . 首先从Soong说起,Soong是Android中对基于GNU make的编译系统的替代物,编译文件“Android.mk”被替换为...
  • 从一个android.mk实例看android.mk基础

    千次阅读 2012-01-11 11:28:56
    用自己修改过的 framework/base/media/libstagefright/Android.mk做例子,讲得不对的大家扔鸡蛋吧: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS)  其中第一行,是LOCAL_PATH的定义。一个Android.mk ...
  • https://developer.android.com/ndk/guides/android_mk.html Android.mk On this page OverviewBasicsVariables and MacrosModule-Description Variables This page describes the
  • Android.mk添加第三方jar或so库到apk-->Android.mk用法 2011-09-12 10:48 Android.mk文档规范 Android.mk 编译文件是用来向 Android NDK描述你的 C,C++源代码文件的, 这篇文档描 述了它的语法。在...
  • 路径:./frameworks/base/core/res/Android.mk # 特点: # 1.支持应用程序编译的资源能够被其它应用使用 # 2.该APK具有系统权限 # 3.能够指定一个全局的依赖于LOCAL_BUILT_MODULE

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,520
精华内容 4,608
关键字:

android.mk