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

ndk編譯動態庫

發布時間: 2022-04-16 04:08:27

❶ 如何設置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」

❷ 如何把ndk-build生成的.o文件編譯到動態庫

下面就通過幾道小例子來熟悉下1、funct...
1

2、var a = 1;function test() { ...
2

3、給兩個小例子作為對比:var a; fun...
3

var a; function fun() { a = "globa...
4

4、函數域優先於全局域,故局部變數a會...
5

5、javascript沒有塊級作用域function ...

❸ 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/下,這也是系統載入動態庫時搜索的路徑。

❹ 如何查看ndk編譯的動態庫符號表

$ /path/to/ndk/buid/prebuilt/windows/arm-eabi-4.4.0/bin/arm-eabi-nm libs/armeabi/libsanangeles.so

00003600 T Java_com_example_SanAngeles_DemoGLSurfaceView_nativePause

00003638 T Java_com_example_SanAngeles_DemoRenderer_nativeDone

0000367c T Java_com_example_SanAngeles_DemoRenderer_nativeInit

000035b4 T Java_com_example_SanAngeles_DemoRenderer_nativeRender

00003644 T Java_com_example_SanAngeles_DemoRenderer_nativeResize

00007334 a _DYNAMIC

0000740c a _GLOBAL_OFFSET_TABLE_

復制代碼

這里可以看到幾乎所有的函數名全局變數名都會被導出。其中有Java_com_example_SanAngeles_為前綴的JNI介面函數,有importGLInit這些普通函數,有freeGLObject這些局部(static)函數,還有sStartTick等全局變數名。其實在這個動態發布的時候,只需要導出java_com_開頭的jni函數就可以了,裡面這些細節函數名完全不需要暴露出來。
如何做到這一點呢?首先,我們需要了解gcc新引進的選項-fvisibility=hidden,這個編譯選項可以把所有的符號名(包括函數名和全局變數名)都強制標記成隱藏屬性。我們可以在Android.mk中可以通過修改LOCAL_CFLAGS選項加入-fvisibility=hidden來做到這一點,這樣編譯之後的.so看到的符號表為:

000033d0 t Java_com_example_SanAngeles_DemoGLSurfaceView_nativePause

00003408 t Java_com_example_SanAngeles_DemoRenderer_nativeDone

0000344c t Java_com_example_SanAngeles_DemoRenderer_nativeInit

00003384 t Java_com_example_SanAngeles_DemoRenderer_nativeRender

00003414 t Java_com_example_SanAngeles_DemoRenderer_nativeResize

00007104 a _DYNAMIC

❺ 如何使用android的ndk編譯器 編譯c++的庫

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類型及區別: 那麼,如何指定ABI類型呢?在 Application.mk 文件中添加一行即可: APP_ABI := armeabi-v7a //只編譯armeabi-v7a版本 APP_ABI := armeabi armeabi-v7a //同時編譯armeabi,armeabi-v7a版本 APP_ABI := all //編譯所有版本 3. LOCAL_LDLIBS Android NDK 除了提供了Bionic libc庫,還提供了一些其他的庫,可以在 Android.mk 文件中通過如下方式添加依賴: LOCAL_LDLIBS := -lfoo 其中,如下幾個庫在 Android NDK 編譯時就默認鏈接了,不需要額外添加在 LOCAL_LDLIBS 中: (1) Bionic libc庫 (2) pthread庫(-lpthread) (3) math(-lmath) (4) C++ support library (-lstdc++) 下面我列了一個表,給出了可以添加到「LOCAL_LDLIBS」中的不同版本的Android NDK所支持的庫: 下面是我總結的一些常用的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」

❻ 如何使用Eclipse的NDK開發動態庫,靜態庫

1.動態庫:

一、創建動態鏈接庫1、創建工程new->project->c++ project選擇Shared Library->Empty Project.輸入工程名a,點擊finish,完成工程的創建。

2、編寫代碼在windows下封裝動態鏈接庫時對要封的函數要用__declspec(dllexport)來標明,在Linux下不用,在linux下只需要直接把要封的函數的聲明放到一個。h文件中,要用這個庫時將相應的。h文件載入到工程中。

3、生成動態鏈接庫編譯代碼,成功後在Debug目錄下會生成liba.so文件。

二、動態鏈接庫的使用1、創建工程new->c++ project->Executable->Empty Project.工程名為libr 2、編寫所需代碼,並將相應的。h文件放到工程目錄下並載入到工程中。

3、加入動態鏈接庫liba.so右鍵工程Properites->C/C++Build->Settings,然後如下圖



編譯通過!
為了我們的程序能夠正確載入,我們需要讓我們的程序在我們的系統范圍內也能夠找到我們的庫。這時候我們需要在設置一下。

❼ linux下 如何用NDK生成C語言動態庫

先將要編譯的源代碼文件移動到一個目錄下面,寫好makefile文件,一般是已經寫好的(沒有的話就要自己寫了),然後配置好ndk環境變數,在/etc/profile目錄下添加export NDK_ROOT=/你的nkd路徑,然後保存,重啟機器,最後就是cd到你要編譯的源碼目錄下,調用ndk_build就行了

❽ 用NDK編譯生成動態庫的時候 出現這個錯誤 怎麼解決,libmyAdd.so是我在linux下生成的動態庫

linux生成的so不能被NDK使用,編譯所使用的指令集不一樣

❾ 如何用Android NDK編譯FFmpeg

我們知道在Ubuntu下直接編譯FFmpeg是很簡單的,主要是先執行./configure,接著執行make命令來編譯,完了緊接著執行make install執行安裝。那麼如何使用Android的NDK編譯出來可以在Android下面可以使用的FFmpeg動態鏈接庫呢?寫下這篇文章就是學習如何裁剪並且編譯出來可以使用的動態庫。
http://www.cnblogs.com/tanlon/p/3938282.html

❿ android ndk到底是什麼

NDK是一系列工具的集合。它提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk(AndroidPackage的縮寫,Android安裝包)。這些工具對開發者的幫助是巨大的。它集成了交叉編譯器,並提供了相應的mk文件隔離CPU、平台、ABI等差異,開發人員只需要簡單修改mk文件(指出「哪些文件需要編譯」、「編譯特性要求」等),就可以創建出so。它可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。
NDK提供了一份穩定、功能有限的API頭文件聲明,Google明確聲明該API是穩定的,在後續所有版本中都穩定支持當前發布的API。從該版本的NDK中看出,這些API支持的功能非常有限,包含有:C標准庫(libc)、標准數學庫(libm)、壓縮庫(libz)、Log庫(liblog)。

熱點內容
如何修改自己的名字和密碼 發布:2025-03-17 09:32:20 瀏覽:787
寶馬3系槍灰色輪轂是哪個配置 發布:2025-03-17 09:28:17 瀏覽:513
鴻蒙系統退回安卓系統怎麼備份 發布:2025-03-17 09:14:33 瀏覽:614
資料庫服務公司 發布:2025-03-17 08:56:43 瀏覽:495
我的世界伺服器載入不了區塊 發布:2025-03-17 08:56:39 瀏覽:817
如何給無線路由器設置密碼 發布:2025-03-17 08:51:40 瀏覽:886
SQL閥 發布:2025-03-17 08:45:23 瀏覽:162
ipadpro第一代什麼配置 發布:2025-03-17 08:44:38 瀏覽:198
linuxjava進程查看 發布:2025-03-17 08:29:19 瀏覽:969
安卓9系統安裝包哪裡下載 發布:2025-03-17 08:20:40 瀏覽:512