當前位置:首頁 » 編程軟體 » ndk編譯

ndk編譯

發布時間: 2022-01-26 01:49:44

『壹』 android開發,怎麼使用ndk編譯成.so文件

一、首先下載android-ndk,官方網站是:http://developer.android.com/tools/sdk/ndk/index.html
目前最新的版本是android-ndk-r8e-windows-x86.zip,下載地址:
http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86.zip
下載後把壓縮解壓出來,例如:D:\ndk,目錄下的ndk-build.cmd就是用來編譯的批處理命令。
二、編譯,打開cmd命令行窗口,cd進入目錄:D:\ndk\samples\hello-jni,
然後執行命令:D:\ndk\ndk-build.cmd(如果設置過環境變數則直接使用ndk-build.cmd)來編譯hello-jni,如果沒有錯誤會輸出:
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
三、創建android應用程序並使用so文件
打開eclipse創建一個android應用程序HelloJni,默認的com.example.hellojni包下面有一個MainActivity.java
在此包下添加一個HelloJni.java,

『貳』 如何把ndk編譯出來的可執行文件偽裝成s

ndk編譯出來的共享庫,eclipse會自動打包到apk中,而編譯出來的可執行文件則不會。 要想可執行文件自動被打包到apk中,可以把文件名改成libxxx.so的形式,偽裝成so,這樣就會被打包進apk。 但是每次編譯之後都改一下名字,太麻煩!

『叄』 ndk-Android NDk 怎麼編譯時動態鏈接第三方so庫,有頭文件

問題描述:Android如何調用第三方SO庫;
已知條件:SO庫為Android版本連接庫(*.so文件),並提供了詳細的介面說明;
已了解解決方案:
1.將SO文件直接放到libs/armeabi下,然後代碼中System.loadLibrary("xxx");再public native static int xxx_xxx_xxx();接下來就可以直接調用xxx_xxx_xxx()方法;
2.第二種方案,創建自己的SO文件,在自己的SO文件里調用第三方SO,再在程序中調用自己的SO,這種比較復雜,需要建java類文件,生成.h文件,編寫C源文件include之前生成的.h文件並實現相應方法,最後用android NDK開發包中的ndk-build腳本生成對應的.so共享庫;
求解:
1.上面兩種方案是否可行?不可行的話存在什麼問題?
2.兩種方案有什麼區別?為什麼網上大部都是用的第二種方案?
3.只有一個*.so文件,並提供了詳細的介面說明,是否可在ANDROID中使用它?

首先要看這個SO是不是JNI規范的SO,比如有沒有返回JNI不直接支持的類型。也就是說這個SO是不是可以直接當作JNI來調用。如果答案是否定的,你只能選第二個方案。

如果答案是肯定的,還要看你是不是希望這個SO的庫直接暴露給JAVA層,如果答案是否定的,你只能選第二個方案,比如你本身也是一個庫的提供者。

一般如果你只有SO,就說明這個是別人提供給你的,你可以要求對方給你提供配套的JAVA調用文件。

1、這個要看這個SO是不是符合JNI調用的規范。還要看你自己的意願。
2、因為第二種方法最靈活,各種情況都可以實現。
3、可以

看能不能直接從JAVA調用的最簡單的方法就是看SO里的函數名是不是Java_XXX_XXX_XXX格式的
是就可以,你可以自己寫一個配套的JAVA文件,注意一下SO函數名和JAVA函數名的轉換規則,或者向SO提供方索要;
不是的話就選第二種方案吧。

1、檢查所需文件是否齊全
使用第三方動態庫,應該至少有2個文件,一個是動態庫(.so),另一個是包含
動態庫API聲明的頭文件(.h)
2、封裝原動態庫
原動態庫文件不包含jni介面需要的信息,所以我們需要對其進行封裝,所以我
們的需求是:將libadd.so 裡面的API封裝成帶jni介面的動態
3、編寫庫的封裝函數libaddjni.c
根據前面生成的com_android_libjni_LibJavaHeader.h 文件,編寫libaddjni.c,用
來生成libaddjni.so

Android中集成第三方軟體包(.jar, .so)

Android中可能會用到第三方的軟體包,這包括Java包.jar和Native包.so。jar包既可通過Eclipse開發環境集成,也可通過編譯源碼集成,看你的工作環境。

假定自己開發的程序為MyMaps,需要用到BaiMaps的庫,包括mapapi.jar和libBMapApiEngine_v1_3_1.so。

一、Eclipse中集成第三方jar包及.so動態庫

MyMaps工程下創建目錄libs以及libs/armeabi,把mapapi.jar放在的libs/目錄下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。

Eclipse中把第三方jar包mapapi.jar打包到MyMaps的步驟:

1. 右擊工程,選擇Properties;
2. Java Build Path,選擇Libraries;
3. Libraries頁面點擊右面按鈕「Add Library…」;
4. 選擇「User Library」,點擊「Next」;
5. 點擊「User Libraries」按鈕;
6. 在彈出界面中,點擊「New…」;
7. 輸入「User library name」,點擊「OK」確認;
8. 返回之後,選擇剛剛創建的User library,右面點擊「AddJARs」;
9. 選擇MyMaps/libs/下的mapapi.jar;
10. 確認,返回。

這樣,編譯之後,該jar包就會被打進MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。
程序運行過程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,載入動態庫時系統會從程序的該lib/目錄下查找.so庫。

二、源碼中集成第三方集成jar包及.so動態庫

Android源碼中MyMaps放在packages/apps下。MyMaps下創建目錄libs以及libs/armeabi,並把mapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。

2.1 修改Android.mk文件

Android.mk文件如下:

[plain] view plain
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := libmapapi

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := MyMaps

include $(BUILD_PACKAGE)

##################################################
include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libmapapi:libs/mapapi.jar
LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so
LOCAL_MODULE_TAGS := optional
include $(BUILD_MULTI_PREBUILT)

# Use the following include to make our testapk.
include $(callall-makefiles-under,$(LOCAL_PATH))

1 集成jar包
LOCAL_STATIC_JAVA_LIBRARIES取jar庫的別名,可以任意取值;
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar庫的規則,格式:別名:jar文件路徑。注意:別名一定要與LOCAL_STATIC_JAVA_LIBRARIES里所取的別名一致,且不含.jar;jar文件路徑一定要是真實的存放第三方jar包的路徑。
編譯用BUILD_MULTI_PREBUILT。
2 集成.so動態庫
LOCAL_PREBUILT_LIBS指定prebuilt so的規則,格式:別名:so文件路徑。注意:別名一般不可改變,特別是第三方jar包使用.so庫的情況,且不含.so;so文件路徑一定要是真實的存放第三方so文件的路徑。
編譯拷貝用BUILD_MULTI_PREBUILT。

2.2 加入到GRANDFATHERED_USER_MODULES

在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中

[plain] view plain
GRANDFATHERED_USER_MODULES += \
… \
libBMapApiEngine_v1_3_1

user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推薦修改$(TARGET_DEVICE_DIR)下的。

2.3 編譯結果

MyMaps.apk編譯生成在out/target/proct/<YourProct>/system/app/下;
libBMapApiEngine_v1_3_1.so放在out/target/proct/<YourProct>/system/lib/下,這也是系統載入動態庫時搜索的路徑。

『肆』 Android用NDK和整套源碼下編譯JNI的不同

NDK:
1、包含頭文件
#include <android/log.h>
2、Android.mk中包含庫
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
上面這個一定要,不然出現error: undefined reference to '__android_log_print'
LOCAL_SHARED_LIBRARIES := libdl\
liblog\ #經測試在Eclipse中用NDK編譯可有可無,沒啥用!但在源碼中就必須是他,所以都加上吧!
libpre_AppUpgrade\
libpre_AppArea\
3、在你的jni文件中定義
#define LOGD() __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定義LOGD類型
#define LOGI() __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定義LOGI類型
#define LOGW() __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定義LOGW類型
#define LOGE() __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定義LOGE類型
#define LOGF() __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定義LOGF類型
adnroid4.2源碼中已經將LOGD等都加了一個頭,
#define ALOGD() __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定義LOGD類型
#define ALOGI() __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定義LOGI類型
#define ALOGW() __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定義LOGW類型
#define ALOGE() __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定義LOGE類型
#define ALOGF() __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定義LOGF類型
注意如果你不想在每一個jni文件中都定義上述宏,投機方法即可以定義在:D:\android-ndk-r9d\platforms\android-19\arch-arm\usr\include\android\log.h中!當然這種編譯也只能在你本機上使用啦~
源碼開發:
1、Android.mk中包含庫
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
LOCAL_SHARED_LIBRARIES := libdl\
liblog\ //源碼中開發一定的加上
libpre_AppUpgrade\
libpre_AppArea\
2、包含頭文件#include <utils/Log.h>
3、注意在使用時記得包含庫的頭文件
轉載

『伍』 如何設置NDK的編譯選項

1. 概述

首先回顧一下 Android NDK 開發中,Android.mk 和Application.mk 各自的職責。

Android.mk,負責配置如下內容:

(1) 模塊名(LOCAL_MODULE)

(2) 需要編譯的源文件(LOCAL_SRC_FILES)

(3) 依賴的第三方庫(LOCAL_STATIC_LIBRARIES,LOCAL_SHARED_LIBRARIES)

(4) 編譯/鏈接選項(LOCAL_LDLIBS、LOCAL_CFLAGS)

Application.mk,負責配置如下內容:

(1) 目標平台的ABI類型(默認值:armeabi)(APP_ABI)

(2) Toolchains(默認值:GCC 4.8)

(3) C++標准庫類型(默認值:system)(APP_STL)

(4) release/debug模式(默認值:release)

由此我們可以看到,本文所涉及的編譯選項在Android.mk和Application.mk中均有出現,下面我們將一個個詳細介紹。

2. APP_ABI

ABI全稱是:Application binary interface,即:應用程序二進制介面,它定義了一套規則,允許編譯好的二進制目標代碼在所有兼容該ABI的操作系統和硬體平台中無需改動就能運行。(具體的定義請參考網路或者維基網路)

由上述定義可以判斷,ABI定義了規則,而具體的實現則是由編譯器、CPU、操作系統共同來完成的。不同的CPU晶元(如:ARM、Intel x86、MIPS)支持不同的ABI架構,常見的ABI類型包括:armeabi,armeabi-v7a,x86,x86_64,mips,mips64,arm64-v8a等。

這就是為什麼我們編譯出來的可以運行於Windows的二進製程序不能運行於Mac OS/Linux/Android平台了,因為CPU晶元和操作系統均不相同,支持的ABI類型也不一樣,因此無法識別對方的二進製程序。

而我們所說的「交叉編譯」的核心原理也跟這些密切相關,交叉編譯,就是使用交叉編譯工具,在一個平台上編譯生成另一個平台上的二進制可執行程序,為什麼可以做到?因為交叉編譯工具實現了另一個平台所定義的ABI規則。我們在Windows/Linux平台使用Android NDK交叉編譯工具來編譯出Android平台的庫也是這個道理。

這里給出最新 Android NDK 所支持的ABI類型及區別:

下面是我總結的一些常用的CFLAGS編譯選項:

(1)通用的編譯選項

-O2 編譯優化選項,一般選擇O2,兼顧了優化程度與目標大小

-Wall 打開所有編譯過程中的Warning

-fPIC 編譯位置無關的代碼,一般用於編譯動態庫

-shared 編譯動態庫

-fopenmp 打開多核並行計算,

-Idir 配置頭文件搜索路徑,如果有多個-I選項,則路徑的搜索先後順序是從左到右的,即在前面的路徑會被選搜索

-nostdinc 該選項指示不要標准路徑下的搜索頭文件,而只搜索-I選項指定的路徑和當前路徑。

--sysroot=dir 用dir作為頭文件和庫文件的邏輯根目錄,例如,正常情況下,如果編譯器在/usr/include搜索頭文件,在/usr/lib下搜索庫文件,它將用dir/usr/include和dir/usr/lib替代原來的相應路徑。

-llibrary 查找名為library的庫進行鏈接

-Ldir 增加-l選項指定的庫文件的搜索路徑,即編譯器會到dir路徑下搜索-l指定的庫文件。

-nostdlib 該選項指示鏈接的時候不要使用標准路徑下的庫文件

(2) ARM平台相關的編譯選項

-marm -mthumb 二選一,指定編譯thumb指令集還是arm指令集

-march=name 指定特定的ARM架構,常用的包括:-march=armv6, -march=armv7-a

-mfpu=name 給出目標平台的浮點運算處理器類型,常用的包括:-mfpu=neon,-mfpu=vfpv3-d16

-mfloat-abi=name 給出目標平台的浮點預算ABI,支持的參數包括:「soft」, 「softfp」 and 「hard」

『陸』 如何使用自己的makefile編譯android ndk項目

android ndk提供了一套自己的makefile管理方式,要將源碼項目移植到android平台,需要按照android的makefile規則編寫makefile,還要按android的規則部署源碼目錄,對一個有自己的makefile管理方法的大型項目來說,只是做一下makefile遷移工作就是一件很麻煩的事。
其實android ndk上的編譯說到底也就是交叉編譯,只要配置好交叉編譯工具鏈,使用原有的makefile也是可以編譯出在android運行的c、c++程序的。
以android-ndk-r4-crystax的ndk版本為例:
編譯器路徑 android-ndk-r4-crystax/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin
名稱前綴 arm-eabi-
頭文件目錄 android-ndk-r4-crystax/build/platforms/android-3/arch-arm/usr/include
庫文件目錄 android-ndk-r4-crystax/build/platforms/android-3/arch-arm/usr/lib
你可以試一下上面的配置,如果編譯鏈接都沒有問題,可以adb push到android設備上運行看看,什麼結果?
有點崩潰,根本運行不起來,你也許想試試看android自帶的ndk例子,確實是能夠運行的,問題在哪兒呢?
只是正確配置了編譯器、頭文件、庫文件還不夠,還需要配置編譯、鏈接的參數,android例子中編譯鏈接的參數是什麼呢?你也許想深究一下android的makefile,可是不久你會發現那是更崩潰的事情,裡面用了很多的make腳本函數。其實android的makefile是可以把執行的詳細命令輸出來的,只要make的時候加上V=1即可。可以看到確實帶了很多參數
編譯參數:
-fpic
-mthumb-interwork
-ffunction-sections
-funwind-tables
-fstack-protector
-fno-short-enums
-Wno-psabi
-march=armv5te
-mtune=xscale
-msoft-float
-mthumb
-fomit-frame-pointer
-fno-strict-aliasing
-finline-limit=64
-Wa,--noexecstack
-D__ARM_ARCH_5__
-D__ARM_ARCH_5T__
-D__ARM_ARCH_5E__
-D__ARM_ARCH_5TE__
-DANDROID
鏈接參數:

-nostdlib
-Bdynamic
-Wl,-dynamic-linker,/system/bin/linker
-Wl,--gc-sections
-Wl,-z,noreloc
-Wl,--no-undefined
-Wl,-z,noexecstack
-L$(PLATFORM_LIBRARY_DIRECTORYS)
crtbegin_static.o
crtend_android.o
這其中鏈接參數中的-Wl,-dynamic-linker,/system/bin/linker、crtbegin_static.o、crtend_android.o是最關鍵的,android使用了自己的進程載入器,並且自定義了c運行時的啟動結束。難怪先前編譯的進程啟動不了。

『柒』 ndk-build 怎樣同時編譯多個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)表示編譯成可執行程序

『捌』 android ndk編譯arm-linux平台可執行程序

既然是移植就不能再用原來的Android ndk進行編譯了吧,不能圖省事啊,要移植當然要換編譯環境重新編譯,Android ndk編譯不出arm-linux程序的,要重新寫Makefile也沒辦法呀,還是交叉編譯吧。

熱點內容
陰陽師腳本免費 發布:2024-12-28 03:39:50 瀏覽:21
會務源碼 發布:2024-12-28 03:27:11 瀏覽:190
如何直接用密保手機找回密碼 發布:2024-12-28 03:17:11 瀏覽:576
電腦向伺服器傳文件的工具 發布:2024-12-28 03:05:17 瀏覽:783
編程搶手機 發布:2024-12-28 02:59:44 瀏覽:443
存儲器佔用多少位元組 發布:2024-12-28 02:56:39 瀏覽:190
魔獸和聯盟哪個對電腦配置要求高 發布:2024-12-28 02:43:26 瀏覽:81
屏保視頻怎麼設置密碼 發布:2024-12-28 02:33:12 瀏覽:76
movies文件夾 發布:2024-12-28 02:33:07 瀏覽:789
艾力紳怎麼跟安卓手機車機互聯 發布:2024-12-28 02:27:29 瀏覽:299