这几个月处理一些跑在 Embedded System 的小工具、小服务,每次 porting 后,总要计算一下程式的大小,这时计算的原理就是用 ldd、objdump 或 readelf 看一下呼叫了哪些 shared library,把他们加一加就差不多了。然而,需要留意的则是 shared library 还会在 link 其他 shared library,所以用到的 shared library 也要一并挑出来查看一下才行。

不知不觉就写了 script 来处理,原理就是建 hash 来判断 shared library 判断过了没。

$ git clone https://github.com/changyy/resource-calculator.git
$ ./resource-calculator/resource-calculator.sh
Usage> ./resource-calculator.sh -v -r path_bin_readelf -s path_bin_strip -o output_dir -l path_for_library_finding  [ BIN_FILE | BIN_DIR | LIB_FILE | LIB_DIR ] ...

其中 -r 是吃 readelf 工具位置,可以用 -r `which armv6-linux-gnueabi-readelf`;-s 是指定 strip 位置,也就是产出时顺便 strip 一下;-o 则是输出到指定输出目录;-l 是指定读取 shared library 位置,如 cross compiler 的 library 位置、platform sysroot/lib 位置和第三方 shared library 位置等;最后的参数则是要验证的 tool 或 library ,若接目录则是进去捞 bin 或 so 出来。

实例 (已在 PATH 环境变数中加入 cross compiler 的搜寻位置):

$ ./resource-calculator/resource-calculator.sh -o /tmp/output -r `which armv6-linux-gnueabi-readelf` -s `which armv6-linux-gnueabi-strip` -l /path/armv6-linux-gnueabi/compiler/lib -l /path/armv6-linux-gnueabi/platform/sysroot/lib -l /path/armv6-linux-gnueabi/3rd-party/lib /path/imagemagick-convert

[INFO] READELF: /path/armv6-linux-gnueabi-readelf
[INFO] STRIP: /path/armv6-linux-gnueabi-strip
[INFO] OTHER LIB: /path/armv6-linux-gnueabi/compiler/lib /path/armv6-linux-gnueabi/platform/sysroot/lib /path/armv6-linux-gnueabi/3rd-party/lib
[INFO] TARGET: /path/imagemagick-convert
[INFO] OUTPUT: /tmp/output/lib /tmp/output/bin /tmp/output/slib
-------------
..............*...............*
All:
       libdl.so.2 libm.so.6 librt.so.1 libpthread.so.0 libMagickWand-6.Q8.so.1 libgcc_s.so.1 libjpeg.so.62 libpng10.so.0 libtiff.so.5 libz.so.1 libMagickCore-6.Q8.so.1 libc.so.6 ld-linux.so.3 libxml2.so.2 libgomp.so.1

$ du -h /tmp/output/
6.7M    /tmp/output/lib
1.9M    /tmp/output/slib
12K     /tmp/output/bin
8.5M   /tmp/output/

$ ls -R /tmp/output/
/tmp/output/:
bin  lib  slib

/tmp/output/bin:
convert

/tmp/output/lib:
libdl.so.2     libMagickCore-6.Q8.so.1  libtiff.so.5
libgomp.so.1   libMagickWand-6.Q8.so.1  libxml2.so.2
libjpeg.so.62  libpng10.so.0            libz.so.1

/tmp/output/slib:
ld-linux.so.3  libc.so.6  libgcc_s.so.1  libm.so.6  libpthread.so.0  librt.so.1

故程式运行时所需的 size 是 8.5MB ,但其中有 sysroot libraries 为 1.9MB ,所以移植到板子上的程式码大小 = 8.5MB - 1.9MB。


相关文章