這幾個月處理一些跑在 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。