【android】Android平台編譯makefile編寫規則


Date: 2018.10.9


1、參考

https://www.ibm.com/developerworks/cn/opensource/os-cn-android-build/
https://blog.csdn.net/yuanjize1996/article/details/54376228
https://blog.csdn.net/xyz_lmn/article/details/6966259/
https://developer.android.google.cn/ndk/guides/stable_apis#purpose

android ndk下載:(內含ndk-build)
https://developer.android.google.cn/ndk/downloads/
http://www.voidcn.com/article/p-fjfskgpc-bph.html

說明:當前最新版本的android-ndk版本是r16b。

Android NDK說明:
主要是包括編譯C/C++/ASM代碼的編譯器,需要按照ndk相關規則進行程序的編譯。因此ndk編譯器需要編寫符合android規則的makefile才能編譯。

2、android平台makefile編寫方法

http://android.mk/#intro 該網址下面有Android.mk的詳細編寫方法。

在任意目錄執行NDK編譯:

2.1 准備環境

首先,你得安裝了Android的NDK編譯工具,假設你的NDK的根目錄在 /opt/android/ndk .
當然,最好你能在環境變量里配置一下路徑,否則使用ndk-build命令的時候,都得加上路徑的前綴了。

修改 ~/.bashrc

export NDK_HOME=/opt/android/ndk
export PATH=$NDK_HOME:$PATH

然后執行:

$ source ~/.bashrc
2.2 編寫 .c 文件

假設你在 ~/math 目錄下編寫了一個 math.c 文件,內容如下:

#include <stdio.h>

int add( int a , int b ) {
    return a+b;
}

OK,后面我們就准備在 ~/math 目錄下,將這個.c文件編譯為Android可使用的靜態庫/動態庫了。

2.3 編譯成動態庫

編寫 Android.mk 文件,內容如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := dmath
LOCAL_SRC_FILES := math.c
include $(BUILD_SHARED_LIBRARY)

在 ~/math 目錄下,執行 ndk-build 命令,參數如下:

$ ndk-build -B  NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk

其中,NDK_PROJECT_PATH 指定了需要編譯的代碼的工程目錄,這里給出的是當前目錄,APP_BUILD_SCRIPT給出的是Android makefile文件的路徑,當然,如果你還有 Application.mk 文件的話,則可以添加

NDK_APP_APPLICATION_MK=./Application.mk 

執行完ndk-build命令后,你會發現當前目錄下,生成了 obj 和 libs 文件夾,這樣,你的libdmath.so動態庫就已經制作完成了,在 libs/armeabi 目錄下。

2.4 編譯為靜態庫

編譯為靜態庫,與編譯為動態庫唯一的區別就是 Android.mk 文件的寫法不同,另外,如果要編譯為靜態庫,則必須有其他的代碼引用該靜態庫代碼,ndk-build才會真正執行,否則無法成功生成靜態庫,這里,我們編寫一個 Android.mk ,將 math.c 同時編譯成靜態庫和動態庫。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := smath
LOCAL_SRC_FILES := math.c
include $(BUILD_STATIC_LIBRARY)

同樣,在 ~/math 目錄下執行:

$ ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk

你會在生成的 libs/armeabi 目錄下看到動態庫libdmath.so,在 obj/local/armeabi 目錄下看到靜態庫 libsmath.a。

2.5 編譯成可執行文件

大部分編譯規則與動靜態庫的書寫方法一樣,主要是加上下面語句:

include $(BUILD_EXECUTABLE)
3、常用NDK命令行參數:

參考:http://blog.51cto.com/ticktick/1425857

Android提供了NDK工具,用來編譯native代碼(c/c++),該工具配置好了相關的交叉編譯環境和工具鏈,只需要你簡單地編寫幾個.mk文件即可將你的c/c++代碼編譯為Android的java工程/Android手機可以識別、加載和運行的庫或者應用程序。

默認情況下,使用NDK編譯c/c++代碼,需要將該代碼放置到任一個Android應用工程的jni目錄下,然后編寫相應的Android.mk文件,並執行ndk-build命令完成編譯。其實你也是可以在任意目錄下去編譯native代碼的,只需要在ndk-build命令后面添加相應的命令行參數即可,這里給出一些常用的ndk-build命令行參數,方便大家靈活地使用NDK編譯自己的native代碼。


1. ndk-build NDK_LOG=1
用於配置LOG級別,打印ndk編譯時的詳細輸出信息

2. ndk-build NDK_PROJECT_PATH=.
指定NDK編譯的代碼路徑為當前目錄,如果不配置,則必須把工程代碼放到Android工程的jni目錄下

3. ndk-build APP_BUILD_SCRIPT=./Android.mk
指定NDK編譯使用的Android.mk文件

4. ndk-build NDK_APP_APPLICATION_MK=./Application.mk
指定NDK編譯使用的application.mk文件

5. ndk-build clean
清除所有編譯出來的臨時文件和目標文件

6. ndk-build -B
強制重新編譯已經編譯完成的代碼

7. ndk-build NDK_DEBUG=1
執行 debug build

8. ndk-build NDK_DEBUG=0
執行 release build

9. ndk-build NDK_OUT=./mydir
指定編譯生成的文件的存放位置

10. ndk-build -C /opt/myTest/
到指定目錄編譯native代碼   
4、ndk工程目錄編譯后libs與obj目錄下庫文件的區別

參考:https://blog.csdn.net/bidgod/article/details/6930440
在執行NDK編譯之后,編譯器會生成libs和obj兩個目錄,並且libs/armeabi中和obj/local/armeabi中都包含可執行文件和動態庫,區別何在呢?

As part of the build process, the files in the libs folder have been stripped of symbols and debugging information. So you’ll want to keep two copies of each of your .so files: One from the libs folder to install on the Android device, and one from the obj folder to install for GDB to get symbols from.
libs目錄下生成的庫是剝離了符號表與調試信息的,而obj下的庫是帶有調試信息的。

5、Android.mk和Application.mk說明

關於Application.mk , Android.mk和JNI的介紹可參考:
https://developer.android.google.cn/ndk/guides/android_mk
https://developer.android.google.cn/ndk/guides/application_mk
通用模塊編譯可以采用Android_lib.mk,Android_app.mk和common.mk以及Application.mk采用ndk-build進行編譯。
libmpeg2解碼器的Android平台編譯:
libmpeg2解碼器的Android平台編譯
示例:
common.mk:設置源文件目錄以及頭文件目錄:配置LOCAL_C_INCLUDES和LOCAL_SRC_FILES.
Android_lib.mk:設置編譯參數、特定平台編譯參數、編譯動靜態庫配置:配置LOCAL_PATH,LOCAL_MODULE,LOCAL_CFLAGS,LOCAL_CPPFLAGS。
Application.mk:設置APP_ABI,APP_PLATFORM和NDK_TOOLCHAIN_VERSION等。
補充說明及注意事項:
匯編(.asm,.S,.s)文件的編譯參數設置:LOCAL_ASMFLAGS
C文件編譯參數設置:LOCAL_CFLAGS
C++文件編譯參數設置:LOCAL_CPPFLAGS
鏈接器參數設置:LOCAL_LDFLAGS

6、ndk-build的編譯選項

https://developer.android.google.cn/ndk/guides/ndk-build

所有給ndk-build的選項都會直接傳給GNU Make,由make運行NDK的編譯腳本。幾個常見調用方式如下:

 ndk-build clean 清掉二進制文件
  ndk-build NDK_DEBUG=1     編譯為可調試版的二進制文件
  ndk-build NDK_DEBUG=0     編譯為release版
  ndk-build V=1             執行ndk-build且打印出它所執行的詳細編譯命令。
  ndk-build -B              強制重新編譯
  ndk-build -B V=1          -B 和 V=1 的組合
  ndk-build NDK_LOG=1        打印出內部的NDK日志信息(用於調試NDK自己)
  ndk-build NDK_APPLICATION_MK=<文件路徑>      用這里指定的路徑尋找Application.mk文件
  ndk-build -C <project路徑>  先cd進入<project路徑>,然后執行ndk-build。

jni中如何指定編譯器:
在jni/Application.mk中添加

NDK_TOOLCHAIN_VERSION :=4.9

NDK_TOOLCHAIN_VERSION. Define this variable as 4.9 to select that version of the GCC compiler. Define this variable as clang to select the Clang compiler,

7、編譯腳本

Android平台通用編譯環境

8、編譯模板

Android平台通用編譯模板

更多參考網址:
https://www.cnblogs.com/wanghuaijun/p/8092747.html
https://blog.csdn.net/listener51/article/details/84026778
https://www.tuicool.com/articles/QZJ3qa
https://blog.csdn.net/crash163/article/details/52228412

9、Android平台編譯注意事項
  1. 當前最新版本的android-ndk版本是r16b。將x86純匯編代碼編譯為x86_64平台Android程序時,報出如下問題:
Android.mk: Unsupported source file extensions for "xxxxxxxxxx" 

原因: 采用ndk版本為r10。該版本不支持x86_64平台上的asm匯編文件的編譯,不識別asm格式的文件。這樣會導致編譯時忽略掉asm文件的編譯。
解決方案: 經過測試,r10,r10b都不支持x86_64平台上的asm匯編編譯,r10e和更高版本的ndk支持x86_64平台上的asm匯編編譯。


THE END!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM