❶ 如何在windows上用ndk交叉编译其他平台程序
目标 :编译arm64的.so库
编译方法:理论上应该有两种交叉编译方法,法一,在linux服务器上安装交叉工具链,直接用交叉工具链进行编译链接;法二,使用ndk完成交叉编译,因为
ndk已经安装好交叉编译工具链,以及相关的系统库和系统头文件了。这两种方法的区别在于,linux服务器上的编译使用的makefile和ndk使用的.mk
文件显然不同。原因是ndk作为一个集成编译环境,制定了一套特定的规则用于生成最终的编译脚本。
这里简单总结下,如何在windows用ndk进行交叉编译arm64目标平台的.so库:
step1:找到ndk开发工具包,官网之类的都可以下载,android-ndk64-r10-windows-x86_64.rar文件
step2:解压上述ndk工具包,将包含程序源文件和头文件的文件夹testProject都放入android-ndk-r10下的samples目录下。
放在其他地方当然也可以,但是后续相对路径之类的不太好加,既然其他例子都放这,把代码放这编译是最保险的了。
step3:在testProject中增加一个jni的文件夹,必须要添加!!!!!!
step4:在jni文件夹中,添加一个Android.mk的文件,必须要添加!!!!!
step5:在jni文件夹中,添加一个Application.mk的文件与Android.mk并列,必须要添加!!!!!
step6:Android.mk和Application.mk合起来就类似于linux环境下的makefile编译文件。
如何写Android.mk,可以参考例子helllo-jni中jni文件夹下的Android.mk。
LOCAL_PATH:=$(call my-dir) #必须要写的
include $(CLEAR_VARS) #必须要写的
LOCAL_MODULE:=hello-jni #编译出来的模块名称
LOCAL_SRC_FILES:=hello-jni.c #制定编译的源文件名称
include $(BUILD_SHARED_LIBRARY)#放在最后
除了上述变量之外,还有其他的指定的变量,
LOCAL_CFLAGS,用于指定编译选项,这个和makefile中是完全一样的,可以指定编译选项-g,也可以指定编译宏及宏值
LOCAL_LDLIBS,用于指定链接的依赖库,这个可以makefile也是完全一样的,可以指定链接库用-l库名,以及指定库搜索路径用_L路径名
LOCAL_STATIC_LIBRARIES,指定链接的静态库名,makefile中没有
LOCAL_C_INCLUDES,用于指定编译头文件的路径,和makefile中不同,路径前不需要加-I,直接写路径即可,可以是相对路径或绝对路径,
多个路径之间用空格隔开。
编写上述Android.mk碰到的问题有,
(1)使用默认的系统自动加载stl库头文件总是出错,只好手动在LOCAL_STATIC_LIBRARIES指定sources/cxx-stl/stlport/stlport来完成对#include<string>这种c++形式的头文件加载
(2)使用$(SYSROOT)/usr/include来完成对系统库头文件的加载,结果找不到sem_t符号,只好指定platforms/android-L/arch-arm64/usr/include
step7:Application.mk编写
APP_STL指定使用的stl移植库,动态或者静态都行
APP_CPPFLAGS,指定app编译的编译选项
APP_ABI指定abi规范类型,例如arm64-v8a,也可以写成ALL就是把所有的类型全部编一编
APP_PLATFORM指定编译的platform名称,这里可以写成android-L或者不指定全编。
step8:编译完成后,运行。
启动cmd,使用cd /D进行到testProject的jni目录下
step9:将android-ndk-r10下的ndk-build.cmd直接拖拽到cmd中,此时直接敲回车,就可以编译了。当然也可以加一个 clean,清除编译中间文件。
step10:检查下编译结果,编译成功后在testProject中多了两个文件夹与jni并列的,libs和obj。
编译链接后的结果就在libs中!
❷ Android NDK到底能做哪些有趣的事情
NDK全称Native Development Kit,因而NDK本身主要是一套工具链。NDK里面包含了交叉编译、链接、调试等的工具,以及一些比较基本的函数库,如STL、标准C库等,一些图形的glue接口等,还有JNI的一些机制。
感觉题主所称的NDK在实际的NDK之外,似乎还包含JNI机制和C/C++编程语言。
JNI是一种让Java层代码和C/C++层代码可以相互调用的机制,也就是Java层代码可以调用C/C++,反过来也可以。不仅仅是Android开发可以用JNI这种机制,普通的PC机上的JAVA开发也可以用这种机制。
在Android app开发中使用C/C++语言,如同其他朋友所言,能带来的好处很多,如利用遗留的相关库,访问底层操作系统接口等等。C/C++是这种开发中的核心。
至于说到有没有必要,当然是具体看情况了。如果Android的Java层开发的知识的积累还非常少,当然应该先积累这方面的东西。对于许多对性能要求比较苛刻的应用领域,如其他朋友提到的音视频编解码,还有游戏的图形什么的使用NDK写一些C/C++代码可能比较好。要看别人优秀的使用了JNI机制和C/C++的开源项目,学一下一定是很有帮助的。
学习方法嘛,主要是分成NDK工具、JNI和 C/C++编程语言3个部分来看。
C/C++编程语言,自不必多说,和常规的 C/C++编程语言又没有什么特别的地方,主要的差别可能也就在可用的函数库等方面了。
JNI的话,有一份叫 《The Java Native Interface Programmer's Guide and Specification》的文档非常好,比较清楚的讲解了Java代码如何与C/C++代码相互访问的方法。
至于NDK,可以参考NDK自带的文档,或者android aosp项目中来了解如何编写Android.mk。 参考NDK自带的文档来了解如何编译,链接,调试,如何编写Application.mk,如何使用STL等。还可以搜一下如何把NDK集成进自己使用的IDE中,如Eclipse,Android Studio等等。
❸ 如何将debug版本的so库变成release版本
由于Smart_Gis安卓客户端的需要,所以需要把gdal_2.3.1库编译成安卓平台Arm64_v8a版本的.so库。由于要求是Android NDK版本 12以上,Android API 21以上的支持。
所以在本次编译过程中全部需要使用64位的操作系统,NDK及编译器,编译环境为 操作系统:Ubuntu 16.04 LTS,安卓NDK版本:android-ndk-r14b,geos, proj。
1,最近遇到了之前编译的geos, proj, skia, gdal库都为debug版本,本人也没有特意的去验证,但是由于项目上线发布的原因,需要将所有的依赖的库发布成release版本的,一来可以增加库的稳定性,二来可以减小体积。
2,由于 gdal 库在编译成release版本的过程中可以参考我的gdal库安卓平台编译这篇文章,并在Application.mk文件里面增加 APP_OPTIM := release 然后 ndk-build命令进行编译就行了,如何验证生成的库是不是debug版本的呢?
在库目录下执行 readelf -S + 文件名 ,在打印出的信息中如果能查看到有debug字符即是debug版本。
3,到这一步我们需要找到我们打开我们编译的工具链的位置,找到strip这个可执行程序,比如说 GCC存储目录或者本人的Android 交叉编译工具链的位置。然后找到存储.so库的目录下并复制当前目录加上需要裁剪的库名到工具链strip存放目录下,
如下图所示并回车。
4,再次查看SO库并会发现该库的体积缩小了很多,并使用readelf -S + 库名打印出来的信息没有debug字符。
❹ 怎么查看Android编译时候交叉编译链工具位置
经常搞嵌入式开发的朋友对于交叉编译环境应该并不陌生,说白了,就是一组运行在x86 PC机的编译工具,可以让你在PC机上编译出目标平台(例如ARM)可识别的二进制文件。Android平台也提供了这样的交叉编译工具链,就放在Android的NDK开发包的toolchains目录下,因此,我们的Makefile文件中,只需给出相应的编译工具即可。
废话就先说到这,直接上例子,我们目标是把下面这个math.c文件编译成一个静态库文件:
#include <stdio.h>
int add( int a , int b ) {
return a+b;
}
你需要编写一个Makefile文件,这里假设你的Android ndk被安装在 /opt/android/ndk 目录下,当然,你可以根据自己的实际情况修改Makefile中相关路径的定义,Makefile文件示例如下:
# Makefile Written by ticktick
# Show how to cross-compile c/c++ code for android platform
.PHONY: clean
NDKROOT=/opt/android/ndk
PLATFORM=$(NDKROOT)/platforms/android-14/arch-arm
CROSS_COMPILE=$(NDKROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar
LD=$(CROSS_COMPILE)ld
CFLAGS = -I$(PWD) -I$(PLATFORM)/usr/include -Wall -O2 -fPIC -DANDROID -DHAVE_PTHREAD -mfpu=neon -mfloat-abi=softfp
LDFLAGS =