android JNI(1)- gelf_update_phdr(): invalid data

关于JNI的基本使用方法,网络上有很多文章。我只想把我最近遇到的关于JNI的问题总结一下。

 

在android 源码下创建一个工程,将源文件拷贝到工程目录的 apps和jni文件夹下。

工程的Android.mk文件为

LOCAL_PATH := $(call my-dir)
LIB_COMMC_INCLUDE := $(LOCAL_PATH)/../../bionic/libc/include
include $(CLEAR_VARS)

LOCAL_SRC_FILES:=/
./apps/bdk_app_demo.c/
./apps/bdk_app_generic.c/
./apps/bdk_app_spp_c.c/
./apps/bdk_app_spp_drv.c/
./apps/bdk_app_spp_s.c/
./apps/bdk_app_sys.c/
./apps/iconv.c/
./apps/bdk_app_ui_data.c/
./apps/cheat_fun.c/
./jni/jnimain.c

LOCAL_C_INCLUDES:=/
    $(JNI_H_INCLUDE)/
    $(LOCAL_PATH)/inc/
    $(LOCAL_PATH)/apps/
    $(LIB_COMMC_INCLUDE)

LOCAL_STATIC_LIBRARIES:=/

libcutils

LOCAL_LDFLAGS+=

       $(LOCAL_PATH)/lib/libgeneric.a/
        $(LOCAL_PATH)/lib/libstack.a/
        $(LOCAL_PATH)/lib/libsys.a/
        $(LOCAL_PATH)/lib/libusb.a

LOCAL_PRELINK_MODULE:=false
LOCAL_MODULE:=libhello

include $(BUILD_SHARED_LIBRARY)

 

工程源文件如LOCAL_SRC_FILES所示,除了libc库外,还包括了四个外部链接库libgeneric.a libstack.a libsys.a libusb.a, 这四个库为第三方得到,而且已经被证明在android平台上可用的。

模块名由LOCAL_MODULE=libhello指定,include $(BUILD_SHARED_LIBRARY)表示目标模块被编译为动态库,JNI要求Native代码编译为动态库供虚拟机加载。

 

配置好工程的源文件和Android.mk后,执行make libhello SHOW_COMMANDS=a; 经过分析android的build系统,我发现只要将SHOW_COMMANDS设置为一个非空的字符串,就可以在make 的过程中将Makefile命令执行的内容打印。虽然android build系统提供了一个showcommands命令来完成同样的工作,我习惯了用前面的方式。

 

最初的build出现了一个错误,build log显示为:

target non-prelinked: libhello (out/target/product/generic/symbols/system/lib/libhello.so)
out/host/linux-x86/bin/acp -fpt
out/target/product/generic/obj/SHARED_LIBRARIES/libhello_intermediates/LINKED/libhello.so
out/target/product/generic/symbols/system/lib/libhello.so
target Strip: libhello (out/target/product/generic/obj/lib/libhello.so)
out/host/linux-x86/bin/soslim --strip --shady --quiet
out/target/product/generic/symbols/system/lib/libhello.so --outfile
out/target/product/generic/obj/lib/libhello.so
external/elfcopy/elfcopy.c(1097): gelf_update_phdr(): invalid data
make: *** [out/target/product/generic/obj/lib/libhello.so] Error 1
make: *** Deleting file `out/target/product/generic/obj/lib/libhello.so'

 

错误行为external/elfcopy/elfcopy.c(1097): gelf_update_phdr(): invalid data

 

从源代码结构以及上面的 Log可以看到,elfcopy是 soslim模块的一部分, soslim是源代码目录toolchain工具arm-eabi-strip的替代工具,功能是为了去除库中多余的符号和调试信息,为动态库瘦身。

 

通过分析make输出的日志。动态库的生成包括几个过程:

1 设置目标和主机相关的变量(包括编译器选择,基本编译选项设置以及其他build变量设置)

2 读取所有模块的Android.mk,生成各模块的build规则。

3 执行libhello的build过程

   编译源文件

   连接目标文件为动态库

   使用soslim为动态库瘦身

   将瘦身的libhello 复制到输出文件夹

 

当前的错误出现在步骤3的瘦身过程。好在android Developer的mail list中,看到有帖子遇到了同样的问题,在发言中有人建议使用gcc 4.2.4以下版本生成目标文件。 android build system默认使用gcc 4.2.1版本编译器。最后发现那四个第三方库使用的是gcc 4.3.1编译器生成, 重编那四个lib库, 问题解决了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值