Android.mk的用法和基础

 
 一个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文件系统。
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw :表示 system/lib/hw
 
用法如:
CAL_MODULE_PATH:=$(TARGET_ROOT_OUT)
 
 
 
指定编译顺序:
 
Android.mk
/**********************************************************************************/
LOCAL_PATH := $(my-dir)


#指定编译顺序
include $(LOCAL_PATH)/****/Android.mk \
            $(LOCAL_PATH)/****/Android.mk \

****************************************/




这里提供了一些代码,帮助你实现一些普通的编译任务。

一、编译一个简单的APK
  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
   
  # Tell it to build an APK
  include $(BUILD_PACKAGE)
二、编译一个依赖某个.jar文件的APK
  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)
三、编译一个用platform key签过名的APK
  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)
四、编译一个用vendor key签名的APK
 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)

五、添加一个prebuilt APK
 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)
、添加一个静态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)
Android.mk中的变量
下面列出了一些你在Android.mk文件中常见的变量,先看一下名字前缀:
1LOCAL_:这类变量每个模块都要设置自己,用include $(CLEAR_VARS)可以清除这类变量,这类变量也是使用最多的。
2PRIVATE_:这类变量是make-target-specific的变量。只有在编译某个模块时才会用到这类变量。在你从子模块返回时,这类变量不会改变。这个可以对我一下标准的make教程。
3HOST_TARGET_:这里包含了一些针对特定的hosttarget的目录和定义。不要在make文件中设置这类变量。
4BUILD_CLEAR_VARS:这类变量通常是一些预定义过的模板make文件的名字。比如CLEAR_VARSBUILD_HOST_PACKAGE,通常执行某个具体功能。
5、编译系统不可以递归调用,因为所有的变量都是全局的。

Parameter

Description

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

In Android.mk files that include $(BUILD_PACKAGE) set this to the set of files you want built into your app. Usually:

LOCAL_ASSET_FILES += $(call find-subdir-assets)

调用include $(BUILD_PACKAGE),会把这个属性中列出的文件编译到app中。

LOCAL_BUILT_MODULE_STEM

 

LOCAL_C_INCLUDES

Additional directories to instruct the C/C++ compilers to look for header files in. These paths are rooted at the top of the tree. UseLOCAL_PATH if you have subdirectories of your own that you want in the include paths.

如果想CC++编译器在更多的目录中搜索头文件的话,把这些附加的目录包含在这个属性中。如果这些目录中还有子目录的话,使用LOCAL_PATH

For example:

LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src

You should not add subdirectories of include to LOCAL_C_INCLUDES, instead you should reference those files in the #includestatement with their subdirectories.

不要把子目录添加到这个属性中去,应该使用#include去包含子目录。

For example:

#include <utils/KeyedVector.h>
not #include <KeyedVector.h>

LOCAL_CC

If you want to use a different C compiler for this module, set LOCAL_CC to the path to the compiler. If LOCAL_CC is blank, the appropriate default compiler is used.

如果你想为当前模块使用一个不同的C编译器,就在这个属性中设置好路径

LOCAL_CERTIFICATE

 

LOCAL_CFLAGS

If you have additional flags to pass into the C or C++ compiler, add them here.

如果有一些标识需要传递给编译器的话,放在这个属性中。

For example:

LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1

LOCAL_CLASSPATH

 

LOCAL_COMPRESS_MODULE_SYMBOLS

 

LOCAL_COPY_HEADERS

The set of files to copy to the install include tree. You must also supply LOCAL_COPY_HEADERS_TO.

This is going away because copying headers messes up the error messages, and may lead to people editing those headers instead of the correct ones. It also makes it easier to do bad layering in the system, which we want to avoid. We also aren't doing a C/C++ SDK, so there is no ultimate requirement to copy any headers.

由于这个属性常常引起一些问题,以后会被删除。

LOCAL_COPY_HEADERS_TO

The directory within "include" to copy the headers listed in LOCAL_COPY_HEADERS to.

This is going away because copying headers messes up the error messages, and may lead to people editing those headers instead of the correct ones. It also makes it easier to do bad layering in the system, which we want to avoid. We also aren't doing a C/C++ SDK, so there is no ultimate requirement to copy any headers.

LOCAL_CPP_EXTENSION

If your C++ files end in something other than ".cpp", you can specify the custom extension here.

如果你的C++文件扩展名不是“.cpp的话,把自定义的扩展名写在这里。

For example:

LOCAL_CPP_EXTENSION := .cc

Note that all C++ files for a given module must have the same extension; it is not currently possible to mix different extensions.

注意,一个模块中,所有的C++文件必须有相同的扩展名。

LOCAL_CPPFLAGS

If you have additional flags to pass into only the C++ compiler, add them here.

你如果只想传递一些标志给C++编译器,写在这里。

For example:

LOCAL_CPPFLAGS += -ffriend-injection

LOCAL_CPPFLAGS is guaranteed to be after LOCAL_CFLAGS on the compile line, so you can use it to override flags listed inLOCAL_CFLAGS

LOCAL_CXX

If you want to use a different C++ compiler for this module, set LOCAL_CXX to the path to the compiler. If LOCAL_CXX is blank, the appropriate default compiler is used.

如果想为当前模块使用一个不同的C++编译器,把编译器的路径写在这里

LOCAL_DX_FLAGS

 

LOCAL_EXPORT_PACKAGE_RESOURCES

 

LOCAL_FORCE_STATIC_EXECUTABLE

If your executable should be linked statically, set LOCAL_FORCE_STATIC_EXECUTABLE:=true. There is a very short list of libraries that we have in static form (currently only libc). This is really only used for executables in /sbin on the root filesystem.

如果你的可执行文件需要静态链接的话,就把这个变量设置为true。只有很少的库需要静态链接,目前只是libc库。事实上,这种形式只用于/sbin目录下的可执行文件。

LOCAL_GENERATED_SOURCES

Files that you add to LOCAL_GENERATED_SOURCES will be automatically generated and then linked in when your module is built. See the Custom Tools template makefile for an example.

添加到这个属性中的文件会在编译模块时自动生成并链接,可以看一下例子子。

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

When linking Java apps and libraries, LOCAL_JAVA_LIBRARIES specifies which sets of java classes to include. Currently there are two of these: core and framework. In most cases, it will look like this:

LOCAL_JAVA_LIBRARIES := core framework

Note that setting LOCAL_JAVA_LIBRARIES is not necessary (and is not allowed) when building an APK with "include $(BUILD_PACKAGE)". The appropriate libraries will be included automatically.

链接Java程序和Java库时,这个属性会标识出哪个Java库会被包含。当前只有两个,coreframework。大部分情况下,会是这样的形式:LOCAL_JAVA_LIBRARIES := core framework。注意,当使用"include $(BUILD_PACKAGE)"来编译APK时,这个属性不能设置。因为相应库会自动链接。

LOCAL_JAVA_RESOURCE_DIRS

 

LOCAL_JAVA_RESOURCE_FILES

 

LOCAL_JNI_SHARED_LIBRARIES

 

LOCAL_LDFLAGS

You can pass additional flags to the linker by setting LOCAL_LDFLAGS. Keep in mind that the order of parameters is very important to ld, so test whatever you do on all platforms.

通过这个属性,你可以向链接器传递一些会加的标识。一定要注意,参数的顺序对ld来说非常重要,多多测试。

LOCAL_LDLIBS

LOCAL_LDLIBS allows you to specify additional libraries that are not part of the build for your executable or library. Specify the libraries you want in -lxxx format; they're passed directly to the link line. However, keep in mind that there will be no dependency generated for these libraries. It's most useful in simulator builds where you want to use a library preinstalled on the host. The linker (ld) is a particularly fussy beast, so it's sometimes necessary to pass other flags here if you're doing something sneaky.

不管是编译可执行文件还是编译库,这个属性允许你添加一些附加库。需要注意的是,编译系统不会生成这些库的依赖关系。通常,这个属性会在编译模拟器时使用,你可能会使用一个已经安装在host上的库。

Some examples:

LOCAL_LDLIBS += -lcurses -lpthread
LOCAL_LDLIBS += -Wl,-z,origin

LOCAL_MODULE

LOCAL_MODULE is the name of what's supposed to be generated from your Android.mk. For exmample,

for libkjs, theLOCAL_MODULE is "libkjs" (the build system adds the appropriate suffix -- .so .dylib .dll). For app modules, useLOCAL_PACKAGE_NAME instead of LOCAL_MODULE.

这个属性存放你要生成的模块名字。如果是app模块,使用LOCAL_PACKAGE_NAME属性。

LOCAL_MODULE_PATH

Instructs the build system to put the module somewhere other than what's normal for its type. If you override this, make sure you also set LOCAL_UNSTRIPPED_PATH if it's an executable or a shared library so the unstripped binary has somewhere to go. An error will occur if you forget to.

用新路径替换掉编译系统生成模块的默认存放路径。如果编译目标是一个可执行文件或者一个共享库,还必须设置LOCAL_UNSTRIPPED_PATH 属性来保存unstripped二进制文件,如果没有设置的话,编译系统会报错。

See Putting modules elsewhere for more.

LOCAL_MODULE_STEM

 

LOCAL_MODULE_TAGS

Set LOCAL_MODULE_TAGS to any number of whitespace-separated tags.

This variable controls what build flavors the package gets included in.

该属性的多个值之间以空格分隔。

For example:

  • user: include this in user/userdebug builds

  • eng: include this in eng builds

  • tests: the target is a testing target and makes it available for tests

  • optional: don't include this

LOCAL_NO_DEFAULT_COMPILER_FLAGS

 

LOCAL_NO_EMMA_COMPILE

 

LOCAL_NO_EMMA_INSTRUMENT

 

LOCAL_NO_STANDARD_LIBRARIES

 

LOCAL_OVERRIDES_PACKAGES

 

LOCAL_PACKAGE_NAME

LOCAL_PACKAGE_NAME is the name of an app. For example, Dialer, Contacts, etc.

属性值是要生成的app的名字。

LOCAL_POST_PROCESS_COMMAND

For host executables, you can specify a command to run on the module after it's been linked. You might have to go through some contortions to get variables right because of early or late variable evaluation:

module := $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)
LOCAL_POST_PROCESS_COMMAND := /Developer/Tools/Rez -d __DARWIN__ -t APPL/
       -d __WXMAC__ -o $(module) Carbon.r

LOCAL_PREBUILT_EXECUTABLES

When including $(BUILD_PREBUILT) or $(BUILD_HOST_PREBUILT), set these to executables that you want copied. They're located automatically into the right bin directory.

使用$(BUILD_PREBUILT) $(BUILD_HOST_PREBUILT)时,这个属性设置为你想复制的可执行文件列表,它们会被自动定位。

LOCAL_PREBUILT_JAVA_LIBRARIES

 

LOCAL_PREBUILT_LIBS

When including $(BUILD_PREBUILT) or $(BUILD_HOST_PREBUILT), set these to libraries that you want copied. They're located automatically into the right lib directory.

使用$(BUILD_PREBUILT) $(BUILD_HOST_PREBUILT)时,这个属性设置为你想复制的库文件列表,它们会被自动定位。

LOCAL_PREBUILT_OBJ_FILES

 

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES

 

LOCAL_PRELINK_MODULE

 

LOCAL_REQUIRED_MODULES

Set LOCAL_REQUIRED_MODULES to any number of whitespace-separated module names, like "libblah" or "Email". If this module is installed, all of the modules that it requires will be installed as well. This can be used to, e.g., ensure that necessary shared libraries or providers are installed when a given app is installed.

属性值是有空格分隔的一系列模块名字,如“libblah”或“Email”。如果当前编译的模块被安装,这个列表中所有的模块也会被安装。假如你需要安装一个app时,这种机制可以保证app依赖的共享库或者provider被安装。

LOCAL_RESOURCE_DIR

 

LOCAL_SDK_VERSION

 

LOCAL_SHARED_LIBRARIES

These are the libraries you directly link against.

编译时需要链接的库的列表。

You don't need to pass transitively included libraries. Specify the name without the suffix:

LOCAL_SHARED_LIBRARIES := /
    libutils /
    libui /
    libaudio /
    libexpat /
    libsgl

LOCAL_SRC_FILES

The build system looks at LOCAL_SRC_FILES to know what source files to compile -- .cpp .c .y .l .java. For lex and yacc files, it knows how to correctly do the intermediate .h and .c/.cpp files automatically. If the files are in a subdirectory of the one containing the Android.mk, prefix them with the directory name:

需要编译的文件列表,如果某些文件在一个子目录中,而且这个子目录中也包含一个Android.mk,就像下面这样使用。

LOCAL_SRC_FILES := /
    file1.cpp /
    dir/file2.cpp

LOCAL_STATIC_JAVA_LIBRARIES

 

LOCAL_STATIC_LIBRARIES

These are the static libraries that you want to include in your module. Mostly, we use shared libraries, but there are a couple of places, like executables in sbin and host executables where we use static libraries instead.

编译模块时需要链接的静态库列表。大部分情况下,我们使用共享库,但链接sbin中的可执行文件和host上的可执行文件时,会使用静态库。

LOCAL_STATIC_LIBRARIES := /
    libutils /
    libtinyxml

LOCAL_UNINSTALLABLE_MODULE

 

LOCAL_UNSTRIPPED_PATH

Instructs the build system to put the unstripped version of the module somewhere other than what's normal for its type. Usually, you override this because you overrode LOCAL_MODULE_PATH for an executable or a shared library. If you overrodeLOCAL_MODULE_PATH, but not LOCAL_UNSTRIPPED_PATH, an error will occur.

告诉编译系统把模块的unstripped版本放在某个地方。通常,你给LOCAL_MODULE_PATH 赋值时才会给这个属性赋值。如果你给LOCAL_MODULE_PATH 赋值,但不给这个属性赋值,系统会报错。

See Putting modules elsewhere for more.

LOCAL_WHOLE_STATIC_LIBRARIES

These are the static libraries that you want to include in your module without allowing the linker to remove dead code from them. This is mostly useful if you want to add a static library to a shared library and have the static library's content exposed from the shared library.

想把静态库包含在模块中,又不想链接器移除无用的代码时,使用这个属性。通常用于你想把一个静态库添加到共享库中,或者让静态库从共享库中暴露出来时。

LOCAL_WHOLE_STATIC_LIBRARIES := /
    libsqlite3_android

LOCAL_YACCFLAGS

Any flags to pass to invocations of yacc for your module. A known limitation here is that the flags will be the same for all invocations of YACC for your module. This can be fixed. If you ever need it to be, just ask.

调用yacc时传递的标记。注意,当前模块中所有的yacc调用都会传递这个标记。

LOCAL_YACCFLAGS := -p kjsyy

OVERRIDE_BUILT_MODULE_PATH

 

 

你可能感兴趣的:(Android.mk的用法和基础)