經驗總結---編譯出可以在Android上執行的可執行檔案
作為一手包攬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
版權宣告:本文為博主原創文章,轉載請附上博文連結!