Android中Makefile编写

本文详细介绍了Android中Makefile的使用,包括如何编译APK,集成第三方库(如.jar和.so/.a),以及编译结果的生成路径。在Android.mk文件中,LOCAL_PATH、CLEAR_VARS、BUILD_XXX宏等起到了关键作用。同时,文中还讲解了如何通过LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES来集成静态和动态库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、编译一个APK的示例

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

 

LOCAL_MODULE_TAGS:= optional (user debug engtests optional samples shell_ash shell_mksh)

LOCAL_SDK_VERSION:= current

 

# List oflibraries to include in the package

LOCAL_STATIC_LIBRARIES:=

LOCAL_SHARED_LIBRARIES:=

LOCAL_STATIC_JAVA_LIBRARIES:=

 

# Build all javafiles in the java subdirectory-

LOCAL_SRC_FILES := $(call all-java-files-under, src)

 

# Name of theAPK to build

LOCAL_PACKAGE_NAME:= LocalPackage

 

LOCAL_CERTIFICATE:=

LOCAL_PROGUARD_FLAG_FILES:=

 

# Tell it tobuild an APK

include$(BUILD_PACKAGE)

 

# Use thefollowing include to make our test apk.

include $(callall-makefiles-under,$(LOCAL_PATH))

 

Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。

LOCAL_PATH:=$(call my-dir)

一般情况下Android.mk和需要编译的源文件在同一目录下,所以定义成上述形式,意思是将LOCAL_PATH变量定义成本文件所在目录路径。

Android.mk中可以定义多个编译模块,每个编译模块都是

include $(CLEAR_VARS)开始,

include $(BUILD_XXX)结束。

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_STATIC_JAVA_LIBRARY)表示编译成java库。

include $(BUILD_EXECUTABLE)表示编译成可执行程序。

include $(BUILD_PACKAGE) 表示编译成应用程序。

二、APK集成第三方库

Android中使用第三方库可能有两种:java库.jar和native库.so/.a。如果做上层APK开发,可以通过Eclipse集成开发环境进行集成;如果是平台级开发,可以通过源码集成,源码集成第三方库至少有两种方式:C/C++链接方式和Android prebuilt方式。这里只讨论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会更方便些,很多它都帮忙处理了。

首先,prebuilt库必须向生成系统声明,需要给出模块名,指定预生成库的路径,模块类型(SHARED_LIBRARIES /STATIC_LIBRARIES)。预生成模块不生成任何东西。预生成库将会复制到$PROJECT/obj/local和复制裁剪到$PROJECT/libs/<abi>目录下。

然后在其他模块中引用预生成库。在Android.mk文件中,将预生成模块名作为LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES的变量值。

此外,.so还可以集成到build/core/user_tags.mk中,不过一般不建议那么做,我们应尽量减少修改系统级配置。

 

l  集成jar包

LOCAL_STATIC_JAVA_LIBRARIES:= libXX1 \

                                                                                    libXX2

######################

include$(CLEAR_VARS) 

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:= libXX1:XXX1.jar \

                                                                                                               libXX2:XXX2.jar

include$(BUILD_MULTI_PREBUILT)

 

LOCAL_STATIC_JAVA_LIBRARIES取jar库的别名,可以任意取值;

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuilt jar库的规则,格式:别名:jar文件路径。注意:别名一定要与LOCAL_STATIC_JAVA_LIBRARIES里所取的别名一致,且不含.jar;jar文件路径一定要是真实的存放第三方jar包的路径。

 

l  集成.so动态库

LOCAL_SHARED_LIBRARIES:= libXX

######################

include$(CLEAR_VARS)

LOCAL_PREBUILT_LIBS:= libXXX:XXX.so

include$(BUILD_MULTI_PREBUILT)

 

LOCAL_PREBUILT_LIBS指定prebuilt so库规则,格式:别名:so文件路径。

 

l  集成.a静态库

LOCAL_STATIC_LIBRARIES:= libXX

##############################

include$(CLEAR_VARS)

LOCAL_PREBUILT_LIBS:= libXX:libXX.a

include$(BUILD_MULTI_PREBUILT)

 

l  Prebuilt示例

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE :=

LOCAL_MODULE_CLASS :=

LOCAL_MODULE_PATH :=               #模块安装路径

LOCAL_MODULE_TAGS :=

LOCAL_SRC_FILES :=

include $(BUILD_PREBUILT)

 

三、编译结果生成路径

<base_rules.mk><envsetup.mk>

每个模块在编译的时候都会产生一个编译目录和一个安装目录,编译目录就是这个模块编译以后生成的目标文件,安装目录就代表着这个模块是否会编译进文件系统,就是是否编译进IMG。

 

LOCAL_MODULE                                                       #模块名称

LOCAL_MODULE_STEM                                       #模块名称,不带后缀

LOCAL_MODULE_PATH                                       #模块安装路径

 

LOCAL_INSTALLED_MODULE_STEM #模块名称+后缀

LOCAL_INSTALLED_MODULE                         #安装路径+模块名称+后缀

 

built_module_path := $(intermediates)           #目标文件路径

LOCAL_BUILT_MODULE_STEM                     #目标文件名称+后缀

LOCAL_BUILT_MODULE                                   #目标文件路径+文件名+后缀

 

目标文件路径

TARGET_OUT:= $(PRODUCT_OUT)/system

TARGET_OUT_APPS:=$(TARGET_OUT)/app

TARGET_OUT_SHARED_LIBRARIES:=$(TARGET_OUT)/lib

 

TARGET_OUT_INTERMEDIATES:= $(PRODUCT_OUT)/obj

TARGET_OUT_STATIC_LIBRARIES:=$(TARGET_OUT_INTERMEDIATES)/lib

TARGET_OUT_INTERMEDIATE_LIBRARIES:= $(TARGET_OUT_INTERMEDIATES)/lib 

TARGET_OUT_COMMON_INTERMEDIATES:= $(TARGET_COMMON_OUT_ROOT)/obj

 

1、如果LOCAL_MODULE_CLASS包含COMMON_MODULE_CLASS := JAVA_LIBRARIES NOTICE_FILES,则编译出的中间文件会放在:

$(TARGET_OUT_COMMON_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates/

TARGET_OUT_COMMON_INTERMEDIATES := out/target/common/obj

 

2、如果LOCAL_MODULE_CLASS不包含COMMON_MODULE_CLASS,则编译出的中间文件会放在:

$(TARGET_OUT_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates/

TARGET_OUT_INTERMEDIATES :=out/target/product/$PROJECT/obj

 

.apk安装路径:

out/target/product/$PROJECT/system/app/$MODULE.apk

.apk目标路径:

out/target/product/$PROJECT/obj/APPS/$MODULE_intermediates/package.apk

.jar/.so/.a目标路径:

out/target/product/$PROJECT/obj/JAVA_LIBRARIES/libXXX_intermediates/javalib.jar

out/target/product/$PROJECT/obj/lib/libXXX.so

out/target/product/$PROJECT/obj/SHARED_LIBRARIES/libXXX_intermediates/

out/target/product/$PROJECT/obj/STATIC_LIBRARIES/libXXX_intermediates/

 

out/target/common/obj/APPS/$APP_intermediates/

out/target/common/obj/JAVA_LIBRARIES/libXXX_intermediates/classes.jar

                                                                                                                                            javalib.jar

四、Android编译系统模块中的LOCAL_XXX变量

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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值