❶ 如何在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 =