博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LOCAL_WHOLE_STATIC_LIBRARIES与LOCAL_STATIC_LIBRARIES的区别
阅读量:5917 次
发布时间:2019-06-19

本文共 5537 字,大约阅读时间需要 18 分钟。

在分析Jelly Bean Audio Subsystem的时候,发现HAL层的库audio_policy.xxx.so与其依赖的静态库libaudiopolicy_legacy.a都有audio_policy_hal.cpp这个源文件而且两者都定义了一个HMI。当调用者引用HMI的时候,调用的究竟是哪个呢?

 

首先看audio_policy.xxx.so的.mk文件,在定义编译audio_policy.xxx.so的段落里面有这么一句:

LOCAL_STATIC_LIBRARIES := \

     libaudiohw_legacy \
     libmedia_helper \
     libaudiopolicy_legacy

说明libaudiopolicy_legacy是以静态库的形式为audio_policy.xxx.so所用,而在通用的audio_policy库(也可以说是谷歌提供给厂商参考用的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这两个宏的差异上面。先看下谷歌在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如下

 

 
1 LOCAL_PATH := $(call my-dir)   2 include $(CLEAR_VARS)   3    4 LOCAL_SRC_FILES := \   5     libstone_1.cpp   6    7 LOCAL_MODULE := libstone_1   8 LOCAL_MODULE_TAGS := optional   9   10 include $(BUILD_STATIC_LIBRARY)  11   12 # =========================================  13 include $(CLEAR_VARS)  14   15 LOCAL_SRC_FILES := \  16     libstone_2.cpp  17   18 LOCAL_STATIC_LIBRARIES := libstone_1  19 # LOCAL_WHOLE_STATIC_LIBRARIES := libstone_1  20 LOCAL_MODULE := libstone_2  21 LOCAL_MODULE_TAGS := optional  22   23 include $(BUILD_SHARED_LIBRARY)

 

 

静态库源文件(libstone_1.cpp):

 

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

 

 

调用者源文件(libstone_2.cpp):

1 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 3,仍使用LOCAL_STATIC_LIBRARIES宏,libstone_2.cpp的代码修改为:

 

1 char hello2[] = "this is a string in libstone_2";  2   3 extern char str_2[];  4   5 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://fqfvx.baihongyu.com/

你可能感兴趣的文章
hdu 5053 the Sum of Cube(上海网络赛)
查看>>
Analyzer中进行货币转换
查看>>
2014年年终总结
查看>>
bat产生随机数并复制文件及生成文件列表
查看>>
【VLC-Android】vlc-android简例
查看>>
动态规划0—1背包问题
查看>>
List,Set,Map
查看>>
分享50款 Android 移动应用程序图标【下篇】
查看>>
RAID5和RAID10,哪种RAID更适合你(上)
查看>>
Reapp - 下一代的 Hybrid App 开发框架
查看>>
【BZOJ】1086: [SCOI2005]王室联邦
查看>>
tomcat启用压缩的方式
查看>>
简单工厂模式--工厂方法模式(简介)
查看>>
Kubernetes deployed on multiple ubuntu nodes
查看>>
鬼畜的多项式
查看>>
qsort()与sort的用法(收藏)
查看>>
SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)
查看>>
OAF_JDBC系列2 - 通过JDBC连接SQLSERVER数据库DriverManager.getConnection
查看>>
JBPM学习(六):详解流程图
查看>>
Android-L-Samples
查看>>