LOCAL_WHOLE_STATIC_LIBRARIES與LOCAL_STATIC_LIBRARIES的區別

來源:互聯網
上載者:User

標籤:android   style   blog   http   color   使用   

在分析Jelly Bean Audio Subsystem的時候,發現HAL層的庫audio_policy.xxx.so與其依賴的靜態庫libaudiopolicy_legacy.a都有audio_policy_hal.cpp這個源檔案而且兩者都定義了一個HMI。當調用者引用HMI的時候,調用的究竟是哪個呢?

 

首先看audio_policy.xxx.so的Android.mk檔案,在定義編譯audio_policy.xxx.so的段落裡面有這麼一句:

LOCAL_STATIC_LIBRARIES := \
     libaudiohw_legacy \
     libmedia_helper \
     libaudiopolicy_legacy

說明libaudiopolicy_legacy是以靜態庫的形式為audio_policy.xxx.so所用,而在通用的audio_policy庫(也可以說是Google提供給廠商參考用的policy庫)audio_policy.default.so的庫裡面是這麼用的:

LOCAL_WHOLE_STATIC_LIBRARIES := \
    libaudiopolicy_legacy

而audio_policy.default.so的源碼裡面就沒有audio_policy_hal.cpp這個源檔案,所以玄機應該就在LOCAL_WHOLE_STATIC_LIBRARIES和LOCAL_STATIC_LIBRARIES這兩個宏的差異上面。先看下Google在build/core/build-system.html裡面是怎麼說的:

 

LOCAL_STATIC_LIBRARIES

 

These are the static libraries that you want to include in your module. Mostly, we use shared libraries, but there are a couple of places, like executables in sbin and host executables where we use static libraries instead.

 

LOCAL_WHOLE_STATIC_LIBRARIES

 

These are the static libraries that you want to include in your module without allowing the linker to remove dead code from them. This is mostly useful if you want to add a static library to a shared library and have the static library‘s content exposed from the shared library.

 

總的來說LOCAL_WHOLE_STATIC_LIBRARIES在串連靜態串連庫的時候不會移除"daed code",何謂dead code呢,就是調用者模組永遠都不會用到的程式碼片段和變數,下面用幾個小源碼來說明。

Android.mk如下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES :=     libstone_1.cppLOCAL_MODULE := libstone_1LOCAL_MODULE_TAGS := optionalinclude $(BUILD_STATIC_LIBRARY)# =========================================include $(CLEAR_VARS)LOCAL_SRC_FILES :=     libstone_2.cppLOCAL_STATIC_LIBRARIES := libstone_1#<span style="color:#ff0000;"> LOCAL_WHOLE_STATIC_LIBRARIES := libstone_1</span>LOCAL_MODULE := libstone_2LOCAL_MODULE_TAGS := optionalinclude $(BUILD_SHARED_LIBRARY)

靜態庫源檔案(libstone_1.cpp):

char hello[] = "this is a string in libstone_1";char str_2[] = "non static string 1";char str_3[] = "non static string 2";void func_1(){hello[0]+=1;}

調用者源檔案(libstone_2.cpp):

char hello[] = "this is a string in libstone_2";

case 1,按照上述的代碼make之後,libstone_1的所有東西都沒有被串連到動態庫libstone_2裡面:

 

readelf -Ws system/lib/libstone_2.so 
Symbol table ‘.dynsym‘ contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00002000    31 OBJECT  GLOBAL DEFAULT   13 hello2
     2: 000002e8    12 FUNC    GLOBAL DEFAULT    7 __on_dlclose
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0
     5: 00002020     0 NOTYPE  GLOBAL DEFAULT   14 __dso_handle
     6: 00001ee4     0 NOTYPE  GLOBAL DEFAULT    9 __INIT_ARRAY__
     7: 00001eec     0 NOTYPE  GLOBAL DEFAULT   10 __FINI_ARRAY__
     8: 0000201f     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
     9: 0000201f     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    10: 00002030     0 NOTYPE  GLOBAL DEFAULT  ABS _end

case 2,修改Android.mk使用LOCAL_WHOLE_STATIC_LIBRARIES 宏,這個時候libstone_2.cpp中的hello要改成hello2,因為libstone_1裡面的東西全部連結進來了:

readelf -Ws system/lib/libstone_2.so 
Symbol table ‘.dynsym‘ contains 16 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000037d    20 FUNC    GLOBAL DEFAULT    7 _Z6func_3v
     2: 0000201f    31 OBJECT  GLOBAL DEFAULT   13 hello
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0
     4: 00002000    31 OBJECT  GLOBAL DEFAULT   13 hello2
     5: 00000390    12 FUNC    GLOBAL DEFAULT    7 __on_dlclose
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize
     7: 00002070     0 NOTYPE  GLOBAL DEFAULT   14 __dso_handle
     8: 00001ee0     0 NOTYPE  GLOBAL DEFAULT    9 __INIT_ARRAY__
     9: 00001ee8     0 NOTYPE  GLOBAL DEFAULT   10 __FINI_ARRAY__
    10: 000003a1    16 FUNC    GLOBAL DEFAULT    7 _Z6func_1v
    11: 00002052    20 OBJECT  GLOBAL DEFAULT   13 str_3
    12: 0000203e    20 OBJECT  GLOBAL DEFAULT   13 str_2
    13: 00002066     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    14: 00002066     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    15: 00002080     0 NOTYPE  GLOBAL DEFAULT  ABS _end

case 2,仍使用LOCAL_STATIC_LIBRARIES宏,libstone_2.cpp的代碼修改為:

char hello2[] = "this is a string in libstone_2";extern char str_2[];void func_3(){str_2[0]+=1;}

這個時候readelf的結果是:

 

readelf -Ws system/lib/libstone_2.so 
Symbol table ‘.dynsym‘ contains 16 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000037d    20 FUNC    GLOBAL DEFAULT    7 _Z6func_3v
     2: 0000201f    31 OBJECT  GLOBAL DEFAULT   13 hello
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0
     4: 00002000    31 OBJECT  GLOBAL DEFAULT   13 hello2
     5: 00000390    12 FUNC    GLOBAL DEFAULT    7 __on_dlclose
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize
     7: 00002070     0 NOTYPE  GLOBAL DEFAULT   14 __dso_handle
     8: 00001ee0     0 NOTYPE  GLOBAL DEFAULT    9 __INIT_ARRAY__
     9: 00001ee8     0 NOTYPE  GLOBAL DEFAULT   10 __FINI_ARRAY__
    10: 000003a1    16 FUNC    GLOBAL DEFAULT    7 _Z6func_1v
    11: 00002052    20 OBJECT  GLOBAL DEFAULT   13 str_3
    12: 0000203e    20 OBJECT  GLOBAL DEFAULT   13 str_2
    13: 00002066     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    14: 00002066     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    15: 00002080     0 NOTYPE  GLOBAL DEFAULT  ABS _end
可以看到,不僅僅是被引用到的str_2,所有在libstone_1中的global變數都被連結到libstone_2中。

所以可以得到如下的結論:

 

是否連結到調用者模組 使用了靜態庫的global變數 不使用
LOCAL_STATIC_LIBRARIES  Y N
LOCAL_WHOLE_STATIC_LIBRARIES  Y Y

 

 

至於android的編譯系統是怎麼處理這兩個宏的,在./build目錄發現其實使用了gcc的參數來區分(in core/definitions.mk ):

1161         -Wl,--whole-archive \
1162         $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
1163         -Wl,--no-whole-archive \
1164         $(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \

 

綜上所述,audio_policy.xxx.so這個policy庫使用的是自己的audio_policy_hal.cpp源檔案。

 

原文地址:http://blog.csdn.net/darkengine/article/details/9720131#

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.