扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。例如,你不需要在你的Android.mk中列出头文件和依赖文件。NDK编译系统将会为你自动处理这些问题。这也意味着,在升级NDK后,你应该得到新的toolchain/platform支持,而且不需要改变你的Android.mk文件。
我们提供的服务有:成都网站设计、网站建设、外贸网站建设、微信公众号开发、网站优化、网站认证、宁陵ssl等。为上千多家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的宁陵网站制作公司
先看一个简单的例子:一个简单的"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)
方向盘左下方有一个可调节的旋转开关,就是大灯高度调节开关。现在,又有一款内置安卓系统的USB便携电脑Android 4.0 mini PC面世,即Zero Devices Z900。
MK802另一个型号名是Z802,而Zero Devices这次推出的Z900就是MK802的升级版,其他方面,Zero Devices Z900采用独特的外壳设计,内置512MB内存和4GB存储空间。
提供microSD卡插槽和HDMI、USB、mini USB接口尺寸为89×32×18毫米,重量为38克。
Zero Devices Z900将运行Android 4.0冰淇淋三明治系统,如果你需要,还可以刷Android 2.3甚至是Linux系统,和MK802一样,用户可以通过HDMI接口连接外置显示器,再通过USB接口连接鼠标或键盘。
至于Z900的上市时间和价格,暂时还没有消息,不过将有黑白两色选择。
Z9002022款大灯高度调节
前照灯高度调节旋钮通常位于仪表板的左侧和灯光控制开关的一侧旋钮上一般有0到3的数字,数字越高,高度越低大多数情况下,0的位置就可以了。
0为初始位置和水平高度,适用于前排有人,行李空装载的情况1-3档适用于车满行李满的情况。
大灯高度可调一般车内有一个手动调节旋钮,可以随意调节大灯的照明高度,但有些高端豪华车的大灯是自动水平调节的。
对于大灯高度自动调节的车辆,车身会配备多个传感器,可以检测车辆的动态平衡,并根据预设程序调节光束角度,但同时也有一定的局限性,不能根据实际需要改变,需要人工干预。
变量
1
LOCAL_PATH := $(call my-dir)
1、解释 LOCAL_PATH:
英文:如下图
中文:Android.mk 开始必须定义变量 LOCAL_PATH,它用来指定源文件的位置
2、解释 my-dir:
英文:如下图
中文:编译系统提供的'my-dir'宏函数,被用来获取当前的目录。
2
include $(CLEAR_VARS)
1、解释 CLEAR_VARS:
英文:如下图
中文:编译系统提供CLEAR_VARS变量,它指向了一个用来清除 LOCAL_ 开头的变量(LOCAL_PATH除外)的makefile文件,需要它的原因是整个的编译上下文中,所有的变量都是全局的,这样就可以保证这些变量只在局部范围内起作用;
3
LOCAL_MODULE := hello-jni
1、解释 LOCAL_MODULE:
英文:如下图
中文:每一个android.mk文件中都必须定义一个模块标示 LOCAL_MODULE , 这个名字必须是唯一的并且不包含任何的空格,编译系统将自动的修改生成文件的前缀和后缀,如一个模块为'foo'共享库将被改为'libfoo.so';
重要提示,如果你的模块名为'libfoo',编译系统生成的文件为 'libfoo.so', 而不会去再增加前缀,当你使用的时候,android平台会自动识别;
4
LOCAL_SRC_FILES := hello-jni.c
1、解释 LOCAL_SRC_FILES
英文:如下图
中文:LOCAL_SRC_FILES必须包含一系列的C/C++源文件,他们将会被建立和装载到模块中,注意你不应该把需要包含的头文件列在这里,因为建立系统将自动计算依赖项,只有源文件才能够被编译器识别;
2、解释 LOCAL_CPP_EXTENSION
英文:如下图
中文:注意默认的c++文件扩展名是'.cpp', LOCAL_CPP_EXTENSION可以用来指定不同类型的扩展名,不要忘了前面的点(如:'.cxx' 将起作用, 但是 'cxx'不会起作用).
如:LOCAL_CPP_EXTENSION := .cc .cpp
5
include $(BUILD_SHARED_LIBRARY)
1、解释 BUILD_SHARED_LIBRARY
英文:如下图
中文:‘建立系统’提供个变量 BUILD_SHARED_LIBRARY, 将根据在‘include’之前定义的所有的信息和LOCAL_前缀的变量,决定将建立什么,如何正确的生成共享库;
2、解释 BUILD_STATIC_LIBRARY
英文: 如下图
中文: 同上,只不过它生成的是静态库
6
LOCAL_C_INCLUDES := $(NDK_ROOT)/sources/third_party/freetype
1、解释 NDK_ROOT
中文:NDK_ROOT 代表的是ndk的根目录,如我的是“D:\Android\android-ndk-r10”,这个例子是用来加载ndk根目录下的freetype的头文件路径;
7
LOCAL_LDFLAGS := \
$(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libfreetype.a
1、解释 LOCAL_LDFLAGS
中文:用来加载用户自己的静态库(.a文件)
2、解释 TARGET_ARCH_ABI
中文:当前的cpu/abi的类型,在链接不同类型的CPU_ABI时非常有用,如下图
8
$(call import-add-path,$(LOCAL_PATH)/libsrc)
1、解释:import-add-path
中文:增加自己的路径到 NDK_MODULE_PATH 环境变量中,再非ndk根目录/sources下编译时会用到
9
LOCAL_SRC_FILES := hello-jni.c HelloJni.cpp
$(error $(LOCAL_SRC_FILES))
1、解释:$
中文:变量前面加上"$"用来返回变量的值
2、解释:$(error string)
中文:用来将string所对应的内容打印到控制台,并且android.mk文件停止继续进行编译,如下图
10
LOCAL_SRC_FILES := hello-jni.c HelloJni.cpp
$(warning $(LOCAL_SRC_FILES))
1、解释:$(warning string)
中文:用来将string所对应的内容打印到控制台,并且android.mk文件将继续进行编译,如下图
11
LOCAL_PRELINK_MODULE := false
1、解释 LOCAL_PRELINK_MODULE:
中文:关闭编译器链接前进行代码优化,防止将没有用到的代码不添加到生成的库中
12
LOCAL_EXPORT_CFLAGS := -DFOO=1
1、解释 LOCAL_EXPORT_CFLAGS
定义这个变量来记录一些列的 c/c++编译标志,他们将会增加到其他的使用这个模块的LOCAL_CFLAGS中,LOCAL_CFLAGS的功能相当于:LOCAL_STATIC_LIBRARIES 和 LOCAL_SHARED_LIBRARIES 这两个变量;
13
LOCAL_STATIC_LIBRARIES := foo
1、解释 LOCAL_STATIC_LIBRARIES
链接进来一个静态库的模块,这里是静态库的模块的名称,而不是静态库的名称
14
LOCAL_SHARED_LIBRARIES
链接进来一个动态库的模块,这里是动态库的模块的名称,而不是静态库的名称
15
LOCAL_EXPORT_CPPFLAGS
跟 LOCAL_EXPORT_CFLAGS 的功能一样,但是它只能够在c++中使用
16
LOCAL_EXPORT_C_INCLUDES
跟 LOCAL_EXPORT_CFLAGS,但是对于c的 include路径,被调用模块申明后,使用模块可以很方便的使用包含的路径
17
LOCAL_EXPORT_LDFLAGS
跟LOCAL_EXPORT_CFLAGS的作用一样,但是仅仅是链接选项
18
LOCAL_EXPORT_LDLIBS
跟LOCAL_EXPORT_CFLAGS的作用类似,但是这个变量说明的系统库,需要带上 '-l' 前缀,他们将导入链接器选项,并追加到你的模块的 LOCAL_LDLIBS
19
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
允许未定义的符号
20
LOCAL_CFLAGS
.c文件对应的编译标记变量
21
LOCAL_LDLIBS
用来链接共享库(so)或者执行文件,使用系统的库文件的时候,需要加上前缀 '-l',例如下面的例子,将告诉连接器生成的模块的时候同时链接 /system/lib/libz.so
LOCAL_LDLIBS := -lz
注意:如果你在一个模块中链接一个静态库,这个静态库是不会起作用的,同时ndk-build 会打印出一条警告消息
22
LOCAL_CFLAGS := -fvisibility=hidden
隐藏库函数名
23
LOCAL_PROGUARD_ENABLED默认是打开的,不特别指定的话,就是起作用的,就可能做优化。
LOCAL_PROGUARD_ENABLED:= disabled
在Linux下,可以通过Makefile来对源码工程进行管理,Android.mk文件是Makefile的一小部分,它用来对Android程序进行编译。Android.mk文件中描述了哪些C文件将被编译且指明了如何编译。Android.mk文件用来告知NDK Build 系统关于Source的信息。
1、编译可执行程序
2、编译动态库或静态库
3、预编译文件(APK或Java库)
以上三种是Android.mk的主要用法,我们写mk文件时也就是以上三种目的。
首先看一个最简单的Android.mk的例子:
讲解:
每个Android.mk文件必须以定义 LOCAL_PATH 为开始。它用于在开发tree中查找源文件。
宏 my-dir 由Build System提供。返回包含Android.mk的目录路径。
CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理 LOCAL_PATH .
这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
LOCAL_MODULE 模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。
Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so.
但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。
LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码。
不必列出头文件,build System 会自动帮我们找出依赖文件。
缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION。
BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。
它负责收集自从上次调用include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。
BUILD_STATIC_LIBRARY:编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE:编译为Native C可执行程序
BUILD_PACKAGE(既可以编apk,也可以编资源包文件,但是需要指定LOCAL_EXPORT_PACKAGE_RESOURCES:=true)
BUILD_JAVA_LIBRARY(Java共享库)
BUILD_STATIC_JAVA_LIBRARY(java静态库)
Android源码中有大量的mk文件,Android系统的编译就是靠着这些mk文件的,所以学好是非常有必要的哦!
当你需要使用JNI的时候,你需要创建一个native工程。Android.mk就是一个makefile配置文件,帮你把C/C++的代码编译成动态库so的。
创建的方式有两种:
在工程根目录里手动创建一个目录叫jni,在里面新建一个Android.mk,然后创建c,cpp文件,把他们配置到Android.mk里。
右键工程,选择Android Tools-Add Native Support自动生成。
扩展资料:
创建Android库
Android 库在结构上与 Android 应用模块相同。可以提供构建应用所需的一切内容,包括源代码、资源文件和 Android 清单。
不过,Android 库将编译到可以用作 Android 应用模块依赖项的 Android 归档 (AAR:Android Archive Resource) 文件,而不是在设备上运行的 APK。
与 JAR 文件不同,AAR 文件可以包含 Android 资源和一个清单文件,这样,除了 Java 类与方法外,还可以捆绑布局和可绘制对象等共享资源。
库模块在以下情况下非常有用:
构建使用某些相同组件(例如 Activity、服务或 UI 布局)的多个应用。
构建存在多个 APK 变体(例如免费版本和付费版本)的应用并且需要在两种版本中使用相同的核心组件。
参考资料来源:百度百科-Android
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流