perlandroid - 在 Android 下的 Perl
本文件的前幾部分包含使用 Google 提供的二進制文件為 Android 2.0 及更高版本交叉編譯 Perl 的說明。後幾部分描述了如何使用 Play Store 上可用的工具鏈之一構建本機 perl。
本文件描述了當嘗試為 Android 構建 Perl 時如何設置主機環境。
這些說明假定您的主機系統上有一個類 Unix 的構建環境; 它們已在 Linux 和 OS X 上進行了測試,可能也適用於 Cygwin 和 MSYS。雖然 Google 也為 Windows 提供了一個 NDK,但這些步驟在該系統上無法本地運行,儘管可能可以通過不同的方法進行交叉編譯。
如果您的主機系統架構是32位元,請記得將下面的 x86_64
更改為 x86
。在同樣的情況下,下面的範例使用了4.8工具鏈;如果您想使用更新或舊版本(例如,NDK第8版中包含的4.4.3工具鏈),只需將其更改為相應版本即可。
您可以從https://developer.android.com/tools/sdk/ndk/index.html 下載 NDK。您將需要普通的非遺留版本。
有三種可能的選擇:arm-linux-androideabi 用於 ARM、mipsel-linux-android 用於 MIPS,以及簡單的 x86 用於 x86。截至2014年,大多數 Android 設備都在運行 ARM,因此通常是一個安全的選擇。
有了這兩者後,您應該將
$ANDROID_NDK/toolchains/$TARGETARCH-4.8/prebuilt/`uname | tr '[A-Z]' '[a-z]'`-x86_64/bin
添加到您的 PATH
中,其中 $ANDROID_NDK
是您解壓 NDK 的位置,而 $TARGETARCH
是您的目標架構。
這將創建一個可供稍後傳遞給 Configure 的工作 sysroot。
$ export ANDROID_TOOLCHAIN=/tmp/my-toolchain-$TARGETARCH
$ export SYSROOT=$ANDROID_TOOLCHAIN/sysroot
$ $ANDROID_NDK/build/tools/make-standalone-toolchain.sh \
--platform=android-9 \
--install-dir=$ANDROID_TOOLCHAIN \
--system=`uname | tr '[A-Z]' '[a-z]'`-x86_64 \
--toolchain=$TARGETARCH-4.8
adb 是 Android 調試橋。對於我們的目的來說,它基本上是一種在 Android 設備上建立 ssh 連接的方式,而無需在設備本身上安裝任何東西,只要設備與主機位於同一局域網,或者通過 USB 連接到主機即可。
Perl 可以使用 adb 或正常的 ssh 連接進行交叉編譯;一般來說,如果您可以通過 USB 端口將設備連接到主機,或者如果您不想在設備上安裝 sshd 應用,您可能想使用 adb,盡管如果您的設備未 root 和您不幸的話,您可能被迫切換到 ssh -- 更多信息稍後會提到。或者,如果您要對模擬器進行交叉編譯,則必須使用 adb。
要使用 adb,請從https://developer.android.com/sdk/index.html 下載 Android SDK。僅 "SDK Tools Only" 版本應該足夠 -- 如果您下載了 ADT Bundle,您可以在 $ADT_BUNDLE/sdk/ 下找到 sdk。
將 $ANDROID_SDK/platform-tools 添加到您的 PATH
中,這將使您能夠訪問 adb。現在您將不得不使用 adb devices
找到您的設備名稱,然後將其傳遞給 Configure 通過 -Dtargethost=$DEVICE
。
但是,在調用 Configure 之前,您需要檢查首先使用 adb 是否是一個可行的選擇。因為 Android 沒有 /tmp,也不允許在 sdcard 中執行可執行文件,我們需要在設備中找到一個地方,讓 Configure 放置一些文件以及運行測試。如果您的設備已 root,那麼您沒問題。嘗試運行這些命令
$ export TARGETDIR=/mnt/asec/perl
$ adb -s $DEVICE shell "echo sh -c '\"mkdir $TARGETDIR\"' | su --"
這將創建我們需要的目錄,然後您可以進入下一步。 /mnt/asec 在 Android 中掛載為 tmpfs,但只能由 root 訪問。
如果您的設備未 root,您仍然有可能運氣好。嘗試運行這個
$ export TARGETDIR=/data/local/tmp/perl
$ adb -s $DEVICE shell "mkdir $TARGETDIR"
如果命令成功運行,您可以進入下一步,但請注意:完成後您將不得不從設備中刪除該目錄!與 /mnt/asec 不同,一旦您關閉手
如果這些方法都不起作用,那麼您就無法使用adb對您的設備進行交叉編譯。請嘗試進行root權限處理,或者採用ssh路徑。
要使用ssh,您需要安裝並運行一個ssh服務器應用程序,並將其設置正確。有幾個付費和免費應用程序可以輕鬆完成此操作,因此您應該能夠在應用商店找到一個。請記住,Perl需要一個無需密碼的連接,因此請設置一個公共密鑰。
請注意,有些應用程序每次連接時都會將垃圾信息輸出到stderr,這可能會影響Configure的正常運行。您可能需要對創建run-ssh
的Configure部分進行一些修改,使其丟棄stderr。
由於您使用ssh,您將不得不向Configure傳遞一些額外的參數
-Dtargetrun=ssh -Dtargethost=$TARGETHOST -Dtargetuser=$TARGETUSER -Dtargetport=$TARGETPORT
在完成所有前期準備後,您現在可以調用Configure。
如果使用adb,"基本"的Configure命令行將如下所示
$ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=adb \
-Dcc=$TARGETARCH-gcc \
-Dsysroot=$SYSROOT \
-Dtargetdir=$TARGETDIR \
-Dtargethost=$DEVICE
如果使用ssh,情況並沒有太大不同--我們只是將目標更改為ssh,並傳入目標用戶和目標端口。結果看起來是這樣的
$ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=ssh \
-Dcc=$TARGETARCH-gcc \
-Dsysroot=$SYSROOT \
-Dtargetdir=$TARGETDIR \
-Dtargethost="$TARGETHOST" \
-Dtargetuser=$TARGETUSER \
-Dtargetport=$TARGETPORT
現在您可以運行make
和make test
了!
作為最後的警告,如果您使用adb,make test
可能會看起來停滯不前;這是因為直到運行所有測試結束之前它才不會輸出任何內容。您可以通過登錄設備,轉到$TARGETDIR,並查看文件output.stdout來檢查其進度。
如果您的目標是x86 Android,您將不得不將$TARGETARCH-gcc
更改為i686-linux-android-gcc
。
在一些舊的低端設備上--比如早期2.2時代--一些測試,特別是t/re/uniprops.t,可能會導致手機崩潰,導致其關機一次,然後重新開機。
儘管Google沒有為Android提供本機工具鏈,但您仍然可以從Play Store獲得一個。
您可能能夠獲取CCTools應用程序,它是免費的。請記住,您需要一個完整的工具鏈;一些應用程序往往默認僅安裝一個簡化版本,缺少一些重要的工具,如ar或nm。
一旦您正確設置了工具鏈,唯一剩下的障礙就是確定它被安裝在設備的哪個位置。例如,CCTools將其工具鏈安裝在/data/data/com.pdaxrom.cctools/root/cctools中。有了這個路徑,編譯perl就不過是
export SYSROOT=<location of the native toolchain>
export LD_LIBRARY_PATH="$SYSROOT/lib:`pwd`:`pwd`/lib:`pwd`/lib/auto:$LD_LIBRARY_PATH"
sh Configure -des -Dsysroot=$SYSROOT -Alibpth="/system/lib /vendor/lib"
Termux 提供一個 Android 終端模擬器和 Linux 環境。它已經安裝了一個跨平台編譯的 Perl。
本地編譯 Perl 5.30 或更新版本應該是非常直接的:
sh Configure -des -Alibpth="/system/lib /vendor/lib"
這在至少 Android 8.1(Oreo)上是有效的...
Brian Fraser <fraserbn@gmail.com>