Android ndk-build編譯jni動(dòng)態(tài)庫(kù)

目的

能快速,簡(jiǎn)單(主要是指脫離AndroidStudio)的把c/c++ 源碼進(jìn)行交叉編譯成Android上的動(dòng)態(tài)庫(kù),靜態(tài)庫(kù),或者可執(zhí)行文件。從而為逆向分析構(gòu)建demo節(jié)省時(shí)間。

編譯環(huán)境配置

電腦:Mac OS 10.13.4
NDK:官網(wǎng)下載,目前最新的好像android-ndk-r17 我用的是 android-ndk-r14b,ndk不需要安裝官網(wǎng)下載后解壓就行。
測(cè)試機(jī): 華為EVA-AL00 Android7.0

配置環(huán)境變量

為了方便使用ndk的命令行工具,我們配置環(huán)境變量
~/.bash_profile 文件中添加如下配置

export ANDROID_NDK_HOME=/Users/user01/Development/android-ndk-r14b
export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin

然后命令行運(yùn)行如下命令:

$ source ~/.bash_profile

然后命令行運(yùn)行:

$ ndk-build -h

如果能打印出 ndk-build 這個(gè)工具的幫助文檔說(shuō)明環(huán)境變量配置成功

測(cè)試簡(jiǎn)單的例子

創(chuàng)建如下目錄結(jié)構(gòu)(注意jni這層目錄很重要,名字不要隨便取):

~/Desktop/test/
└── jni/
    ├── Android.mk
    ├── Application.mk
    └── test.c

主要有三個(gè)文件,其中Android.mk和Application.mk 是輔助ndk-build進(jìn)行編譯的,test.c是我們的c測(cè)試用例

  1. Application.mk

主要指定生成哪些cpu架構(gòu)的動(dòng)態(tài)庫(kù),這里只生成armeabi 和armeabi-v7a架構(gòu)的庫(kù)

APP_ABI      := armeabi armeabi-v7a
APP_PLATFORM := android-14
  1. Android.mk

具體Android.mk的更詳細(xì)的配置自行Google

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
# 生成的so庫(kù)的名字為libdemo.so
LOCAL_MODULE    := demo
# 用于編譯的c文件
LOCAL_SRC_FILES := test.c
# 生成庫(kù)的類(lèi)型,是動(dòng)態(tài)庫(kù),靜態(tài)庫(kù)還是可執(zhí)行文件,這里先來(lái)生成一個(gè)動(dòng)態(tài)庫(kù)
include $(BUILD_SHARED_LIBRARY)
# 下面這么寫(xiě)是生成可執(zhí)行文件
#include $(BUILD_EXECUTABLE)
  1. test.c

很簡(jiǎn)單就是打印一句 hello world!

#include <stdio.h>

int main(const int argc,const char* args[]){

const char* str  = "hello world!";
printf("%s\n",str);
return 0;

}

然后命令行進(jìn)入到test目錄下面:

$ cd ~/Desktop/test

$ ndk-build -C ./jni

然后會(huì)生成如下目錄結(jié)構(gòu),obj目錄下是生成動(dòng)態(tài)庫(kù)的中間文件,libs里面是最終生成的不同CPU架構(gòu)的動(dòng)態(tài)庫(kù):

test
├── jni
│   ├── Android.mk
│   ├── Application.mk
│   └── test.c
├── libs
│   ├── armeabi
│   │   └── libdemo.so
│   └── armeabi-v7a
│       └── libdemo.so
└── obj
    └── local
        ├── armeabi
        │   ├── libdemo.so
        │   └── objs
        │       └── demo
        │           ├── test.o
        │           └── test.o.d
        └── armeabi-v7a
            ├── libdemo.so
            └── objs
                └── demo
                    ├── test.o
                    └── test.o.d

為什么非要有jni那一層目錄

約定優(yōu)于配置,沒(méi)有不行嗎?行,但是要改點(diǎn)東西。去掉jni那層目錄再編譯一次,當(dāng)前目錄結(jié)構(gòu)如下:

test/
├── Android.mk
├── Application.mk
└── test.c

命令行執(zhí)行

  1. $ cd ~/Desktop/test
  2. $ ndk-build

結(jié)果報(bào)錯(cuò)如下:

Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.

錯(cuò)誤日志上說(shuō)什么路徑找不到錯(cuò)誤,需要定義一個(gè)xx變量,我們只需要把編譯命令改成如下就可以了:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk

編譯一個(gè)可以運(yùn)行的文件

修改Android.mk 文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := demo
LOCAL_SRC_FILES := test.c
#include $(BUILD_SHARED_LIBRARY)

# Android4.4 以后 調(diào)用的可執(zhí)行文件不是基于PIE方式編譯的,則無(wú)法運(yùn)行
LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE
# 編譯一個(gè)可執(zhí)行文件
include $(BUILD_EXECUTABLE)

這個(gè)可執(zhí)行文件在電腦上是沒(méi)法執(zhí)行的,只能放到手機(jī)里面執(zhí)行,執(zhí)行如下命令,我們把剛生成的文件放到手機(jī)上:

  1. push 文件到手機(jī)
    $ adb push libs/armeabi-v7a/demo /data/local/tmp
  2. 為手機(jī)中的demo文件添加可執(zhí)行權(quán)限(為了方便直接給予所有權(quán)限了)
    $ adb shell 'chmod 777 /data/local/tmp/demo'
  3. 用手機(jī)環(huán)境運(yùn)行demo這個(gè)文件
    $ adb shell '/data/local/tmp/demo'

運(yùn)行結(jié)果會(huì)打印一行
hello world!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容