Android Android.mk

例子:

{

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
$(warning $(LOCAL_PATH))

LOCAL_MODULE := libyuv

#工作包含目录
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/
$(warning 工作目录 $(LOCAL_PATH) 包含目录 $(LOCAL_C_INCLUDES))

FILE_LIST := $(wildcard $(LOCAL_PATH)/source/*.cc)
$(warning FILE_LIST =============>  $(FILE_LIST))

#进行赋值(两种方法都可以)
#LOCAL_SRC_FILES := $(FILE_LIST)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_LDLIBS+= -L$(SYSROOT)/usr/lib -llog

#链接其他库
#LOCAL_SHARED_LIBRARIES := \
#libcutils \
#libutils \

#编译生成动态库
include $(BUILD_SHARED_LIBRARY)

#编译生成静态库
#include $(BUILD_STATIC_LIBRARY)

}

{

1、Android.mk文件概述

Android.mk文件用来告诉NDK编译系统,应该如何编译这些源码。更确切地说,该文件其实就是一个小型的Makefile。该文件会被NDK的编译工具解析多次,所以要注意不要过多使用环境变量,以免第一次解析时产生的变量影响后面的解析。Android.mk把源码组织成不同的模块,每个模块可以是一个静态库也可以是一个动态库。动态库才会被拷贝到安装包中,静态库只能用于编译生成动态库。

同一个Android.mk文件可以定义多个模块,不同的模块可以共用同一个源文件。

注意,NDK所使用的Android.mk文件的语法与Android操作系统的开放源码中的Android.mk的语法非常接近,但是两个编译系统对Android.mk的使用方法不同,这是为了方便应用程序开发人员复用以前的代码。
2、一个简单的例子

在详细讨论Android.mk文件的语法之前,先看一个简单的 “hello JNI“ 的例子,文件位于 apps/hello-jni/project。其中的 src 子目录存放Android工程的java源码,jni子目录存放C/C++源码文件,即 jni/hello-jni.c (实现了一个返回字符串给虚拟机的函数)。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。

在NDK安装目录的samples目录下有更加丰富的例子,里面都有详细的注释。
3、变量名的限制

下面这些变量是你可以直接使用或者应该由你来定义的。你也可以定义自己的变量,但是不能用以下NDK所保留的变量名:

以 LOCAL_ 开头的名字(例如,LOCAL_MODULE)

以 PRIVATE_, NDK_,APP_ 开头的名字(供NDK内部使用)

小写字母的变量名也不能使用(供NDK内部使用,例如 my-dir)

例如,你可以随便用 MY_ 开头的变量名:

MY_SOURCES := foo.c
    ifneq ($(MY_CONFIG_BAR),)
      MY_SOURCES += bar.c
    endif

LOCAL_SRC_FILES += $(MY_SOURCES)

4、NDK预定义变量

下面这些变量是ndk提前定义好的变量。有时ndk会解析同一个Android.mk文件多次,每次解析时,这些变量的值可能不相同。
CLEAR_VARS

指向一个特殊的Makefile,负责清理 LOCAL_XXX 变量(LOCAL_PATH除外)。一般在定义新模块之前使用这个变量,用法:

include $(CLEAR_VARS)
BUILD_SHARED_LIBRARY

该变量实际指向了一个Makefile,用来把所有名为 LOCAL_XXX的变量中的信息收集起来,然后确定如何把你提供的源码编译成目标模块。用法:include $(BUILD_SHARED_LIBRARY)     默认文件名:lib<LOCAL_MODULE>.so
BUILD_STATIC_LIBRARY

类似于BUILD_SHARED_LIBRARY,不过它用来编译静态库。静态库不会被拷贝到你的安装包中去,它往往用来编译其他动态库。用法:include $(BUILD_STATIC_LIBRARY)    默认文件名:lib<LOCAL_MODULE>.a
PREBUILT_SHARED_LIBRARY

该变量指向一个已编译好的共享库。与BUILD_SHARED_LIBRARY和BUILD_STATIC_LIBRARY不同,此时相应的LOCAL_SRC_FILES不再指定源文件,而是指向这个预编译共享库文件(例如 foo/libfoo.so)。可以在其他模块中,通过使用LOCAL_PREBUILTS变量来引用这个预编译模块。参考Prebuilt。
PREBUILT_STATIC_LIBRARY

与PREBUILT_SHARED_LIBRARY相同,只不过这里是静态库。 参考 Prebuilt。
TARGET_ARCH

目标CPU架构的名字,与Android操作系统的CPU架构名一致。如果想兼容所有ARM的CPU,可以用 “arm” 这个名字。
TARGET_PLATFORM

目标Android平台的名字。例如 android-3 对应的是 Android 1.5 系统镜像(Cupcake)。所有系统镜像的名字和相应的系统镜像可参考Stable APIs。
TARGET_ARCH_ABI

目标CPU和ABI组合的名字,目前只有2个值可以用:

armeabi     对于ARMv5TE

armeabi-v7a

注意,一直到Android NDK 1.6_r1,这里的值都是用“arm”。然而,该值已被重新定义以更好地匹配Android平台内部所使用的。

关于架构和ABI及兼容性问题,参考文档 Cpu Arch ABIs。

其他的目标ABI会在将来的NDK版本中增加,并且是不同的名字。注意,所有兼容ARM的ABI的TARGET_ARCH都是arm,但是TARGET_ARCH_ABI不同。
TARGET_ABI

目标平台和ABI的组合,定义为 $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)。当你想在真机上测试一种系统镜像时有用。该变量的默认值是android-3-armeabi。

直到Android NDK 1.6_r1,这个值一直是 android-3-arm。
5、NDK预定义的宏函数

下面是NDK预定义的“函数”宏,用法是  $(call <function>) ,返回的是文本信息
my-dir

返回上一个被包含的Makefile的路径,典型情况是Android.mk文件所在的路径。这个函数对于定义LOCAL_PATH特别有用,例如:

LOCAL_PATH := $(call my-dir)

注意:由于make的工作原理,该函数返回的确实是上一个被包含的Makefile的路径(也就是说返回的结果可能不是Android.mk所在目录)。所以,包含了另外一个文件之后,就不要再使用 my-dir 了。

例如,下面的例子:

LOCAL_PATH := $(call my-dir)
    该模块其他声明
    
    include $(LOCAL_PATH)/foo/Android.mk
    LOCAL_PATH := $(call my-dir)
    另一个模块的声明

上面的问题就是第二次调用my-dir的时候,得到的是 $PATH/foo 而不是 $PATH,因为它前面有一个include语句。

因此,最好在所有include语句之前,把LOCAL_PATH定义好:

LOCAL_PATH := $(call my-dir)
        ... declare one module
        LOCAL_PATH := $(call my-dir)
        ... declare another module
        # extra includes at the end of the Android.mk
        include $(LOCAL_PATH)/foo/Android.mk

如果觉得这样做不方便,可以把第一次调用的结果保存到变量中,例如:

MY_LOCAL_PATH := $(call my-dir)
        LOCAL_PATH := $(MY_LOCAL_PATH)
        ... declare one module
        include $(LOCAL_PATH)/foo/Android.mk
        LOCAL_PATH := $(MY_LOCAL_PATH)
        ... declare another module

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。

this-makefile

返回当前的Makefile的路径(即该函数调用时的位置)
parent-makefile

如果当前这个Makefile被另一个Makefile包含,则返回那个包含了自己的Makefile的路径(即parent)
grand-parent-makefile

(你猜猜......)
import-module

该函数用于按模块名查找另一个模块的Android.mk文件,并包含进来。用法如下:

$(call import-module,<name>)

上面将在 NDK_MODULE_PATH变量所指定的目录列表中寻找名为<name>的模块,找到之后将包含进来。

可以参考 Import Module。
6、模块描述变量

下面这些变量用于对模块进行描述,这些变量应该在 include $(CLEAR_VARS) 和 include $(BUILD_XXXX) 之间定义好。
LOCAL_PATH (必须)

这个变量表示当前文件(一般是Android.mk)所在的路径,该变量很重要,必须定义(在Android.mk文件的开头处定义)。常见写法如下:

LOCAL_PATH := $(call my-dir)

该变量不会被 include $(CLEAR_VARS) 清空,所以不论Android.mk定义了几个模块,一个Android.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_MODULE_FILENAME不支持文件路径(所以不能有斜杠),不要写扩展名(文件路径和文件扩展名是由编译工具自动加上的)

LOCAL_SRC_FILES (必须)

该变量用来指定该模块对应的源文件,只把需要传给编译器的源文件名加进LOCAL_SRC_FILES,编译系统会自动处理头文件依赖。这里的文件名都是以 LOCAL_PATH 作为当前目录的(即相对于LOCAL_PATH目录),例如:

LOCAL_SRC_FILES := foo.c toto/bar.c
注意:必须使用Unix风格的斜杠,Windows风格的斜杠不能正确处理。
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)

bar模块依赖foo模块,声明如下:

include $(CLEAR_VARS)
        LOCAL_MODULE := bar
        LOCAL_SRC_FILES := bar.c
        LOCAL_CFLAGS := -DBAR=2
        LOCAL_STATIC_LIBRARIES := foo
        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 可以用于导出该依赖:

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)

此处在编译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文件。

换句话说,如果你定义:

LOCAL_SRC_FILES  := foo.c bar.S
      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命令,输入文件作为它的第一个命令行参数,输出文件作为第二个命令行参数,例如:

myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
    myasmfilter bar.S $OBJS_DIR/bar.S

}

{

  • LOCAL_MODULE 本地模块
  • LOCAL_SRC_FILES 本地源文件
  • PREBUILT_SHARED_LIBRARY 指已经编译好的动态库
  • (LOCAL_PATH)") 可以打印出LOCAL_PATH这个变量
  • LOCAL_C_INCLUDES 本地源码路径
  • LOCAL_LDLIBS 指定库或至少要链接到结果中的对象
  • LOCAL_SHARED_LIBRARIES 编译好的动态库,为此模块中的依赖
  • BUILD_STATIC_LIBRARY:编译为静态库。
    BUILD_SHARED_LIBRARY :编译为动态库
    BUILD_EXECUTABLE:编译为Native C可执行程序

}

{

(1)Android.mk文件首先需要指定LOCAL_PATH变 量,用于查找源文件。由于一般情况下
Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:
LOCAL_PATH:=$(call
my-dir)
上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。

(2)Android.mk中可以定义多个编译模块,每个编译模块都
是以include $(CLEAR_VARS)开始

以include
$(BUILD_XXX)结束

include $(CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定
让GNU MAKEFILE为你清除除LOCAL_PATH以外的所有LOCAL_XXX变量,

LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES
等。
include $(BUILD_STATIC_LIBRARY)表示编译成静态库
include
$(BUILD_SHARED_LIBRARY)表示编译成动态库。
include
$(BUILD_EXECUTABLE)表示编译成可执行程序

(3)举例如下(frameworks/base/libs
/audioflinger/Android.mk):

LOCAL_PATH:= $(call my-dir)
include
$(CLEAR_VARS)  模块一
ifeq ($(AUDIO_POLICY_TEST),true)
 
ENABLE_AUDIO_DUMP := true
endif
LOCAL_SRC_FILES:= \
   
AudioHardwareGeneric.cpp \
    AudioHardwareStub.cpp \
   
AudioHardwareInterface.cpp
ifeq ($(ENABLE_AUDIO_DUMP),true)
 
LOCAL_SRC_FILES += AudioDumpInterface.cpp
  LOCAL_CFLAGS +=
-DENABLE_AUDIO_DUMP
endif
LOCAL_SHARED_LIBRARIES := \
   
libcutils \
    libutils \
    libbinder \
    libmedia \
   
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
 
LOCAL_CFLAGS += -DGENERIC_AUDIO
endif
LOCAL_MODULE:=
libaudiointerface
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
 
LOCAL_SRC_FILES += A2dpAudioInterface.cpp
  LOCAL_SHARED_LIBRARIES +=
liba2dp
  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
 
LOCAL_C_INCLUDES += $(call include-path-for, bluez)
endif
include
$(BUILD_STATIC_LIBRARY)  模块一编译成静态库
include $(CLEAR_VARS)  模块二
LOCAL_SRC_FILES:=              
\
    AudioPolicyManagerBase.cpp
LOCAL_SHARED_LIBRARIES := \
   
libcutils \
    libutils \
    libmedia
ifeq
($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS += -ldl
else
 LOCAL_SHARED_LIBRARIES
+= libdl
endif
LOCAL_MODULE:= libaudiopolicybase
ifeq
($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_A2DP
endif
ifeq
($(AUDIO_POLICY_TEST),true)
  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
include
$(BUILD_STATIC_LIBRARY) 模块二编译成静态库
include $(CLEAR_VARS) 模块三
LOCAL_SRC_FILES:=              
\
    AudioFlinger.cpp            \
   
AudioMixer.cpp.arm          \
    AudioResampler.cpp.arm      \
   
AudioResamplerSinc.cpp.arm  \
    AudioResamplerCubic.cpp.arm \
   
AudioPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
    libcutils \
   
libutils \
    libbinder \
    libmedia \
   
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
 
LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
 
LOCAL_CFLAGS += -DGENERIC_AUDIO
else
  LOCAL_SHARED_LIBRARIES +=
libaudio libaudiopolicy
endif
ifeq ($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS
+= -ldl
else
 LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:=
libaudioflinger
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
 
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
  LOCAL_SHARED_LIBRARIES
+= liba2dp
endif
ifeq ($(AUDIO_POLICY_TEST),true)
 
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
ifeq
($(TARGET_SIMULATOR),true)
    ifeq ($(HOST_OS),linux)
       
LOCAL_LDLIBS += -lrt -lpthread
    endif
endif
ifeq
($(BOARD_USE_LVMX),true)
    LOCAL_CFLAGS += -DLVMX
   
LOCAL_C_INCLUDES += vendor/nxp
    LOCAL_STATIC_LIBRARIES +=
liblifevibes
    LOCAL_SHARED_LIBRARIES += liblvmxservice
#   
LOCAL_SHARED_LIBRARIES += liblvmxipc
endif
include
$(BUILD_SHARED_LIBRARY) 模块三编译成动态库

(4)编译一个应用程序(APK)

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  
  #
Build all java files in the java subdirectory-->直译(建立
在java
子目录中的所有
Java文件

LOCAL_SRC_FILES := $(call all-subdir-java-files)
  
  # Name of
the APK to build-->直译(创建APK的名称

LOCAL_PACKAGE_NAME := LocalPackage
  
  # Tell it to build an
APK-->直译(告诉
它来建立
一个
APK

include
$(BUILD_PACKAGE)

(5)编译一个依赖于静态Java库(static.jar)的应用
程序

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)

# List of static libraries to include in the package
 
LOCAL_STATIC_JAVA_LIBRARIES := static-library
  
  # Build all
java files in the java subdirectory
  LOCAL_SRC_FILES := $(call
all-subdir-java-files)
  
  # Name of the APK to build
 
LOCAL_PACKAGE_NAME := LocalPackage
  
  # Tell it to build an APK
 
include $(BUILD_PACKAGE)

(6)编译一个需要用平台的key签名的应用程序

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  
  #
Build all java files in the java subdirectory
  LOCAL_SRC_FILES :=
$(call all-subdir-java-files)
  
  # Name of the APK to build
 
LOCAL_PACKAGE_NAME := LocalPackage
  
  LOCAL_CERTIFICATE :=
platform
  
  # Tell it to build an APK
  include
$(BUILD_PACKAGE)

(7)编译一个需要用特定key前面的应用程序

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  
  #
Build all java files in the java subdirectory
  LOCAL_SRC_FILES :=
$(call all-subdir-java-files)
  
  # Name of the APK to build
 
LOCAL_PACKAGE_NAME := LocalPackage
  
  LOCAL_CERTIFICATE :=
vendor/example/certs/app
  
  # Tell it to build an APK
 
include $(BUILD_PACKAGE)

(8)添加一个预编译应用程序

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  
  #
Module name should match apk name to be installed.
  LOCAL_MODULE :=
LocalModuleName
  LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
 
LOCAL_MODULE_CLASS := APPS
  LOCAL_MODULE_SUFFIX :=
$(COMMON_ANDROID_PACKAGE_SUFFIX)
  
  include $(BUILD_PREBUILT)

(9)添加一个静态JAVA库

LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  
  #
Build all java files in the java subdirectory
  LOCAL_SRC_FILES :=
$(call all-subdir-java-files)
  
  # Any libraries that this
library depends on
  LOCAL_JAVA_LIBRARIES := android.test.runner

# The name of the jar file to create
  LOCAL_MODULE := sample

# Build a static jar file.
  include
$(BUILD_STATIC_JAVA_LIBRARY)

(10)Android.mk的编译模块中间可以定义相关的编译内
容,也就是指定相关的变量如下:

LOCAL_AAPT_FLAGS

LOCAL_ACP_UNAVAILABLE

LOCAL_ADDITIONAL_JAVA_DIR
 
LOCAL_AIDL_INCLUDES

LOCAL_ALLOW_UNDEFINED_SYMBOLS

LOCAL_ARM_MODE

LOCAL_ASFLAGS

LOCAL_ASSET_DIR

LOCAL_ASSET_FILES 在Android.mk文件中编译应用程序(BUILD_PACKAGE)时设置此变量,表示资源文件,
                 
通常会定义成LOCAL_ASSET_FILES += $(call find-subdir-assets)
 
LOCAL_BUILT_MODULE_STEM

LOCAL_C_INCLUDES 额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录
                
举例如下:
                 LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
                
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
 
LOCAL_CC 指定C编译器

LOCAL_CERTIFICATE  签名认证

LOCAL_CFLAGS 为C/C++编译器定义额外的标志(如宏定义),举例:LOCAL_CFLAGS +=
-DLIBUTILS_NATIVE=1
 
LOCAL_CLASSPATH

LOCAL_COMPRESS_MODULE_SYMBOLS

LOCAL_COPY_HEADERS install应用程序时需要复制的头文件,必须同时定义LOCAL_COPY_HEADERS_TO
 
LOCAL_COPY_HEADERS_TO
install应用程序时复制头文件的目的路径

LOCAL_CPP_EXTENSION
如果你的C++文件不是以cpp为文件后缀,你可以通过LOCAL_CPP_EXTENSION指定C++文件后缀名
                   
如:LOCAL_CPP_EXTENSION := .cc
                   
注意统一模块中C++文件后缀必须保持一致。

LOCAL_CPPFLAGS 传递额外的标志给C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection

LOCAL_CXX 指定C++编译器
 
LOCAL_DX_FLAGS

LOCAL_EXPORT_PACKAGE_RESOURCES

LOCAL_FORCE_STATIC_EXECUTABLE
如果编译的可执行程序要进行静态链接(执行时不依赖于任何动态库),则设置LOCAL_FORCE_STATIC_EXECUTABLE:=true
                             
目前只有libc有静态库形式,这个只有文件系统中/sbin目录下的应用程序会用到,这个目录下的应用程序在运行时通常
                             
文件系统的其它部分还没有加载,所以必须进行静态链接。
 
LOCAL_GENERATED_SOURCES
 
LOCAL_INSTRUMENTATION_FOR

LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME

LOCAL_INTERMEDIATE_SOURCES

LOCAL_INTERMEDIATE_TARGETS

LOCAL_IS_HOST_MODULE

LOCAL_JAR_MANIFEST

LOCAL_JARJAR_RULES

LOCAL_JAVA_LIBRARIES 编译java应用程序和库的时候指定包含的java类库,目前有core和framework两种
                    
多数情况下定义成:LOCAL_JAVA_LIBRARIES := core framework
                    
注意LOCAL_JAVA_LIBRARIES不是必须的,而且编译APK时不允许定义(系统会自动添加)
 
LOCAL_JAVA_RESOURCE_DIRS

LOCAL_JAVA_RESOURCE_FILES

LOCAL_JNI_SHARED_LIBRARIES

LOCAL_LDFLAGS 传递额外的参数给连接器(务必注意参数的顺序)
 
LOCAL_LDLIBS
为可执行程序或者库的编译指定额外的库,指定库以"-lxxx"格式,举例:
             LOCAL_LDLIBS +=
-lcurses -lpthread
             LOCAL_LDLIBS += -Wl,-z,origin
 
LOCAL_MODULE
生成的模块的名称(注意应用程序名称用LOCAL_PACKAGE_NAME而不是LOCAL_MODULE)

LOCAL_MODULE_PATH 生成模块的路径
 
LOCAL_MODULE_STEM
 
LOCAL_MODULE_TAGS
生成模块的标记
 
LOCAL_NO_DEFAULT_COMPILER_FLAGS

LOCAL_NO_EMMA_COMPILE

LOCAL_NO_EMMA_INSTRUMENT

LOCAL_NO_STANDARD_LIBRARIES

LOCAL_OVERRIDES_PACKAGES

LOCAL_PACKAGE_NAME APK应用程序的名称

LOCAL_POST_PROCESS_COMMAND
 
LOCAL_PREBUILT_EXECUTABLES
预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用,指定需要复制的可执行文件

LOCAL_PREBUILT_JAVA_LIBRARIES

LOCAL_PREBUILT_LIBS 预编译including
$(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用, 指定需要复制的库.

LOCAL_PREBUILT_OBJ_FILES

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES 
 
LOCAL_PRELINK_MODULE
是否需要预连接处理(默认需要,用来做动态库优化)

LOCAL_REQUIRED_MODULES 指定模块运行所依赖的模块(模块安装时将会同步安装它所依赖的模块)
 
LOCAL_RESOURCE_DIR

LOCAL_SDK_VERSION

LOCAL_SHARED_LIBRARIES 可链接动态库
 
LOCAL_SRC_FILES 编译源文件

LOCAL_STATIC_JAVA_LIBRARIES

LOCAL_STATIC_LIBRARIES 可链接静态库
 
LOCAL_UNINSTALLABLE_MODULE

LOCAL_UNSTRIPPED_PATH
 
LOCAL_WHOLE_STATIC_LIBRARIES
指定模块所需要载入的完整静态库(这些精通库在链接是不允许链接器删除其中无用的代码)
 
LOCAL_YACCFLAGS
 
OVERRIDE_BUILT_MODULE_PATH

-----------------------------------------------------------------------------------------------------------------

一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU
Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk
file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。例如,你不需要在你的Android.mk中
列出头文件和依赖文件。NDK编译系统将会为你自动处理这些问题。这也意味着,在升级NDK后,你应该得到新的toolchain/platform支
持,而且不需要改变你的Android.mk文件。
      先看一个简单的例子:一个简单的"hello world",比如下面的文件:
sources/helloworld/helloworld.c

sources/helloworld/Android.mk
相应的Android.mk文件会象下面这样:
----------
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_PATH := $(call
my-dir)
一个Android.mk
file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’,
由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
include $( CLEAR_VARS)
CLEAR_VARS
由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE,
LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),除LOCAL_PATH
。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。
LOCAL_MODULE :=
helloworld
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包
含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为‘foo‘的共享库模块,将会生成‘libfoo.so‘文件。
LOCAL_SRC_FILES
:= helloworld.c
LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这
里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

在Android中增加本地程序或者库,这些程序和库与其所载路径没有任何关系,只和它们的Android.mk文件有关系。Android.mk和普通
的Makefile有所不同,它具有统一的写法,主要包含一些系统公共的宏。
    
在一个Android.mk中可以生成多个可执行程序、动态库和静态库。
1,编译应用程序的模板:
     #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)
(菜鸟级别解
释::=是赋值的意思,$是引用某变量的值)LOCAL_SRC_FILES中加入源文件路径,LOCAL_C_INCLUDES
中加入所需要包含的头文件路径,LOCAL_STATIC_LIBRARIES加入所需要链接的静态库(*.a)的名
称,LOCAL_SHARED_LIBRARIES中加入所需要链接的动态库(*.so)的名称,LOCAL_MODULE表示模块最终的名
称,BUILD_EXECUTABLE表示以一个可执行程序的方式进行编译。
2,编译静态库的模板:
     #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表示编译一个静态
库。
3,编译动态库的模板:
     #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表示编译一个静态
库。
      以上三者的生成结果分别在如下,generic依具体target会变:
out/target/product/generic/obj/EXECUTABLE
out/target/product/generic/obj/STATIC_LIBRARY
out/target/product/generic/obj/SHARED_LIBRARY
     
每个模块的目标文件夹分别为:
可执行程序:XXX_intermediates
静态库:     
XXX_static_intermediates
动态库:      XXX_shared_intermediates
     
另外,在Android.mk文件中,还可以指定最后的目标安装路径,用LOCAL_MODULE_PATH和
LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的宏进行选择:
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:
表示system文件系统。
TARGET_OUT_DATA:表示data文件系统。
用法如:
 CAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

}

原文地址:https://www.cnblogs.com/YZFHKMS-X/p/12264526.html

时间: 2024-11-09 09:40:30

Android Android.mk的相关文章

从零开始学android&lt;android事件的处理方式.二十四.&gt;

在android中一共有 多种事件,每种事件都有自己相对应的处理机制 如以下几种 1 单击事件 View.OnClickListener public abstract void onClick (View v) 单击组件时触发 2 单击事件 View.OnLongClickListener public abstract boolean onLongClick (View v) 长按组件时触发 3 键盘事件 View.OnKeyListener public abstract boolean

[android] android下junit测试框架配置

我们的业务代码一般是放在一个新的包下面,这个业务类不能够通过右键run as java application,因为android项目只能运行在手机上的dalvak虚拟机里面 新建一个包,里面写测试类,测试类需要继承AndroidTestCase类,写测试方法,需要throws exception抛出异常给测试框架,测试方法里面一般new出需测试的类,调用它的方法,然后断言结果,assertEquals(预估, 实际结果) 在outline视窗 (window=>show view=>outl

图解Android - Android GUI 系统

图解Android - Android GUI 系统 (1) - 概论 图解Android - Android GUI 系统 (2) - 窗口管理系统 图解Android - Android GUI 系统 (3) - Surface Flinger (TBD) 图解Android - Android GUI 系统 (4) - Activity的生命周期 图解Android - Android GUI 系统 (5) - Android的用户输入处理

Android Android:persistentDrawingCache

前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net 雨季o莫忧离:http://blog.csdn.net/luckkof 正文 ViewGroup---属性  android:persistentDrawingCache (Google官方译文) Defines the persistence of the drawing cache. The drawing cache might be enabled by

[Android]Android代码调试工具: Traceview和Dmtracedump

?Android 程序调试工具 Google为我们提供的代码调试工具的亮点:traceview 和 dmtracedump .有了这两个工具,我们调试程序分析bug就非常得心应手了.traceview帮助我们分析程序性能,dmtracedump生成函数调用图.遗憾的是,google提供的dmtracedump是个失败的工具,并不能绘图,本文会详细介绍解决方案,实现绘图. ?生成.trace文件 android.os.Debug类,其中重要的两个方法Debug.startMethodTracing

[Android]Android经典教程

第一季1.Android平台一日游2.搭建Android开发环境3.Say Hello To Android4.Activity初步5.Activity和Intent6.Android当中的常见控件7.Activity生命周期(一)8.Activity生命周期(二)9.Activity布局初步(一)10.Activity布局初步(二)11.Activity布局初步(三)12.Android常见控(二)13.Android常用控件(三)14.Handler的使用(一)15.Handler的使用(二

[Android]Android TraceView工具使用

一. 选择跟踪范围 在想要根据的代码片段之间使用以下两句代码 Debug.startMethodTracing("love_world_"); Debug.stopMethodTracing(); 例如,onCreate与onStart方法之间方法跟踪 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCr

[Android]Android日志抓取软件测试

1. log文件分类简介 1. 实时打印: 1.1 logcat main(应用程序) -- adb logcat -b main -v time > app.log 1.2 logcat radio(射频相关-SIMSTK,modem相关的ATcommand) -- adb logcat -b radio -v time > radio.log 1.3 logcat events(系统事件的日志,比如触屏事件等) -- adb logcat -b events -v time 1.4 tcp

Android # Android 环境搭建之 Python 配置

在终端输入python,然后import sysprint sys.path The Python Tutorial - Python v2.7.7 documentation https://docs.python.org/2.7/tutorial/index.html Python 3.1.2和2.7比较哪个版本更稳定?_python吧_百度贴吧 http://tieba.baidu.com/p/936048566 python2.7.3和3.3.2的区别_百度知道 http://zhida

[Android]Android布局优化之 merge

转载请标明:转载于http://www.cnblogs.com/Liuyt-61/p/6602915.html ----------------------------------------------------------------- >使用merge合并UI布局 作用:合并UI布局,使用该标签能降低UI布局的嵌套层次 场景(1):布局根结点是FrameLayout且不需要设置background或padding等属性,可用merge代替. 场景(2):某布局作为子布局被其他布局incl