緣由
曾夢(mèng)想仗劍走天涯艇纺,看一看世界的繁華糖耸。豈料一入 JNI 深似海其监,從此女神是路人剔桨。生成so文件,是每個(gè) JNI 人的終極夢(mèng)想幔翰。前段日子漩氨,公司人少,扔過(guò)來(lái)的是cpp實(shí)現(xiàn)文件遗增,呵呵,以為要往c渣渣方向發(fā)展款青,嚇得我趕緊拿起那本紅皮書(shū)做修,c++從入門(mén)到放棄。幾個(gè)月過(guò)去,書(shū)還沒(méi)人捧熱饰及,cpp不見(jiàn)了蔗坯,取而代之是.a文件,什么玩意兒燎含?掏出度娘宾濒,怒刷binggo。一手Shadowsocks屏箍,谷狗汪汪汪绘梦。靜態(tài)庫(kù),簡(jiǎn)單來(lái)說(shuō)赴魁,編譯器認(rèn)識(shí)卸奉,而linux不認(rèn)識(shí)。故事颖御,從這里開(kāi)始榄棵。
.a 怎么用
想用就用,用得響亮潘拱。我就靜靜的疹鳄,靜靜的看著。一巴掌一個(gè)腳印芦岂,啪啪啪瘪弓,痛嗎?不痛盔腔,輕輕松松三步走杠茬。
啪. 定位
下藥要對(duì)口,位置不能隨心弛随。來(lái)來(lái)來(lái)瓢喉,jni (JNI Floder)目錄下。又回到最初的起點(diǎn)舀透,記憶中你cpp文件的位置(打個(gè)廣告栓票,參考我前邊寫(xiě)的關(guān)于JNI文章)。對(duì)愕够,沒(méi)錯(cuò)走贪,又是jni目錄。進(jìn)階的.a惑芭,還是老地方坠狡,熟悉的味道,不一樣的配方遂跟。然逃沿,no pic no bb婴渡。吶~*@……#!#凯亮!神圣召喚術(shù) --- 圖圖圖边臼。
上邊的sources目錄是瞎寫(xiě)的,歸個(gè)類假消。這里有東西解釋下柠并,比如說(shuō) arm64-v8a之類的, 這個(gè)是指cpu類型富拗。目前而言臼予,armeabi 這個(gè)是基類,所有手機(jī)都支持的類型媒峡。蕓蕓眾手機(jī)瘟栖,天涯cpu類型what?no谅阿,no半哟,nobody I want nobody nobody But You,一個(gè)字:懶签餐。so armeabi寓涨,你值得擁有。x86/x86-64這個(gè)一般是電腦cpu類型氯檐,模擬器用得上戒良。如果能夠每個(gè)類型都build出來(lái),自然是好的冠摄,畢竟每個(gè)類型cpu都有各自的優(yōu)化糯崎。
啪啪. 鏈接
重點(diǎn)來(lái)了。使用.a的過(guò)程河泳,就是鏈接沃呢。當(dāng)然不僅僅是,整個(gè)打包成so過(guò)程拆挥,都是鏈接過(guò)程薄霜,這里主講如何鏈接.a。
mk纸兔,從 jni 誕生那一刻起惰瓜,隨之誕生。這里暫且先講mk方式實(shí)現(xiàn)鏈接汉矿,其它暫且不提崎坊。悠久的歷史,腳本性質(zhì)的配置洲拇,承載著老一輩人的遠(yuǎn)方與詩(shī)流强。左手痹届,右手呻待,一個(gè)慢動(dòng)作打月。一步兩步三四步,帶你走個(gè)過(guò)場(chǎng)蚕捉。記住了奏篙,固然可喜,若是沒(méi)有迫淹,就再看一遍吧秘通。
# Android.mk文件,稍作修改敛熬,即可食用
LOCAL_PATH := $(call my-dir)
//鏈接.a塊
include $(CLEAR_VARS)
LOCAL_MODULE := libHello
LOCAL_C_INCLUDES := $(LOCAL_PATH)/sources
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/sources
LOCAL_SRC_FILES := sources/$(TARGET_ARCH_ABI)/libHello.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_CPPFLAGS := -std=c++14
LDFLAGS := -shared
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_MODULE := JniDemo
LOCAL_SRC_FILES := jni_dynamic.cpp
LOCAL_STATIC_LIBRARIES := libHello
include $(BUILD_SHARED_LIBRARY)
# Application.mk 這個(gè)基本不需要改
APP_STL := gnustl_static//使用 STL 靜態(tài)庫(kù)
NDK_TOOLCHAIN_VERSION := 4.9//鏈接器tool版本
/**
*fexceptions 允許異常功能
*frtti 運(yùn)行時(shí)類型識(shí)別
*fpermissive 此項(xiàng)有效時(shí)表示寬松的編譯形式肺稀,比如沒(méi)有用到的代碼中有錯(cuò)誤也可以通過(guò)
* std=c++14 允許使用c++14的函數(shù)等功能
*/
APP_CPPFLAGS := -fexceptions -frtti -fpermissive -std=c++14
APP_ABI := armeabi armeabi-v7a arm64-v8a mips mips64
APP_PLATFORM := android-14
APP_OPTIM := debug
這2個(gè)固定搭配,沒(méi)什么需要特別解釋的地方应民,照搬磚頭即可话原。如果你砸到了自己的腳,火速120诲锹,你來(lái)找我也沒(méi)用繁仁。mk文件已經(jīng)就位,當(dāng)然還需要build.gradle的支持归园。
android{
....
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "E:/adt-bundle-windows-x86_64-20140321/android-ndk-r10/ndk-build.cmd",//ndk.build位置
'NDK_PROJECT_PATH=build/intermediates/ndk',//ndk位置
'NDK_LIBS_OUT=src/main/jniLibs',//輸出目錄
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
'NDK_APPLICATION_MK=src/main/jni/Application.mk'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
這段黄虱,不解釋呢,說(shuō)不過(guò)去庸诱。解釋呢捻浦,一句話,自定義ndkbuild命令(生成so的利器)桥爽。到這里本想著已經(jīng)告一段路了朱灿,是時(shí)候見(jiàn)證奇跡的時(shí)刻了。然而還不料聚谁,一個(gè)error讓我沉醉母剥,毫無(wú)保留,沒(méi)有余力悲傷:
D:\Study_Code\JniDemo\app\src\main\jni\sources\hello.h
Error:(1, 18) string: No such file or directory
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: Error while executing 'E:\adt-bundle-windows-x86_64-20140321\android-ndk-r10\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-25 NDK_OUT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=D:\Study_Code\JniDemo\app\build\intermediates\ndk\debug\lib APP_ABI=all}
顯然形导,c++中string找不到环疼。喲喲喲,切克鬧朵耕。bug炫隶,bug,bug阎曹,驚起一灘苦水伪阶。既然開(kāi)啟了自定義煞檩,那么就需要做點(diǎn)限制,比如說(shuō)禁用自動(dòng)執(zhí)行ndk-build栅贴。如果自動(dòng)執(zhí)行ndk-build的話斟湃,那么我的Application.mk配置將失效,默認(rèn)是c環(huán)境檐薯,緣來(lái)如此凝赛。
android{
...
sourceSets {
main {
jni.srcDirs = []//禁用自動(dòng)執(zhí)行ndk-build
}
}
}
.mk 這艘小船,到這兒坛缕,已經(jīng)上岸了墓猎。
啪啪啪.見(jiàn)證奇跡的時(shí)刻
上邊的已然做到,那么這一刻赚楚,屬于你的奇跡終究還是到來(lái)了毙沾。biu,biu宠页,build左胞。接下來(lái),或許更精彩勇皇。
附送一張機(jī)票罩句,帶你領(lǐng)略世界的浩瀚