作为一手包揽Ubuntu和Android设备的初级开发者,我不止一次地尝试把这两个同是用Linux内核的操作系统统一起来——让Ubuntu下的可执行程序能够在Android设备上运行。于是我不止一次地尝试,不止一次地查找资料,终于如愿以偿。

我把我的经验在这里与大家分享。

准备工具

【宿主机】

(1)glibc-arm2.1.7库文件——让Android系统能够跑起自己编译好的程序

(2)arm-linux-gcc4.4.3——嵌入式ARM系统的应用程序编译器,这个就不必多说了。运行之前请务必保证设置好环境变量。

【Android设备】

(1)要求已经Root——在没有开启Root权限的情况下,本教程中编译好的程序会无法运行,出现Segmentation Fault的错误。

(2)RE管理器——Android上的文件管理工具,在这里用于复制文件

(3)终端模拟器(建议用Terminal Emulator)——用于调试我们的程序

具体步骤

1.在宿主机上,通过预先用arm-linux-gcc编译,获取程序解释器和共享库文件名

a.在终端中运行:

arm-linux-gcc-o <输出文件名><源代码文件名>

得到可执行文件

b.在终端中运行:

readelf -l <输出文件名>

仔细找找,就可以找到程序解释器的文件名了。一般用方括号扩起,并有”interpreter”(程序解释器)的注明。

c.运行

readelf -d <输出文件名>

在输出结果中找到”NEEDED”一行。该行最右边就是共享库的文件名。有多少个文件名就有多少个共享库。

d.搞定之后,把输出文件删掉。

之所以要进行这一步,是因为不同的程序对应的程序解释器可能不同。

2.在宿主机上用arm-linux-gcc正式编译出可执行文件

这一步编译出来的可执行文件是要直接放到设备上运行的。

必须使用以下格式:

arm-linux-gcc-o <输出文件名> <源代码文件名> -Wl,-dynamic-linker=/yourpath/<程序解释器文件名>

其中:-dynamic-linker后接程序解释器在设备上的完整路径(注意:不是宿主机上面的路径),下文中该路径直接简称为yourpath。

3.把程序解释器、共享库复制出来

进入glibc-arm解压目录中的”lib”文件夹,在其中找到我们之前看到的几个文件。

值得注意的是,一般情况下,glibc-arm的一些库文件会用符号链接,指向另外的库文件。在文件管理器中,符号链接是带有小箭头的。可以通过右击符号链接,选择“属性”,看到它们的对应关系。

如:

ld-linux.so.3==>ld-2.17.so

libc.so.6==>libc-2.17.so

这时我们要把被链接的库文件复制出来,不能只复制带有小箭头的符号链接,否则等于没复制!

4.把可执行文件和库文件复制到设备中。

(1)把可执行文件放到system、data、cust这些分区中(它们使用的是ext3、yaffs2等文件系统,对Linux命令兼容较好。放到FAT文件系统中很容易出现各种PermissionDenied)。然后设置权限为rwxrwxrwx.

(2)安放程序解释器

a。用RE管理器把被链接的程序解释器库文件放到system、data、cust这些分区的任意目录中,记下它所在的路径。

b.接着设置其权限为rwxrwxrwx。(长按该文件,选择“权限”)

c。打开终端,输入:ln-s <被链接的程序解释器库文件名完整路径>/<该库文件的文件名>/yourpath/<程序解释器库文件名>

在设备上建立符号链接。这样就安放好了。

注:Ubuntu下不方便用adb,所以我的做法是:打开设备的USB存储连接,把需要的文件统统拷进去,剩下的复制粘贴、符号链接建立就用RE管理器了。

(3)把共享库放到Android的库目录中

Android系统可用的库目录有/system/lib,/vendor/lib,用哪个都行。可在设备上打开终端模拟器,运行echo$LD_LIBRARY_PATH查看。(值得注意的是,在没有运行su的情况下,会看到不止一个目录;但是在su之后,只能使用上述的两个目录。)

安放的方法和(2)类似:

a.用RE管理器把被链接的共享库文件放到/system/lib或/vendor/lib目录中。

b.接着设置其权限为rwxrwxrwx。

c.打开终端,输入:

ln -s <被链接的共享库文件名完整路径>/<该库文件的文件名> /system/lib/<共享库文件名>

或输入:

ln -s <被链接的共享库文件名完整路径>/<该库文件的文件名> /vendor/lib/<共享库文件名>

在设备上建立符号链接。这样就安放好了。

4.在设备上打开终端模拟器进行调试

先运行su,打开root权限,然后切换到可执行文件所在的目录,输入

./<可执行文件名>
回车,即可看到效果。

如果觉得上面的步骤看起来有些晕,不妨看看我在下面举的具体例子!

实例说明

我打算把下面的这段C源代码编译出来,放到我的Android手机上面运行:

【代码内容】

#include<stdio.h>
 
int main()

int i=0;
 printf("HELLO ANDROID!");
 for(i=0;i<=100;i++)
   printf("%d ",i);
printf("END");
return 0;
}

【可执行文件放在】/system/

【可执行文件名】hello4

【程序解释器放在】/system/(我把文件放到/vendor/lib/)

【共享库文件放在】/vendor/lib/

【宿主机上的工作目录】/home/administrator/complie/

【具体步骤】

1.预先编译。

在终端中输入:

arm-linux-gcc-o hello41 hello.c

得到临时的可执行文件hello41。

然后运行

readelf -l hello41
得知程序解释器的名字(ld-linux.so.3)。再运行readelf-d hello41,得知共享库的名字(libc.so.6)。

如图所示:

2.正式编译

在终端中运行:

arm-linux-gcc-o hello4 hello.c-Wl,-dynamic-linker=/system/lib-linux.so.3
回车即得输出的可执行文件hello4.

3.找到库文件

进入glibc-arm解压目录的lib子目录,找到lib-linux.so.3和libc.so.6两个文件。但它们是带有小箭头的符号链接。

这时右击lib-linux.so.3,选择“属性”,查看它链接到的文件,是ld-2.17.so;类似地,得知libc.so.6链接到的文件是libc-2.17.so。

把ld-2.17.so和libc-2.17.so复制出来。

4.把文件复制到设备上。

连上手机,打开USB存储设备,把可执行文件hello4,和上面的两个库文件ld-2.17.so和libc-2.17.so都复制到设备的SD卡中。接着关闭USB存储设备,稍等片刻打开RE管理器:

把可执行文件hello4复制到/system/目录中,然后长按该文件,选择“权限”,把上面的9个勾全部勾上(也就是设置rwxrwxrwx权限)。

同理,把ld-2.17.so和libc-2.17.so复制到/vendor/lib/中,用同样的方法设置权限为rwxrwxrwx。

接着打开终端模拟器建立符号链接,运行:

su                                                  //打开管理员权限
 
ln-s /vendor/lib/ld-2.17.so /system/ld-linux.so.3
 
ln-s /vendor/lib/libc-2.17.so /vendor/lib/libc.so.6

就可以了。

P.S.以上创建符号链接的操作也可以用RE管理器搞定,方法:长按文件,把菜单拖到最下面,选择”链接到文件”,进到需要创建符号链接的目录,点击“创建链接”,最后按上面ln命令的写法给符号链接重命名就可以了。

5.打开终端模拟器测试

依次输入

su            //打开管理员权限
 
cd system     //切换到/system目录
 
./hello4      //运行程序

就可以成功看到如下的运行结果:

至此,顺利成功!

相关资源

glibc-arm 库文件:http://download.csdn.net/detail/remme123/5422131  (感谢remme提供)

参考资料

[1]基于glibc的程序在android上的移植—转,andy_1982,http://www.eoeandroid.com/thread-22046-1-1.html

[2][11]缺少动态连接库.so--cannotopen shared object file: No such file or directory,SmartVessel,http://www.cnblogs.com/smartvessel/archive/2011/01/21/1940868.html

[3]bash:***: No such file or directory , seamus,http://blog.csdn.net/dlutxie/article/details/8645051

[4]关于-/bin/sh:命令:notfound的解决办法,micheal7500,http://blog.chinaunix.net/uid-20539088-id-115759.html

--------------------- 
作者:爱拼安小匠 
来源:CSDN 
原文:https://blog.csdn.net/u012303373/article/details/37694597 
版权声明:本文为博主原创文章,转载请附上博文链接!

经验总结---编译出可以在Android上执行的可执行文件相关推荐

  1. 一套代码编译出ios和android,Hippy: Hippy 是一个新生的跨端开发框架,目标是使开发者可以只写一套代码就直接运行于三个平台(iOS、Android 和 Web)...

    Hippy 跨端开发框架 介绍 Hippy 是一个新生的跨端开发框架,目标是使开发者可以只写一套代码就直接运行于三个平台(iOS.Android 和 Web).Hippy 的设计是面向传统 Web 开 ...

  2. Mac上执行Linux可执行文件报错:cannot execute binary file

    问题 在Mac上执行一个Linux可执行程序.出现以下报错:-bash: xxx: cannot execute binary file 解决 在Linux系统上执行,或在Mac上安装虚拟机.

  3. android游戏基址,Android上可执行ELF文件中的段不能有基址

    Android上可执行ELF文件中的段不能有基址 @(Android研究)[android] [TOC] 场景 我使用Android NDK的编译工具交叉编译qemu项目(编译可在Android上运行 ...

  4. android.mk 添加v7_在Android上以命令行方式移植FFmpeg

    最近要做视频I帧提取和摘要生成的项目,在Android平台上的应用,经过调研,发现ffmpeg有很多相关功能的轮子,因此考虑将ffmpeg移植到Android平台.为了更好解耦和以及更多的文档参考,选 ...

  5. 编译可在Android上运行的qemu user mode

    前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码. 下文中的"NDK"若无特殊说明均指"Android ...

  6. android如何编译出带符号表的.so库

    android如何编译出带符号表的.so库 关于这个问题,其实编译器带-g就会有调试信息.这是gcc相关的. 默认其实android编译的就是带符号表的,只是在strip掉了. 例如下面的操作: /$ ...

  7. android通过c调用shmat函数,编译可在Android上运行的qemu user mode

    编译可在Android上运行的qemu user mode @(Android研究)[android|qemu] [TOC] 前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编 ...

  8. Go编译android,go语言的程序跑在android上

    之前写了一个检查页面的golang程序http://www.simonzhang.net/?p=1346.就用这个测试一下放到android上看看效果如何.但是我在windows上的golang还是产 ...

  9. android系统源码7.1.2_r8下载,编译,运行到nexus5X上,修改源码并编译SDK进行测试

    一,学习android系统源码下载,编译的作用 1,可以自己 DIY 自己的rom系统,从系统层面,宏观的加深理解 android系统 2,编译自己的 userdebug(原生root权限) rom, ...

最新文章

  1. Applet相关知识
  2. 第八周实践项目 5 计数的模式匹配
  3. android正则表达式隐藏邮箱地址中间字符
  4. Gentoo 安装日记 05 (磁盘分区)
  5. 关于本人在多个技术平台发布文章的声明
  6. mysql 的 sql 执行计划详解
  7. ubuntu命令行登录
  8. 中科院博士返乡卖汉服:3个月卖了300万,预计全年能破1500万
  9. MVC 模式和模型 2
  10. Android笔记-ERROR: Invalid revision: 3.17.20200511-g8787079
  11. ANSYS CFD网格划分笔记1
  12. phpstudy php乱码,PHP_完美解决PHP中文乱码,一.首先是PHP网页的编码 1. php - phpStudy...
  13. 平房误差函数_平方误差函数(square error function)与平方损失函数(square loss function)...
  14. 图像深度:8bit、16bit、24bit、32bit; 16.7M色彩
  15. OpenCV入门系列 —— boxFilter盒子滤波
  16. 华为云跨服务器传输文件,云服务器传输文件
  17. 微信小程序:长期稳定短视频去水印
  18. html设置网页标题栏logo(图标)
  19. 建筑工程人转行之路续篇(五年后)
  20. B/S架构的HIS系统与EMR系统界面

热门文章

  1. Godaddy ssl证书配置到nginx
  2. 如何清除360网站服务器缓存,360浏览器怎么清除缓存 360浏览器打不开网页怎么办...
  3. 2021 OpenCV人工智能竞赛优秀项目团队介绍集锦(二)
  4. linux中管道符号和追加符号(覆盖符号)的用法简介
  5. 远程鼠标,键盘,云鼠标
  6. 用汇编实现2进制到16进制 2进制到10进制转换并按要求输出
  7. Docker部署nginx
  8. PHP unset浅谈
  9. 易安卓打开Android系统中的解锁方式选择页面(锁屏方式选择)
  10. Qt多线程开发(QThread)