在ndk或者jni開發(fā)過程中您旁,我們經(jīng)常會(huì)有打日志的需求烙常,并且需要顯示日志輸出的源文件名稱、行數(shù)等信息鹤盒,這時(shí)候就需要我們輸出一個(gè)完整的日志格式蚕脏。本文針對(duì)采用ndk-build方式編譯,如果是采用cmake編譯昨悼,不再本文討論范圍之內(nèi)
常見宏
首先我們看一下ANSI C標(biāo)準(zhǔn)中幾個(gè)標(biāo)準(zhǔn)預(yù)定義宏:
-
__LINE__
:在源代碼中插入當(dāng)前源代碼行號(hào)蝗锥; -
__FILE__
:在源文件中插入當(dāng)前源文件名; -
__DATE__
:在源文件中插入當(dāng)前的編譯日期率触; -
__TIME__
:在源文件中插入當(dāng)前編譯時(shí)間终议; -
__STDC__
:當(dāng)要求程序嚴(yán)格遵循ANSI C標(biāo)準(zhǔn)時(shí)該標(biāo)識(shí)被賦值為1;
假設(shè)你的日志輸出格式:
#define NEW_LINE "\r\n"
#define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
#define DEBUG(fmt, ...) {
debug_to_file(G_STRLOC " " fmt NEW_LINE, ## __VA_ARGS__);
}
我們可以看到葱蝗,這里定義的了一個(gè)宏__FILE__
這個(gè)就是當(dāng)前源文件
舉個(gè)栗子
正如上面例子所示穴张,使用了__FILE__
之后,默認(rèn)情況下两曼,輸出的路徑是編譯該源文件時(shí)皂甘,該源文件在編譯環(huán)境下的全路徑,例如你的源文件路徑是在/User/eggsy/Demo/src/main/jni/test.c
悼凑,在該文件的58行中有代碼
58 DEBUG("ouput demo log %s","success");
那么輸出的時(shí)候日志就是
/User/eggsy/Demo/src/main/jni/test.c:58 ouput demo log success
這里我們看到輸出的就是在源文件的全路徑偿枕,當(dāng)前路徑看起來過長了璧瞬,如果你的工程目錄層級(jí)在系統(tǒng)更深處,那么這里前面打印出來的日志路徑就非常長了渐夸,其實(shí)對(duì)我們最重要的是從jni目錄開始日志路徑嗤锉,能夠完整說明源文件路徑
解決方案
傳統(tǒng)方式
先來說下傳統(tǒng)的編譯方式,采用ndk-build方式墓塌,我們經(jīng)常需要在如下目錄下放置Android.mk
與Application.mk
文件
在build.gradle
中我們需要配置指定Android.mk
文件位置
// 引入工程外部的編譯文件
externalNativeBuild {
ndkBuild {
path 'src/main/jni/Android.mk'
}
}
這種方式編譯出來的瘟忱,日志中源文件路徑就是全路徑。
優(yōu)化方式
優(yōu)化方式就是我們需要切到src/main/jni
目錄下苫幢,
cd src/main/jni
執(zhí)行ndk-build命令
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk NDK_LIBS_OUT=../output/libs
-
NDK_PROJECT_PATH
:指定工程的路徑访诱,由于我們已經(jīng)cd到了jni目錄,這里就用.
表示當(dāng)前路徑 -
NDK_APPLICATION_MK
:表示application的配置 -
APP_BUILD_SCRIPT
:表示構(gòu)建腳本的路徑 -
NDK_LIBS_OUT
:表示最后生成動(dòng)靜態(tài)的位置
所以我們看到如上圖目錄結(jié)構(gòu)中的ouput
目錄下會(huì)生成我們編譯的庫韩肝。
最后生成日志的時(shí)候触菜,就是相對(duì)路徑啦,沒有前面一大堆絕對(duì)路徑I√荨C登狻!
LOCAL_SRC_FILES源碼路徑
最后距離成功還差一步谜诫,漾峡,參考上面的《目錄結(jié)構(gòu)》圖片,在Android.mk
中喻旷,在引用源文件的時(shí)候生逸,要用相對(duì)路徑,如果使用絕對(duì)路徑(LOCAL_PATH變量+源文件)且预,上面的修改就無效了槽袄,例如
LOCAL_SRC_FILES := $(LOCAL_PATH)/andsrc/demo.c ......
需要改為
LOCAL_SRC_FILES := andsrc/demo.c ......
這樣的相對(duì)路徑,相對(duì)路徑是相對(duì)于Android.mk
的當(dāng)前路徑而言锋谐。
總結(jié)
其實(shí)這個(gè)小技巧很簡單遍尺,但是真正遇到的時(shí)候可能會(huì)困擾一些同學(xué)很久,最關(guān)鍵的就是編譯的時(shí)候需要指定NDK_PROJECT_PATH
涮拗、NDK_APPLICATION_MK
乾戏、APP_BUILD_SCRIPT
參數(shù)啦,當(dāng)然這些參數(shù)你也可以配置在gradle中三热,無需手動(dòng)執(zhí)行