zoukankan      html  css  js  c++  java
  • 【转】如何把ndk编译出来的可执行文件伪装成so打包到apk中

    原文网址:http://jeyechao.iteye.com/blog/2164286

    ndk编译出来的共享库,eclipse会自动打包到apk中,而编译出来的可执行文件则不会。

    要想可执行文件自动被打包到apk中,可以把文件名改成libxxx.so的形式,伪装成so,这样就会被打包进apk。

    但是每次编译之后都改一下名字,太麻烦!

    写个脚本吧,又有arm, armv7, x86的麻烦事!

    想试着改LOCAL_MODULE_FILENAME来试试,NDK又不允许。

    于是稍微看了下NDK的编译脚本,发现如下解决办法。

    NDK是通过在Android.mk文件中include $(BUILD_EXECUTABLE)来编译可执行文件,其实就是调用了一个已经写好的脚本——build-executable.mk。(编译脚本都在NDK_ROOT/build/core目录里面)

    仔细看脚本的调用过程可以发现,脚本一开始先检查一下变量合法性(前面改LOCAL_MODULE_FILENAME的方法在这里过不去),最终调用include$(BUILD_SYSTEM)/build-module.mk来编译。

    于是研究这个脚本,找到决定编译输出的变量,在调用最终的编译脚本之前改成想要的就可以了。

    最终我的方案如下:

    1. 为了不破坏ndk本来的脚本,将build-executable.mk拷贝一份放在自己的工程目录下面,在倒数第三行插入一句 $(evalLOCAL_BUILT_MODULE := $(TARGET_OUT)/$(MY_LOCAL_MODULE_FILENAME))

    2. 在自己的Android.mk文件中定义MY_LOCAL_MODULE_FILENAME变量,当然值就是你想要的文件名啦

    3. 编译时不调用系统的include$(BUILD_EXECUTABLE), 而改调用自己的脚本(就是上面拷贝出来且做了修改的那个脚本),为了方便,你可以给自己的脚本定义一个变量来指向它。

    就是这样。

    写得比较乱,贴几段关键代码吧。

    修改后的build-executable.mk代码。

    Xml代码  收藏代码
    1. LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE  
    2. LOCAL_MAKEFILE     := $(local-makefile)  
    3.   
    4. $(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))  
    5. $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))  
    6. $(call check-LOCAL_MODULE_FILENAME)  
    7.   
    8. # we are building target objects  
    9. my := TARGET_  
    10.   
    11. $(call handle-module-filename,,)  
    12. $(call handle-module-built)  
    13.   
    14. $(eval LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(MY_LOCAL_MODULE_FILENAME))  
    15.   
    16. LOCAL_MODULE_CLASS := EXECUTABLE  
    17. include $(BUILD_SYSTEM)/build-module.mk  

     14行就是我们加的那一行。

     上面的文件放在jni根目录,跟目录下的Android.mk代码:

    Xml代码  收藏代码
    1. MY_BUILD_EXECUTABLE := $(JNI_ROOT)/build-executable.mk  
    2. include $(call all-subdir-makefiles)  

     需要编译可执行文件的模块这样写:

    Xml代码  收藏代码
    1. LOCAL_PATH := $(call my-dir)  
    2. include $(CLEAR_VARS)  
    3.   
    4. LOCAL_SRC_FILES := ...  
    5. LOCAL_MODULE := xxx  
    6. MY_LOCAL_MODULE_FILENAME := libxxx.so  
    7. LOCAL_C_INCLUDES := ...  
    8. LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog  
    9. LOCAL_CFLAGS := -fPIC  
    10.   
    11. include $(MY_BUILD_EXECUTABLE)  

     OK, 大功告成!

  • 相关阅读:
    gc buffer busy/gcs log flush sync与log file sync
    给Oracle年轻的初学者的几点建议
    Android 编程下帧动画在 Activity 启动时自动运行的几种方式
    Android 编程下 Touch 事件的分发和消费机制
    Java 编程下 static 关键字
    Java 编程下 final 关键字
    Android 编程下模拟 HOME 键效果
    Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
    Extjs4 大型项目目录结构重构
    [转]SQLServer 2008 允许远程连接的配置方法
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4308594.html
Copyright © 2011-2022 走看看