安卓预编译动态库
㈠ android 怎么编译so文件
android NDK编译多个so文件
android编译系统的makefile文件Android.mk写法如下
(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)
# Mole name should match apk name to be installed.
LOCAL_MODULE := LocalMoleName
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 NDK 如何使用自己的共享库
Import MoleNDK r5 支持预编译的共享库所谓预编译的共享库,就是说你自己从其他地方找来的源码,编译出来的共享库。这个共享库自己有,android 系统中没有。使用方法如下:1、声明一个共享库模块:把这个共享库声明为 “一个” 独立的模块。假如libfoo.so 与 Android.mk 位于同一个目录。则 Android.mk 应该这样写: LOCAL_PATH := $(call my-dir)LOCAL_STATIC_LIBRARIES include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt # 模块名 LOCAL_SRC_FILES := libfoo.so # 模块的文件路径(相对于 LOCAL_PATH) include $(PREBUILT_SHARED_LIBRARY) # 注意这里不是 BUILD_SHARED_LIBRARY这个共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (stripped)2、在其他模块中引用这个共享库 在Android.mk 中,将这个共享库的模块名加入 LOCAL_STATIC_LIBRARIES (静态库) 或者LOCAL_SHARED_LIBRARIES (动态库)例如, 使用 libfoo.so 的方法: include $(CLEAR_VARS) LOCAL_MODULE := foo-user LOCAL_SRC_FILES := foo-user.c LOCAL_SHARED_LIBRARY := foo-prebuilt include $(BUILD_SHARED_LIBRARY)3、为该共享库导出头文件 这个共享库一般会有对应的头文件,比如 libfoo.so 就有 foo.h 一个简单的方法: include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) 这样,使用该共享库的模块就会在其 LOCAL_C_INCLUDES 变量中,加入这个包含路径 4、调试共享库 建议你的共享库包含调试信息。 $PROJECT/libs/<abi> 目录下的共享库都是 strip 之后的 有调试信息的版本,要被 ndk-gdb 使用5、共享库的 ABI 你的共享库与目标系统的ABI的兼容性很重要。 请检查 TARGET_ARCH_ABI,有以下值: armeabi => ARMv5TE 以上 armeabi-v7a => ARMv7 以上 x86 => x86 建议: armeabi ABI 可以运行在所有 ARM CPU 上面。
㈢ 安卓平台属于动态库操作吗
属于
静态库全称静态链接库,动态库全称动态链接库,看到全称就知道什么意思了吧?也就是说在链接的时候才会用到的库,只有C/C++、OC语言才会有链接过程,Java没有。
在Android中说到静态库和动态库,一般说的都是C/C++代码,我们知道在android中是通过jni技术访问到C代码的,我们会把C/C++打包成so文件,这个就是动态库(共享库)。如果我们想要使用的C库是.a形式的静态库时,我们要把.a包装成so库,具体网上有方法。
个人感觉在java语言中讨论静态库和动态库就是个伪概念,java是的编译结果是字节码文件,不是二进制文件,而且没有链接的过程,jvm在解释执行java代码的时候调用C++代码只能是动态的。
在C++和object C开发中,用编译链接的过程,静态库在链接过程中,会和自己写的源代码打到一块,多个程序多个静态库。动态库不会打到一块,如果有共享情况的话,系统只会加载一次。
OC的代码处理过程是很复杂的,有预处理、编译、链接过程,预处理就是处理宏什么的,编译这个过程就很复杂了,有编译前端和编译后端,编译称机器码(中间还会有汇编的过程),链接就是链接动态库或者静态库。
Android(java)代码处理过程就很简单啦,毕竟是运行在虚拟机上的。没有所谓的预处理,直接编译,这里的编译也就是把java代码转化成字节码,这个编译和OC中的编译可不是一个概念,只不过也这么叫而已。后续Aandroid还会用dex工具把.class打包成.dex,不同的VM模式(5.0以后都是ART)会对.dex进行不同的优化,具体看Android 编译到运行APK过程总结。需要提一下的是,ART采用AOT和JIT技术,在安装或者运行的时候,会把字节码转化成机器码,这个机器码也会受VM控制的,具体看Android之Dalvik 、ART
C/C++、Object C属于编译型语言,这是毋庸置疑的,因为它们都会在生成安装包之前编译成机器码。
㈣ Android 怎么自定义共享库
LOCAL_PATH := $(call my-dir)//标准mk语句,指编译路径,所有mk文件第一句都是这个 /**这个模块表示引用了一个本地的静态库 include $(CLEAR_VARS) //清除各种变量,因为这些变量是静态全局的,如果清除,下次编译时又会用到这些变量造成出错 LOCAL_MODULE := libopencore-amrnb //本地静态库模块的名字,这个名字在下面编译jni时需要引用 LOCAL_SRC_FILES := lib/libopencore-amrnb/smfwuxiao/article/details/6591927 NDK r5 开始支持预编译共享库。预编译共享库就是从其他地方获得源码编译出的共享库,而不是Android系统自带的。方法如下: 1、声明共享库模块 把共享库声明为一个独立模块。假如 libfoo.so 与 Android.mk 位于同一目录。则 Android.mk 应该这样写: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt # 模块名 LOCAL_SRC_FILES := libfoo.so # 模块的文件路径(相对于 LOCAL_PATH) include $(PREBUILT_SHARED_LIBRARY) # 注意这里不是 BUILD_SHARED_LIBRARY 这个共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (strip过的) 2、在其他模块中引用这个共享库 在 Android.mk 中,将这个共享库的模块名加入 LOCAL_STATIC_LIBRARIES (静态库)或 LOCAL_SHARED_LIBRARIES (动态库) 例如, 使用 libfoo.so 的方法: include $(CLEAR_VARS) LOCAL_MODULE := foo-user LOCAL_SRC_FILES := foo-user.c LOCAL_SHARED_LIBRARY := foo-prebuilt include $(BUILD_SHARED_LIBRARY) 3、为共享库导出头文件 这个共享库一般有相应的头文件,比如 libfoo.so 就有 foo.h。 一个简单方法(在Android.mk中写): include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) 这样,使用该共享库的模块就会在它的 LOCAL_C_INCLUDES 变量加入该头文件搜索路径。 4、调试共享库 建议你的共享库保留调试信息。 $PROJECT/libs/<abi> 目录下的共享库都是 strip 之后的(没有调试信息)。有调试信息的版本可被ndk-gdb使用。 5、共享库 ABI 你的共享库与目标系统ABI的兼容性很重要。 请检查 TARGET_ARCH_ABI,有以下值: armeabi => ARMv5TE 以上 armeabi-v7a => ARMv7 以上 x86 => x86 建议: armeabi ABI 可以运行在所有 ARM CPU 上。
㈤ Android Studio手动配置Makefile、CMake
在Ubutu上编译出来的.so文件,怎么添加到Android项目中去使用呢?目前:可以通过
Makefile方式和CMake方式引入预编译静动态库(静态库.a 动态库.so)到项目中去使用。就目前而言CMake是Goole推荐使用方式,但是加入接手一个老的NDK项目是MakeFile方式,看不懂就GePi了,所以这里我们还是介绍一下MakeFile方式将静动态库加入到AS中,完成NDK项目的开发。废话不多说,直接撸步骤了:
1、在src/main目录下创建一个ndkBuild文件夹
2、在此文件中创建一个Android.mk文件
3、在此文件中创建一个test.c的源文件
4、将编译好的的.so库复制到src/main目录下
如图所示目录结构:
1、编辑Android.mk文件
2、编辑grade(app)文件
3、编辑test.c文件
4、使用编译好的.so库里面的函数
本结果运行在Android 5.1 系统上
再次运行在Android 8.0系统上
看以清楚知道,其实我们的APK包里面就没有libMainTest.so库,所以APP在8.0上会出现奔溃的现象。so...
1、在src/main目录下创建一个cmake文件夹
include:里面包含需要一些头文件
cmakeTest.c:需要编译的源文件
2、在app目录下创建一个文件:CmakeLists.txt
3、编辑grade(app)
4、编辑cmakeTest.c文件
4、引用编译好的libcmakeTest.so
Android 8.0.0系统:
Android 5.1.1系统:
㈥ 怎么用Qt Creator编写JNI的so动态库供安卓java开发者使用
这种情况可以通过代码目的JNI去调用,在JNI中导入头文件,通过NDK编译成功后即可。学习java推荐千锋教育,该机构坐拥国内顶级的教师团队,每年培养众多学子,值得托付和信赖。
Java语言基础数据类型有两种:对象和基本类型(Primitives)。Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先声明。这种机制和非静态类型的语言有很大差别,非静态语言不要求对变量进行声明。虽然显式类型声明看起来较繁琐,但其有助于编译器对很多编程错误的预防,例如,由于变量名拼写错误导致创建了没有用的变量,调用了不存在的方法等。显式声明可以彻底防止这些错误被生成到运行代码中。
想要了解更多有关java开发的相关信息,推荐咨询千锋教育。千锋企业合作部于2013年成立,主要针对企业用人需求和学员职业规划进行服务。经过8年发展,企业合作部已经成为千锋连接企业和学员的重要纽带。服务面对企业建立全方位、立体化、遍布全国的企业合作网络,覆盖全国一线二线城市大中小型公司,成功帮助20000余名人才实现就业,合作企业达20000余家,每年签订1000余份人才培养订单,让广大学员没有后顾之忧。
㈦ 第二章:Android.bp语法
注意 :关于Android.bp的权威解释可以参见 android.bp权威文档
Google官方语法文档 https://android.googlesource.com/platform/build/soong
从前面的列子可以看出定义一个模块从模块的类型开始,模块有不同的类型,如前面例子中的cc_library_shared,当然类型还有很多种,譬如 cc_binary、android_app 、cc_library_static 等等。模块包含一些属性格式为“property-name:property-value”,其中name属性必须指定,其属性值必须是全局唯一的。
其中默认模块可用于在多个模块中重复相同的属性
srcs 属性以字符串行表的形式指定用于编译模块的源文件。您可以使用模块引用语法 “:” 来引用生成源文件的其他模块的输出,如 genrule 或 filegroup。
实例说明:
我们知道Android.mk中可以定义变量,当然作为新编译系统中替代Android.mk的Android.bp也是一定存在,更加何况Android.mk还可以一定条件的转换成Android.bp。
变量范围限定为声明它们的文件的其余部分,可以使用 “=” 号赋值, 但是不能使用 “:=” 赋值。变量是不可变的,但有一个例外它们可以附上+= 赋值,但仅在变量被引用之前。
下面我们看一下正确使用变量的列子:
我们知道Android.mk中可以进行注释,当然Android.bp里面也可以,Android.mk中使用 # 然后添加注释,Android.bp使用单行注释 // 和多行注释 /* */ 两种方式。
具体支持以下几种类型:
String类型、字符串行表类型和Map类型支持操作符 + 。
Android.bp可以支持android_app、cc_binary、cc_binary_host等多种类型,具体定义在Android源码的 build/soong/androidmk/cmd/androidmk/android.go 可以查看,具体如下:
Android.bp可以支持多种预编译类型,具体定义在Android源码的 build/soong/androidmk/cmd/androidmk/android.go 可以查看,如下图所示:
例如: system/core/libusbhost/Android.bp aosp9.0开始
Android.bp是一门实战性的东西,光说不练没有啥用,说再多不如直接开练来得舒服。那就直接开始手撕实例了,让我们开战吗!
下面几种库编译类型:
2.1 动态库类型
最终编译为so包
**2.2 java库类型: **
最终编译为jar包
2.3 Andorid应用类型
最终编译为apk包
转自: https://blog.csdn.net/tkwxty/article/details/104395820
㈧ android 怎么引用一个静态库
由于工作需要,需要在framework中增加自己的动态库,并且动态库需要使用合作方提供的第三方静态库。但是在引入静态库编译动态库时总是提示失败。具体如下:
1. 文件列表
可以看出这个配置文件的内容主要分为两部分,第一部分预编译静态库,这一过程不触发构建过程,仅仅是重起了个名字,并且将该库拷贝到某个路径下(具体可以参看另一篇文章,NDK使用二进制库的方法);第二部分是用于编译动态本地库,可以看出它通过LOCAL_STATIC_LIBRARIES关键字引入了之前预编译的静态库。
㈨ 如何导入Android的AAR动态库so文件到底怎么样放
1、 .so动态库的生成 可使用gcc或者g++编译器生成动态库文件(此处以g++编译器为例) g++ -shared -fPIC -c XXX.cpp g++ -shared -fPIC -o XXX.so XXX.o 2、 .so动态库的动态调用接口函数说明 动态库的调用关系可以在需要调用动态库的程序编译时,。可以看看安卓巴士教程:http://www.apkbus.com/thread-464057-1-1.html
㈩ Android 怎么自定义共享库
在源码根目录下有个 vendor (供应商) 目录,专门用于存放各个供应商的会有代码。其中有一个个 sample 目录,这是 Google 用于示范如何编写自定义共享库的示例,它展示了自定义共享库、JNI 调用、对库的使用方法及皮肤定制等功能。下面我们通过对该示例进行分析,让大家熟悉这个轻量级的框架。
1、首先看一下 sample 目录的结构:
sample
├── Android.mk
├── apps
│ ├── Android.mk
│ ├── client
│ └── upgrade
├── frameworks
│ ├── Android.mk
│ └── PlatformLibrary
├── MODULE_LICENSE_APACHE2
├── procts
│ ├── AndroidProcts.mk
│ └── sample_addon.mk
├── README.txt
├── sdk_addon
│ ├── hardware.ini
│ └── manifest.ini
└── skins
└── WVGAMedDpi
Android.mk: 该文件用于编写构建规则,默认继承 Android 的 make 框架。
frameworks: 该目录在这里的意义等同于 Android 源码中的 frameworks 。
PlatformLibrary: 该目录就自定义共享库。
apps: 该目录用于编写依赖该库的应用程序。经过测试也可以用来编写不依赖该库的程序,这有个好处,让开发商可以把自己特有的应用集成到框架中。
client 与 upgrade: 这是两个依赖该库的应用程序示例。
procts: 该目录中的文件对包含该库与 Android 框架集成的信息,如模块名称等。
AndroidProcts.mk: 指明该模块的 make 配置文件的在哪里。
sample_addon.mk :模块的配置信息。
sdk_addon: 该目录对该库的硬件需求进行定义。
hardware.ini: 定义模块对硬件的需求。
manifest.ini: 模块的说明文件。名称、供应商等。
skins: 该目录用于存放自定义皮肤。
WVGAMedDpi: 已经定义好的一套皮肤。
2.如何封装 Java 共享库?
PlatformLibrary 为我们展示了封装 Java 共享库的方法。其目录结构如下: frameworks/PlatformLibrary
├── Android.mk
├── com.example.android.platform_library.xml
├── java
│ └── com
│ └── example
│ └── android
│ └── platform_library
│ └── PlatformLibrary.java
└── README.txt
Android.mk: 该文件说明如何构建该模块。
com.example.android.platform_library.xml: 该文件是模块注册时需要的文件。该文件需要被放置到 /system/etc/permissions 目录下。
Java /*: Java 源码所在目录。具体步骤:
a、编写 Java 库,并将源码放到 java 目录下。这一步和编写普通 Java 程序没有差别。
b、编写 Android.mk,内容如下:
# 获得当前目录,清空环境变量
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) # 源码所在目录,all-subdir-java-files 表示所有了目录中的 Java 文件。
LOCAL_SRC_FILES := \
$(call all-subdir-java-files) # 该模块是可选的。
LOCAL_MODULE_TAGS := optional # Java 模块名称
LOCAL_MODULE:= com.example.android.platform_library # 编译为 Java 库。最近以 jar 的形式而不是 apk 的形式存在。
include $(BUILD_JAVA_LIBRARY) # 构建该库的 API 文档
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= platform_library
# 文档对应的库
LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library
# 库的类型
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true # 编译为 Java API。
include $(BUILD_DROIDDOC)
c、编写 com.example.android.platform_library.xml,内容如下:
< xml version="1.0" encoding="utf-8" >
<permissions>
<!-- 库的名称及对应的 Jar 文件位置 -->
<library name="com.example.android.platform_library"
file="/system/framework/com.example.android.platform_library.jar"/>
</permissions> 现在基本的库我们已经编写完成,现在需要对框架中的其它文件进行配置。
d、编写 sample/frameworks/Android.mk, 内容如下:
# 包含子目录中的所有 make 文件 include $(call all-subdir-makefiles) 该文件与 sample/Android.mk 文件相同。
e、编写 sample/sdk_addon/manifest.ini,内容如下: # 该模块的名称、供应商及描述
name=Sample Add-On
vendor=Android Open Source Project
description=sample add-on # 构建该模块的 Android 平台代号
api=3 # 模块的版本号。必须为整数。
revision=1 # 该模块中包括的共享库列表
libraries=com.example.android.platform_library # 对每个库的详细定义,格式如下:
# <library.name>=<name>.jar;<desc> # <library.name>: 通过前面 libraies 定义的库的名称。
# <name>.jar: 包含库 API 的 jar 文件。该文件放在 libs/add-on 下面。
com.example.android.platform_library=platform_library.jar;Sample optional plaform library 该文件还可包括该模块的其它定义,如皮肤等,为了保持该文档清晰易懂的初衷,这里不做介绍,需要了解可以给我邮件。
f、编写 sample/procts/sample_addom.mk,内容如下:
# 要植入系统镜像的应用及可选类库。可以包括 Java 库和本地库。这里我们只有 Java 库。
PRODUCT_PACKAGES := \ com.example.android.platform_library # 把 xml 文件复制到系统镜像中相应的位置去。
PRODUCT_COPY_FILES := \ vendor/
sample/frameworks/PlatformLibrary/com.example.android.platform_library.xml:system/etc/permissions/
com.example.android.platform_library.xml # 这个扩展的名称
PRODUCT_SDK_ADDON_NAME := platform_library # 把模块的 manifest 和硬件配置文件复制到系统镜像中相应的位置。 PRODUCT_SDK_ADDON_COPY_FILES := \
vendor/sample/sdk_addon/manifest.ini:manifest.ini \
vendor/sample/sdk_addon/hardware.ini:hardware.in # 把库的 Jar 包复制到相应的位置。 PRODUCT_SDK_ADDON_COPY_MODULES := \
com.example.android.platform_library:libs/platform_library.jar # 文档的名称。必须与。
# LOCAL_MODULE:= platform_library
PRODUCT_SDK_ADDON_DOC_MODULE := platform_library # 这个扩展继承系统扩展。 $(call inherit-proct, $(SRC_TARGET_DIR)/proct/sdk.mk) # 这个扩展的真实名字。这个名字会用于编译。
# 用 'make PRODUCT-<PRODUCT_NAME>-sdk_addon' 的形式来编译此扩展。
PRODUCT_NAME := sample_addon
g、编写 sample/procts/AndroidProcts.mk,内容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/sample_addon.mk h、最后运行make -j8 PRODUCT-sample_addon-sdk_addon,编译扩展。
至此,我们就完成了 Java 库的封装。
3、接下来我们再来看如何通过 JNI 的方式对 C 代码进行封装。
a、在 sample/frameworks/PlatformLibrary 目录下添加一个文件夹,用于放置 JNI 本地代码,目录结构如下:
frameworks/PlatformLibrary/jni
├── Android.mk
└── PlatformLibrary.cpp
b、把 frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
文件改写为 JIN 调用接口,代码如下 : package com.example.android.platform_library; import android.util.Config;
import android.util.Log; public final class PlatformLibrary {
static { / Load the library. If it's already loaded, this does nothing. System.loadLibrary("platform_library_jni");
private int mJniInt = -1; public PlatformLibrary() {} / Test native methods. public int getInt(boolean bad) {
// this alters mJniInt //
int result = getJniInt(bad); // reverse a string, for no very good reason //
String reverse = reverseString("Android!"); Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'"); return mJniInt; //
/ Simple method, called from native code. private static void yodel(String msg) {
Log.d("PlatformLibrary", "yodel: " + msg); //
/ Trivial native method call. If "bad" is true, this will throw an
/ exception. native private int getJniInt(boolean bad); / Native method that returns a new string that is the reverse of
/ the original. This also calls yodel(). native private static String reverseString(String str);
}
c、在 frameworks/PlatformLibrary/jni/PlatformLibrary.cpp 中编写 PlatformLibrary.java 中规定本地调用的具体实现。
d、编写 frameworks/PlatformLibrary/jni/Android.mk,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional # JNI 模块的名称
LOCAL_MODULE:= libplatform_library_jni # 依赖的源代码文件
LOCAL_SRC_FILES:= \
PlatformLibrary.cpp # 编译时需要的库
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils # 没有静态库
LOCAL_STATIC_LIBRARIES := # 包含必须的 JNI 头文件
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) # 编译器选项
LOCAL_CFLAGS += # 对该模块不进行预编译。使用预编译可以提高模块的性能。
LOCAL_PRELINK_MODULE := false # 把它编译成动态共享库
include $(BUILD_SHARED_LIBRARY) 该文件主要定义了本地库的名字、依赖、编译选项及编译方式。
e、修改 frameworks/PlatformLibrary/Android.mk,在末尾添加如下两行:
include $(CLEAR_VARS) # 调用子目录中的 make 文件。
include $(call all-makefiles-under,$(LOCAL_PATH))
f、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加该 JNI 本地库。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni
g、编译即可。至此,添加 JNI 库完毕。
4、添加接下来我们再看看如何添加原生应用程序
添加原生应用程序就很简单了,只需要把按照 Android 应用开发的基本方法,写好一个应用,该应用可以依赖这个扩展,也可以不依赖。如 sample 中的 client 应用,目录结构如下: apps/client/
├── AndroidManifest.xml
├── Android.mk
└── src
└── com
└── example
└── android
└── platform_library
└── client
└── Client.java
a、在应用根目录中添加一个 Android.mk 文件,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := user # 目标名称
LOCAL_PACKAGE_NAME := PlatformLibraryClient # 只编译这个apk包中的java文件
LOCAL_SRC_FILES := $(call all-java-files-under, src) # 使用当前版本的 SDK
LOCAL_SDK_VERSION := current # 依赖使用刚才编写的扩展
LOCAL_JAVA_LIBRARIES := com.example.android.platform_library include $(BUILD_PACKAGE)
b、在 AndroidManifest.xml 中添加一句:
<uses-library android:name="com.example.android.platform_library" />
c、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加该 JNI 本地库。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni \
PlatformLibraryClient
d、编译即可。至此,添加 JNI 库完毕。
5、其他功能如添加皮肤等,这里就不一一示范了,请参考<sdk-src>/vendor/sample。