android ndk-build android.mk,關於ndk-build所使用的Android.mk和Application.mk

Android.mk文件

一個Android.mk file用來向編譯系統描述你的源代碼。具體來說:該文件是GNU Makefile的一小部分,會被編譯系統解析一次或多次。你可以在每一個Android.mk file中定義一個或多個模塊,你也可以在幾個模塊中使用同一個源代碼文件。編譯系統為你處理許多細節問題。例如,你不需要在你的Android.mk中列出頭文件和依賴文件。NDK編譯系統將會為你自動處理這些問題。這也意味着,在升級NDK后,你應該得到新的toolchain/platform支持,而且不需要改變你的Android.mk文件。

先看一個簡單的例子:一個簡單的"hello world",比如下面的文件:

sources/helloworld/helloworld.c

sources/helloworld/Android.mk

相應的Android.mk文件會象下面這樣:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE

:= helloworld

LOCAL_SRC_FILES := helloworld.c

include $(BUILD_SHARED_LIBRARY)

我們來解釋一下這幾行代碼:

LOCAL_PATH := $(call my-dir)

一個Android.mk file首先必須定義好LOCAL_PATH變量。它用於在開發樹中查找源文件。在這個例子中,宏函數’my-dir’, 由編譯系統提供,用於返回當前路徑(即包含Android.mk file文件的目錄)。

include $( CLEAR_VARS)

CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),除LOCAL_PATH 。這是必要的,因為所有的編譯控制文件都在同一個GNU MAKE執行環境中,所有的變量都是全局的。

LOCAL_MODULE := helloworld

LOCAL_MODULE變量必須定義,以標識你在Android.mk文件中描述的每個模塊。名稱必須是唯一的,而且不包含任何空格。注意編譯系統會自動產生合適的前綴和后綴,換句話說,一個被命名為'foo'的共享庫模塊,將會生成'libfoo.so'文件。

LOCAL_SRC_FILES := helloworld.c

LOCAL_SRC_FILES變量必須包含將要編譯打包進模塊中的C或C++源代碼文件。注意,你不用在這里列出頭文件和包含文件,因為編譯系統將會自動為你找出依賴型的文件;僅僅列出直接傳遞給編譯器的源代碼文件就好。

在Android中增加本地程序或者庫,這些程序和庫與其所載路徑沒有任何關系,只和它們的Android.mk文件有關系。Android.mk和普通的Makefile有所不同,它具有統一的寫法,主要包含一些系統公共的宏。

在一個Android.mk中可以生成多個可執行程序、動態庫和靜態庫。

1,編譯應用程序的模板:

#Test Exe

LOCAL_PATH := $(call my-dir)

#include $(CLEAR_VARS)

LOCAL_SRC_FILES:= main.c

LOCAL_MODULE:= test_exe

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_EXECUTABLE)

(菜鳥級別解釋::=是賦值的意思,$是引用某變量的值)LOCAL_SRC_FILES中加入源文件路徑,LOCAL_C_INCLUDES 中加入所需要包含的頭文件路徑,LOCAL_STATIC_LIBRARIES加入所需要鏈接的靜態庫(*.a)的名稱,LOCAL_SHARED_LIBRARIES中加入所需要鏈接的動態庫(*.so)的名稱,LOCAL_MODULE表示模塊最終的名稱,BUILD_EXECUTABLE表示以一個可執行程序的方式進行編譯。

2,編譯靜態庫的模板:

#Test Static Lib

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= /

helloworld.c

LOCAL_MODULE:= libtest_static

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_STATIC_LIBRARY)

一般的和上面相似,BUILD_STATIC_LIBRARY表示編譯一個靜態庫。

3,編譯動態庫的模板:

#Test Shared Lib

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= /

helloworld.c

LOCAL_MODULE:= libtest_shared

TARGET_PRELINK_MODULES := false

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_SHARED_LIBRARY)

一般的和上面相似,BUILD_SHARED_LIBRARY表示編譯一個靜態庫。

以上三者的生成結果分別在如下,generic依具體target會變:

out/target/product/generic/obj/EXECUTABLE

out/target/product/generic/obj/STATIC_LIBRARY

out/target/product/generic/obj/SHARED_LIBRARY

每個模塊的目標文件夾分別為:

可執行程序:XXX_intermediates

靜態庫:      XXX_static_intermediates

動態庫:      XXX_shared_intermediates

另外,在Android.mk文件中,還可以指定最后的目標安裝路徑,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH來指定。不同的文件系統路徑用以下的宏進行選擇:

TARGET_ROOT_OUT:表示根文件系統。

TARGET_OUT:表示system文件系統。

TARGET_OUT_DATA:表示data文件系統。

用法如:

CAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

Application.mk文件要將C\C++代碼編譯為SO文件,光有Android.mk文件還不行,還需要一個Application.mk文件。本文檔是描述你的Android應用程序中需要的本地模塊的Application.mk的語法使用,要明白如下。Application.mk目的是描述在你的應用程序中所需要的模塊(即靜態庫或動態庫)。Application.mk文件通常被放置在$PROJECT/jni/Application.mk下,$PROJECT指的是您的項目。另一種方法是將其放在頂層的子目錄下:$NDK/apps目錄下,例如:$NDK/apps//Application.mk是一個簡稱,用於描述你的NDK編譯系統的應用程序(這個名字不會生成共享庫或者最終的包)下面是Application.mk中定義的幾個變量。APP_PROJECT_PATH這個變量是強制性的,並且會給出應用程序工程的根目錄的一個絕對路徑。這是用來復制或者安裝一個沒有任何版本限制的JNI庫,從而給APK生成工具一個詳細的路徑。APP_MODULES這個變量是可選的,如果沒有定義,NDK將由在Android.mk中聲明的默認的模塊編譯,並且包含所有的子文件(makefile文件)如果APP_MODULES定義了,它不許是一個空格分隔的模塊列表,這個模塊名字被定義在Android.mk文件中的LOCAL_MODULE中。注意NDK會自動計算模塊的依賴注意:NDK在R4開始改變了這個變量的行為,再次之前:- 在您的Application.mk中,該變量是強制的- 必須明確列出所有需要的模塊APP_OPTIM這個變量是可選的,用來定義“release”或"debug"。在編譯您的應用程序模塊的時候,可以用來改變優先級。“release”模式是默認的,並且會生成高度優化的二進制代碼。"debug"模式生成的是未優化的二進制代碼,但可以檢測出很多的BUG,可以用於調試。注意:如果你的應用程序是可調試的(即,如果你的清單文件中設置了android:debuggable的屬性是"true")。默認的是"debug"而不是"release"。這可以通過設置APP_OPTIM為"release"來將其覆蓋。注意:可以在"release"和"debug"模式下一起調試,但是"release"模式編譯后將會提供更少的BUG信息。在我們清楚BUG的過程中,有一些變量被優化了,或者根本就無法被檢測出來,代碼的重新排序會讓這些帶阿彌變得更加難以閱讀,並且讓這些軌跡更加不可靠。APP_CFLAGS當編譯模塊中有任何C文件或者C++文件的時候,C編譯器的信號就會被發出。這里可以在你的應用中需要這些模塊時,進行編譯的調整,這樣就不許要直接更改Android.mk為文件本身了重要警告:+++++++++++++++++++++++++++++++++++++++++++++++ + +++ 在這些編制中,所有的路徑都需要於最頂層的NDK目錄相對應。+ 例如,如果您有以下設置:++sources/foo/Android.mk+sources/bar/ Android.mk+ 編譯過程中,若要在foo/Android.mk中指定你要添加的路徑到bar源代碼中,+ 你應該使用+ APP_CFLAGS += -Isources/bar+ 或者交替:+ APP_CFLAGS += -I $(LOCAL_PATH )/../bar++ 使用'-l../bar/'將不會工作,以為它將等同於"-l$NDK_ROOT/../bar"++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++注意:在Android的NDK 1.5_r1,只適用於C源文件,而不適合C++。這已得到糾正,以建立完整相匹配的Andr​​oid系統。APP_CXXFLAGSAPP_CPPFLAGS的別名,已經考慮在將在未來的版本中廢除了APP_CPPFLAGS當編譯的只有C++源文件的時候,可以通過這個C++編譯器來設置注意:在Android NDK-1.5_r1中,這個標志可以應用於C和C++源文件中。並且得到了糾正,以建立完整的與系統相匹配的Android編譯系統。你先可也可以使用APP_CFLAGS來應用於C或者C++源文件中。建議使用APP_CFLAGSAPP_BUILD_SCRIPT默認情況下,NDK編譯系統會在$(APP_PROJECT_PATH)/jni目錄下尋找名為Android.mk文件:$(APP_PROJECT_PATH)/jni/Android.mk如果你想覆蓋此行為,你可以定義APP_BUILD_SCRIPT來指定一個備用的編譯腳本。一個非絕對路徑總是被解釋為相對於NDK的頂層的目錄。APP_ABI默認情況下,NDK的編譯系統回味"armeabi"ABI生成機器代碼。喜愛哪個相當於一個基於CPU可以進行浮點運算的ARMv5TE。你可以使用APP_ABI來選擇一個不同的ABI。比如:為了在ARMv7的設備上支持硬件FPU指令。可以使用APP_ABI := armeabi-v7a或者為了支持IA-32指令集,可以使用APP_ABI := x86或者為了同時支持這三種,可以使用APP_ABI := armeabi armeabi-v7a x86APP_STL默認情況下,NDK的編譯系統為最小的C++運行時庫(/system/lib/libstdc++.so)提供C++頭文件。然而,NDK的C++的實現,可以讓你使用或着鏈接在自己的應用程序中。例如:APP_STL := stlport_static    --> static STLport libraryAPP_STL := stlport_shared    --> shared STLport libraryAPP_STL := system            --> default C++ runtime library

引用:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值