您的位置:首页 > 移动开发 > Android开发

Android 编译静态链接的可执行文件

2016-07-13 23:18 573 查看

Android 编译静态链接的可执行文件

在Android 开发与调试过程中往往遇到以下两种场景,导致我们编译的可执行程序无法运行:

不支持动态链接,比如系统初始化进程init和Recovery模式下执行的recovery,它们在执行的时候,往往不会挂载/system分区,不存在ld和ldd.so等动态加载工具和C库,这样的可执行程序往往需要静态链接。

一些辅助测试的工具程序。比如busybox等,如果是动态链接的话,依赖的库的接口如有变化,往往会导致程序无法执行。一般都是静态链接,一次编译后,可以随时执行。

那么在Android 中如何编译一个静态链接的可执行程序呢?

其实非常简单,我们仿照源码中的bootable/recovery/Android.mk,简化出如下的编译模板:

LOCAL_PATH := $(call my-dir)
#复位编译参数
include $(CLEAR_VARS)
#指定模块名
LOCAL_MODULE := module_name
#标志该模块需要强制静态链接
LOCAL_FORCE_STATIC_EXECUTABLE := true
#指定额外的编译、链接参数
LOCAL_CFLAGS +=
#编译源文件列表
LOCAL_SRC_FILES :=
#该模块需要链接的静态库列表,这里千万别忘记需要静态链接libc
LOCAL_STATIC_LIBRARIES := libc \
....
#编译成可执行文件
include $(BUILD_EXECUTABLE)


其中核心的就两句:

LOCAL_FORCE_STATIC_EXECUTABLE := true 表明该模块需要静态链接

LOCAL_STATIC_LIBRARIES := 给出该模块需要链接的静态库列表。

编译指令还是include $(BUILD_EXECUTABLE)

如何判断一个可执行程序是动态链接还是静态编译的呢?可以通过file指令。

如下图,recoery是静态链接的(statically linked).

david@david-Macmini:~/work-dir/android601_r46/out/target/product/mini-emulator-x86/root$ file init
init: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[md5/uuid]=02402d7e0969337b0240427f8bbe25c0, stripped


而sh是动态链接的,使用动态库(dynamically linked (uses shared libs))。

david@david-Macmini:~/work-dir/android601_r46/out/target/product/mini-emulator-x86/system/bin$ file sh
sh: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), BuildID[md5/uuid]=ac75e2c45ea4e5b8971720f877bc35c1, stripped
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: