androidmk语法

官方文档-ndk相关的都在这个网站上

https://developer.android.google.cn/ndk/guides/android_mk.html

问题

1 为什么会有Android.mk 和Application.mk 这两个分别是什么?

2 nkd怎样运行hello C语言程序?自己试了好久没有好使。

3 ndk-build 参数选项都有什么

ndk-build NDK_PROJECT_PATH=iu456_library/build/  NDK_APPLICATION_MK=Application.mk APP_DIR:=${APP_DIR}

NDK_PROJECT_PATH 指定了需要编译的代码的工程目录,这里给出的是当前目录,

APP_BUILD_SCRIPT给出的是Android makefile文件的路径

Application.mk详解

Application.mk简介

​ 要将C/C++代码编译为so文件,光有Android.mk文件还不行,还需要一个Application.mk文件。本文将对Application.mk进行非常详细介绍。

1.作用

​ Application.mk是用来确定一些编译规则的,它规定的不是某一个文件某一行代码,而是所有文件相关

2.存放位置

Application.mk和Android.mk是放在同一个目录下的。一般是放在src/main/jni/下jni是新建的文件夹,用于存放C/C++相关的代码,jni文件夹和java文件夹是同级目录,如果生成的.so也是在/main下创建文件夹jniLibs,把.so放在jniLibs文件夹下。

Application.mk写法用法

Application.mk的写法:

key1 := value1
key2 := value2
key3 := value3

Application.mk文件中里面全都是标签key和值value来定义一些属性的,所有我们只需要看懂里面标签的意义就知道整个Application.mk的用法了。比如APP_ABI,是用来确定编译成什么样处理器平台下的so文件。

1.最简单的文件格式:

#注释:注解*****
APP_ABI := arm64-v8a #  APP_ABI :=后面接的是需要生成的.so平台文件,正常手机使用arm64处理器的即可。
APP_PLATFORM := android-21 # APP_PLATFORM :=后面接的是使用SDK的最低等级 

Application.mk的所有标签详解

标签书写的次序是无序的。

APP_PLATFORM(必选项)

作用:定义使用的ndk库函数版本号。

属性值可以是: android-,其中是ndk的版本。

一般和SDK的版本(minSdkVersion 21)相对应,NDK版本的各个版本在NDK目录(sdk\ndk-bundle\)下的platforms文件夹中

APP_ABI (必选项)

作用:编译成什么类型的cpu的so,

拥有三个属性值armeabi armeabi-v7a x86,可以只用一个,也可以可以全选,如果全选也可以使用all.

写法可以是:

中间要变成的多个so版本用空格间隔开即可

生成两种格式

APP_ABI := armeabi-v7a arm64-v8a
APP_ABI := all 全选

关于三种cpu处理器的介绍:

目前主流的Android设备是armeabi-v7a架构的,然后就是x86和armeabi了。
如果同时包含了 armeabi,armeabi-v7a和x86,所有设备都可以运行,程序在运行的时候去加载不同平台对应的so,这是较为完美的一种解决方案,但是同时也会导致包变大。
armeabi-v7a是可以兼容armeabi的,而v7a的CPU支持硬件浮点运算,目前绝大对数设备已经是armeabi-v7a了,所以为了性能上的更优,就不要为了兼容放到armeabi下了。
x86也是可以兼容armeabi平台运行的,另外需要指出的是,打出包的x86的so,总会比armeabi平台的体积更小,对于性能有洁癖的童鞋们,还是建议在打包so的时候支持x86。

#####关于使用哪种cup的问题
如果功能简单,并且希望自己的apk小一点,编一个x86版本的so即可。
如果想为了适应所有机型可以添加一下armeabi-v7a的版本。

一般来说正常手机使用x86版本的即可,
对于模拟器的话,就要看创建模拟器设置的cpu类型了。如果不确定模拟器的cpu类型,就生成多个so库即可。

APP_STL (非必选项)

作用:如何连接c++标准库 。
属性值:
stlport_static 静态链接
stlport_shared 动态链接
system 系统默认

如果生成的so库包含静态.a文件,这个属性要写成stlport_static,否则可以不用写。

APP_OPTIM (非必选项)

编译版本,如果是DEBUG版本就会带上调试信息。可以使用gdb-server进行动态断点低调试。
debug 调试版本 so中带调试信息,
release(默认) 发布版本 so不带调试信息

正常情况不用写这个属性就可以了,如果需要进行断点调试的情况可以设置为debug。

代码详解

APP_PLATFORM := android-24  # 定义使用的ndk库函数版本号。
APP_OPTIM := release  # release(默认) 发布版本 so不带调试信息
APP_STL := c++_static
NDK_TOOLCHAIN_VERSION := clang
APP_BUILD_SCRIPT := Android.mk

# the buildsystem and validation is only done on these architectures
APP_ABI := armeabi-v7a arm64-v8a

# needed because VNKD needs liblog declared but in NDK it is implicit
APP_ALLOW_MISSING_DEPS := true

其他标签

它是Android NDK构建系统使用的一个可选的构建文件,也是一个GNU Makefile片段下面是Application.mk构建文件支持的变量:

APP_MODULES:默认情况下,Android NDK构建系统构建Android.mk文件声明的所有模块。
该变量可以覆盖上述行为并提供一个空格分开的,需要被构建的模块列表

APP_OPTIM:该变量可以设置为release和debug来改变生成的二进制文件的优化级别,
默认为release模式。

APP_CLAGS:列出编译器标识,在编译任何模块的C和C++源文件时这些标志都会被传给编译器

APP_CPPFLAGS:列出编译器标识,在编译任何模块的C++源文件时这些标志都会被传给编译器

APP_BUILD_SCRIPT:默认情况下,Android NDK构建系统在项目的JNI子目录下查找Android.mk构建文件。

APP_CFLAGS

编译选项

可以在Application.mk文件中修改此编译选项参数,此参数可以覆盖Android.mk文件中的相同定义,从而不必去Android.mk文件中修改.

需要注意地是,这个选项里的路径必须是以顶层NDK目录为相对路径,如存在以下两个文件:

sources/foo/Android.mk

sources/bar/Android.mk

如果在foo/Android.mk文件中想要添加bar目录,那么得这样便用:

APP_CFLAGS += -Isources/bar

如果这样使用:**
**

APP_CFLAGS += -I$(LOCAL_PATH)/../bar

将会变成’-I$NDK_ROOT/…/bar’,从而出现并不是你想要的结果.

在android-ndk-1.5_r1时,此选项中只在C代码中被支持,而C++不支持,不过现在已经被纠正了.

**

**

之前的是项目中遇到的一些知识点,下面的是我整理的比较全面的application.mk知识点。

在Application.mk文件内定义了一些变量:
(1)APP_PROJECT_PATH(非必须
此变量值必须是你工程根目录的绝对路径.这用于指定JNI生成的.so文件安装路径或拷贝路径.
(2)APP_MODULES
此变量是可选的,如果没有在此文件中定义,则默认由Android.mk文件决定.
如果在Application.mk文件中定义此变量,那么它必须是一串由空格相隔的模块名列表,并且与Android.mk文件中的LOCAL_MODULE变量定义保持一致.需要注意地是,NDK会自动计算模块所需要的依赖文件。
注:此变量在NDK R4版本之前是在Application.mk中是必须的,所有模块必须显式地列出.
(3)APP_CXXFLAGS
APP_CPPFLAGS的别名,将来此变量将会被抛弃。
(4)APP_CPPFLAGS
C++代码的编译选项。在android-ndk-1.5_r1版本中,此变量只适用于C++,但是现在可以同时适用于C和C++。

(5)APP_BUILD_SCRIPT
在默认情况下,NDK会在jni目录下查找Android.mk文件并使用它,如果你想修改它,那么在此变量中你可以指定一个你自己的脚本来执行,路径还是以工程顶层目录为相对路径.

(6)APP_GNUSTL_FORCE_CPP_FEATURES
在先前的NDK版本中,当使用GNU libstdc++ runtime运行库(通过设置APP_STL变量为gnustl_static或gnustl_shared)都会强制支持异常和RTTI,在有些极少情况下可能会出现问题,同时会使生成的机器码包含不必须的内容。
这种问题在NDK r7b中得到解决,但是这也意味着如果你真的需要支持异常和RTTI 的话,则必须显式声明。要么通过APP_CPPFLAGS,要么通过LOCAL_CPPFLAGS,或LOCAL_CPP_FEATURES。本变量就是为了解决此问题的.
有两个选项供选择,也可同时都选择.

官方文档

https://developer.android.google.cn/ndk/guides/application_mk

Application.mk文件

简介:
-----------------------------
要将C\C++代码编译为SO文件,光有Android.mk文件还不行,还需要一个Application.mk文件。
本文档是描述你的Android应用程序中需要的本地模块的Application.mk的语法使用,要明白如下。

Application.mk目的:

​ 是描述在你的应用程序中所需要的模块(即静态库或动态库)。

Application.mk文件通常被放置在 P R O J E C T / j n i / A p p l i c a t i o n . m k 下 , PROJECT/jni/Application.mk下, PROJECT/jni/Application.mkPROJECT指的是您的项目。

另一种方法是将其放在顶层的子目录下:

$NDK/apps目录下,例如:
$NDK/apps/<myapp>/Application.mk

<myapp>是一个简称,用于描述你的NDK编译系统的应用程序(这个名字不会生成共享库或者最终的包)

下面是Application.mk中定义的几个变量。

APP_PROJECT_PATH

这个变量是强制性的,并且会给出应用程序工程的根目录的一个绝对路径。这是用来复制或者安装一个没有任何版本限制的JNI库,从而给APK生成工具一个详细的路径。

APP_MODULES

这个变量是可选的,如果没有定义,NDK将由在Android.mk中声明的默认的模块编译,并且包含所有的子文件(makefile文件)
如果APP_MODULES定义了,它不许是一个空格分隔的模块列表,这个模块名字被定义在Android.mk文件中的LOCAL_MODULE中。注意NDK会自动计算模块的依赖

注意:NDK在R4开始改变了这个变量的行为,再次之前:
- 在您的Application.mk中,该变量是强制的
- 必须明确列出所有需要的模块

APP_OPTIM–

这个变量是可选的,用来定义“release”或"debug"。在编译您的应用程序模块的时候,可以用来改变优先级。

“release”模式是默认的,并且会生成高度优化的二进制代码。"debug"模式生成的是未优化的二进制代码,但可以检测出很多的BUG,可以用于调试。

注意:如果你的应用程序是可调试的(即,如果你的清单文件中设置了android:debuggable的属性是"true")。默认的是"debug"而不是"release"。这可以通过设置APP_OPTIM为"release"来将其覆盖。

注意:可以在"release"和"debug"模式下一起调试,但是"release"模式编译后将会提供更少的BUG信息。在我们清楚BUG的过程中,有一些变量被优化了,或者根本就无法被检测出来,代码的重新排序会让这些带阿弥变得更加难以阅读,并且让这些轨迹更加不可靠。

APP_CFLAGS

当编译模块中有任何C文件或者C++文件的时候,C编译器的信号就会被发出。这里可以在你的应用中需要这些模块时,进行编译的调整,这样就不许要直接更改Android.mk为文件本身了

重要警告:+++++++++++++++++++++++++++++++++++++++++++++++ + +
+
+ 在这些编制中,所有的路径都需要于最顶层的NDK目录相对应。
+ 例如,如果您有以下设置:
+
+sources/foo/Android.mk
+sources/bar/ Android.mk
+ 编译过程中,若要在foo/Android.mk中指定你要添加的路径到bar源代码中,
+ 你应该使用
+ APP_CFLAGS += -Isources/bar
+ 或者交替:
+ APP_CFLAGS += -I KaTeX parse error: Undefined control sequence: \+ at position 24: …ATH )/../bar + \̲+̲ 使用'-l../bar/'将…NDK_ROOT/…/bar"

++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++

注意:在Android的NDK 1.5_r1,只适用于C源文件,而不适合C++。
这已得到纠正,以建立完整相匹配的Andr​​oid系统。

APP_CXXFLAGS
APP_CPPFLAGS的别名,已经考虑在将在未来的版本中废除了

APP_CPPFLAGS
当编译的只有C++源文件的时候,可以通过这个C++编译器来设置

注意:在Android NDK-1.5_r1中,这个标志可以应用于C和C++源文件中。并且得到了纠正,以建立完整的与系统相匹配的Android编译系统。你先可也可以使用APP_CFLAGS来应用于C或者C++源文件中。
建议使用APP_CFLAGS

APP_BUILD_SCRIPT–

默认情况下,NDK编译系统会在$(APP_PROJECT_PATH)/jni目录下寻找名为Android.mk文件:
$(APP_PROJECT_PATH)/jni/Android.mk

如果你想覆盖此行为,你可以定义APP_BUILD_SCRIPT来指定一个备用的编译脚本。一个非绝对路径总是被解释为相对于NDK的顶层的目录。

APP_ABI–

默认情况下,NDK的编译系统回味"armeabi"ABI生成机器代码。喜爱哪个相当于一个基于CPU可以进行浮点运算的ARMv5TE。你可以使用APP_ABI来选择一个不同的ABI。

比如:为了在ARMv7的设备上支持硬件FPU指令。可以使用
APP_ABI := armeabi-v7a

或者为了支持IA-32指令集,可以使用
APP_ABI := x86

或者为了同时支持这三种,可以使用
APP_ABI := armeabi armeabi-v7a x86

APP_STL–

默认情况下,NDK的编译系统为最小的C++运行时库(/system/lib/libstdc++.so)提供C++头文件。
然而,NDK的C++的实现,可以让你使用或着链接在自己的应用程序中。
例如:
APP_STL := stlport_static --> static STLport library
APP_STL := stlport_shared --> shared STLport library
APP_STL := system --> default C++ runtime library

下面是一个Application.mk文件的示例:
APP_PROJECT_PATH :=

android.mk

一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器–包括 Windows NT 下的编译器–维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

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 :=  HcSyncml
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包 含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'HcSyncml'的共享库模块,将会生成'libHcSyncml.so'文件。

LOCAL_C_INCLUDES := $(LOCAL_PATH)/extra_inc$(LOCAL_PATH)/main_inc
LOCAL_C_INCLUDES 中加入所需要包含的头文件路径

LOCAL_SRC_FILES
LOCAL_SRC_FILES中加入源文件路径(需要编译的文件),多个文件用 ‘\’ 隔开

LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib –llog
表示允许打印Log

在Android.mk里面打印一句话:

$(warning 'hehe fuck=================')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值