![](/img/trans.png)
[英]Is it possible to run a native arm binary on a non-rooted android phone?
[英]Want to compile native Android binary I can run in terminal on the phone
幾天來,我一直在嘗試編譯一個本機 ARM Android 二進制文件,該二進制文件將使用終端應用程序在我的手機上執行。 我想生成與安裝在手機上的標准 Posix 二進制文件(如 ls、mkdir 等)相同類型的二進制文件。我已經在 Mac OS X 下下載了 Android NDK,並且能夠編譯簡單的 ELF 二進制文件而不會出錯。 但是,當我將它們轉移到手機時,它們總是出現段錯誤。 也就是說,在 GCC 中使用 -static 編譯時會出現段錯誤。 如果我不使用 -static,他們會抱怨沒有被鏈接,等等。簡單地說,他們不工作。
我的假設是它們沒有正確鏈接到 Android 標准 C 庫。 即使我將我的二進制文件與 NDK 提供的 libc 鏈接起來,它們仍然不起作用。 我讀到 Android 使用 Bionic C 庫,並嘗試下載它的源代碼,但我不確定如何從中構建一個庫(似乎都是 ARM 程序集)。
手機上的Android C庫和Android NDK提供的庫是不是真的不一樣? NDK 中包含的那個是否不允許我編譯可以通過終端執行的本機二進制文件? 非常感謝這里的任何指導!
更新:
我終於在 Mac OS X 上使用 GCC 4.7.0 讓它工作了。我下載了 Bionic 頭文件,然后使用 Android NDK 附帶的 C 庫編譯了一個動態鏈接的二進制文件。 我能夠使用手機的 C 庫(二進制文件為 33K)讓測試應用程序在手機上運行。 我還嘗試靜態鏈接到 NDK 的 C 庫,這也有效。
為了讓這一切正常工作,我必須將 -nostdlib 傳遞給 GCC,然后手動將 crtbegin_dynamic.o 和 crtend_android.o 添加到 GCC 的命令行。 它的工作原理是這樣的:
$CC \
$NDK_PATH/usr/lib/crtbegin_dynamic.o \
hello.c -o hello \
$CFLAGS \
$NDK_PATH/usr/lib/crtend_android.o
對於靜態二進制文件,使用“crtbegin_static.o”。 這在 crtbegin_dynamic.S/crtbegin_static.S 源中進行了解釋。
對於這個實驗,我只使用了普通的 'ol GCC 4.7.0 和 Binutils 2.22。 我還用 newlib 編譯了 GCC,但我實際上並沒有將我的 ARM 二進制文件與 newlib 鏈接。 我強制 GCC/ld 直接鏈接到 Android NDK 提供的 libc,或者在動態二進制文件的情況下,鏈接到手機上的 libc。
只需使用 android-ndk。 並像這樣構建一個Android.mk。 include $(BUILD_EXECUTABLE)
告訴它構建可執行文件而不是 JNI .lib
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wall
LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g
LOCAL_C_INCLUDES := bionic
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES:= main.cpp
LOCAL_MODULE := mycmd
include $(BUILD_EXECUTABLE)
endif # TARGET_SIMULATOR != true
首先,確保您有 NDK:
http://developer.android.com/tools/sdk/ndk/index.html
這是為您的手機編譯 C 二進制文件的最簡單方法:
http://developer.android.com/tools/sdk/ndk/index.html
http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html
通常$NDK(可能不同)=
Linux:
/home/ <user>
/android-ndk
Mac OS X:
/Users/ <user>
/android-ndk
在終端:
# create tool-chain - one line
# New method in ndk 12.
$NDK/build/tools/make_standalone_toolchain.py --arch arm --install-dir=/tmp/my-android-toolchain
# Old method.
#$NDK/build/tools/make-standalone-toolchain.sh --platform=android-3 --install-dir=/tmp/my-android-toolchain
# add to terminal PATH variable
export PATH=/tmp/my-android-toolchain/bin:$PATH
# make alias CC be the new gcc binary
export CC=arm-linux-androideabi-gcc
# compile your C code(I tried hello world)
$CC -o foo.o -c foo.c
# push binary to phone
adb push foo.o /data/local/tmp
# execute binary
adb /data/local/tmp/foo.o
將 CMake 與 Android NDK 一起使用是編譯 Android 控制台應用程序的好方法。
下載CMake和android-cmake (像這樣設置)。 如果您的程序名為 main.c,則在文件CMakeLists.txt
中寫入以下內容:
project(test)
cmake_minimum_required(VERSION 2.8)
add_executable(test ./main.c)
並運行cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .
然后,您將擁有一個程序的 Makefile,您可以運行make
來獲得您的test
可執行文件。
在 CMake 中,您可以使用工具鏈文件進行交叉構建。
來自谷歌開發者:
cmake \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
$OTHER_ARGS
CMake 有自己的內置 NDK 支持。 在 CMake 3.21 之前,Android 不支持此工作流程,並且經常會因新的 NDK 版本而中斷。 從 CMake 3.21 開始,實現被合並。
從 cmake 3.21 開始,您可以:
mkdir build
cd build
cmake ..
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_SYSTEM_VERSION=23 # API level. optional, recommanded
-DCMAKE_ANDROID_NDK=path/to/ndk
-DCMAKE_ANDROID_ARCH=arm # optional, recommanded
-DCMAKE_ANDROID_ARCH_ABI=armeabi # optional, recommanded
注意:在上面的命令中,行尾( <line feed>
)沒有被轉義,請不要直接在你的 shell 中復制粘貼這個命令
有關變量、可能值和確定算法的更多信息,請參閱使用 NDK 為 Android 進行交叉編譯。
嘗試如果agcc 包裝器可以幫助您,如Android-tricks博客中所引用的那樣。 根據博客文章你想使用仿生庫,但是手機上已經安裝了一個,而不是一些單獨編譯的版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.