聲明:
本文是自己在學習中做的一些總結,希望我的總結可以對你有所幫助。同時需要注意的是在文中Android.mk與Makefile是一個東西,都是用來編譯程序的腳步,所以大家不用太糾結這個名稱。
自己碰到的問題:
我昨天對一個文件中的內容進行了修改,但是發現編譯成功後我的log內容並沒有在log中顯現,同時我發現原有的log的行數還是沒有修改前的行數,所以我可以確定自己的修改並沒有編譯到生成的so中,所以我調用的時候就沒有自己修改的內容了。
解決方法:
1. 看一下自己修改內容的目錄下的Android.mk文件中是否包含自己修改的文件,如果沒有包含,那麼說明這個文件壓根就不會被編譯,所以不管你做了什麼都沒有用的,不過這個情況還是很少出現的。一般如果以前會運行的文件,那麼他一定在Makefile中有所包含,所以這個時候你要看的是:LOCAL_SRC_FILES 這個tag了,這個tag表示要加載的源文件。我們接着講,這個時候我看到了自己編輯的源文件session.c 。
2. 確定了我們修改的文件所在,接下來就要看:LOCAL_MODULE這個tag了,這個tag用於表示這個模塊所特有的名稱,通過這個名稱就可以區別這個模塊。
3. 確定了模塊的名稱後,下面要注意的是文件結尾結尾出的tag:include $(BUILD_STATIC_LIBRARY)。因爲這個tag可以指明模塊要編譯爲一個什麼東西,例如上面的 BUILD_STATIC_LIBRARY就表示要編譯爲一個靜態的庫,而BUILD_SHARED_LIBRARY則表示要編譯爲動態的庫。BUILD_EXECUTABLE表示可執行文件。
4. 對於上面我的問題,我所要修改的文件編譯爲一個名爲:libhls的靜態庫,如下所示:
LOCAL_MODULE := libhls
include $(BUILD_STATIC_LIBRARY)
5. 搜索看那個文件中引用了libhls這個靜態庫,由於我要編譯的大的模塊爲Player,所以在這個目錄下搜索libhls,使用下面的命令:
grep -rn "libhls" Player/*
6. 對搜索到的內容進行篩選,由於我們知道libhls是一個靜態的庫,所以對靜態庫引用的tag爲:
LOCAL_STATIC_LIBRARIES
所以我們要選擇有LOCAL_STATIC_LIBRARIES 和libhls的語句,搜索如下:
LOCAL_STATIC_LIBRARIES := libhls
同時如果想要引用動態的庫可以使用下面的標籤:
LOCAL_SHARED_LIBRARIES
利用下面的標籤來引用動態的庫,如下:
LOCAL_SHARED_LIBRARIES :=crypto
7. 同樣這個時候我們需要重複上面步驟3到6,來查看這個Makefile的結尾是什麼,並且能生成什麼。然後一路查找看如何調用,並查看是否有LOCAL_MODULE_PATH這個tag,這個tag表示模塊生成路徑,而這個時候通常表示要生成外部可以調用的so文件。這裏對應的tag爲:
LOCAL_MODULE_PATH:=$(TARGET_OUT_SHARED_LIBRARIES)/player
8. 查找到這裏就可以知道如何編譯以及調用哪個so的文件來包含自己的修改了。例如我對應得修改文件一直由這裏的so動態庫調用,所以可以使用由下到上的mm遞歸以及模塊最後就將你修改的內容編進so動態庫中,而你只需要將這個動態庫複製到對應的庫中就可以解決上面的問題了 。
擴充:
除了上面介紹的這些信息,我們還有些tag是需要知道的,下面我在幾個事例中表明一些tag的作用:
//////////////////////////////////////////////////////////////////////////////////////////
include $(call all-subdir-makefiles)
在一些Android.mk中只有一句話,就是上面這樣的,他的意思是他會包含所有下層的Makefile,也就是說當在這個文件下mm的時候其實是遞歸的對這個Makefile下層的Makefile進行編譯。
下面舉個例子:
all-subdir-makefiles: 返回一個位於當前’my-dir’路徑的子目錄中的所有Android.mk的列表。
例如,某一子項目的目錄層次如下:
src/foo/Android.mk
src/foo/lib1/Android.mk
src/foo/lib2/Android.mk
如果 src/foo/Android.mk 包含一行:
include $(call all-subdir-makefiles)
那麼它就會自動包含 src/foo/lib1/Android.mk 和 src/foo/lib2/Android.mk。
這項功能用於向編譯系統提供深層次嵌套的代碼目錄層次。
注意,在默認情況下,NDK 將會只搜索在 src/*/Android.mk 中的文件。
this-makefile: 返回當前Makefile 的路徑(即這個函數調用的地方)
parent-makefile: 返回調用樹中父 Makefile 路徑。即包含當前Makefile的Makefile 路徑。
grand-parent-makefile:返回調用樹中父Makefile的父Makefile的路徑
/////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
LOCAL_PATH := $(call my-dir) //用於指明當前所在文件的路徑,接下來就可以直接使用
// LOCAL_PATH 來指明當前Makefile的路徑了
include $(CLEAR_VARS) //一般放到開始的位置來清除變量,指定讓GNU MAKEFILE爲你清除除
//LOCAL_PATH以外的所有LOCAL_XXX變量,清楚它們可以避免衝突
LOCAL_ARM_MODE := arm //默認情況下,arm目標二進制會以thumb的形式生成(16位),你
// 可以通過設置這個變量爲arm如果你希望你的module是以32位指令的形式。
LOCAL_MODULE_TAGS := optional
ifeq ($(LIVEPLAY_SEEK), true) //這裏是一個if的判斷語句,通過使用if可以有選
//擇性的添加一些模塊或者屬性
LOCAL_CFLAGS += -DSEEK // -D相當於是在加一個宏定義:
// #define LIVEPLAY_SEEK
endif
LOCAL_SRC_FILES := parser.c \ //定義包含的源文件
session.c \ //文件之間可以用空格或Tab鍵進行分割,換行請用"\"
//如果是追加源代碼文件的話,請用LOCAL_SRC_FILES +=
LOCAL_C_INCLUDES := \ //定義搜索頭文件的可能目錄,注意這裏是通過
//LOCAL_PATH作爲參考來查找的目錄地址
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../include \
ifeq ($(BUILD_WEB), true)
LOCAL_CFLAGS += -DWEB
endif
LOCAL_SHARED_LIBRARIES +=libamavutils //文件中使用的動態庫
LOCAL_MODULE := libhls //模塊名稱
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -Wno-psabi //-W表示警告選項
endif
include $(BUILD_STATIC_LIBRARY) //最終編譯生成靜態庫
///////////////////////////////////////////////////////////////////////////////////
Ps:
ifeq ($(strip $(BLUETOOTH_USE_BPLUS)),true) 選者編譯 如果BLUETOOTH_USE_BPLUS這個模塊有定一爲true,則編譯進去
LOCAL_CFLAGS += -DBLUETOOTH_USE_BPLUS 這個語句等價爲 #define BLUETOOTH_USE_BPLUS
(菜鳥級別解釋::=是賦值的意思,$是引用某變量的值
---------------------
作者:旭飛
來源:CSDN
原文:https://blog.csdn.net/wuhui790517095/article/details/8878506
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
參考文件:
Android NDK 學習筆記 4-Android.mk 篇
android.mk中LOCAL_CFLAGS 介紹 : tag解釋
Android.mk文件中LOCAL_CFLAGS常見設置:Android.mk文件中LOCAL_CFLAGS常見設置