Хотите скомпилировать собственный двоичный файл Android, который я могу запустить в терминале на телефоне

В течение пары дней я пытался скомпилировать собственный двоичный файл ARM Android, который будет выполняться на моем телефоне с помощью терминального приложения. Я хочу сгенерировать двоичный файл того же типа, что и стандартные двоичные файлы Posix, установленные на телефоне, например ls, mkdir и т. Д. Я загрузил Android NDK под Mac OS X и смог скомпилировать простые двоичные файлы ELF без ошибок. Однако, когда я передаю их на телефон, они всегда перестают работать. То есть они имеют ошибку при компиляции с -static в GCC. Если я не использую -static, они жалуются на отсутствие ссылок и т. Д. Проще говоря, они не работают.

Моя гипотеза заключается в том, что они неправильно связываются со стандартной библиотекой C Android. Несмотря на то, что я связываю свои двоичные файлы с libc, предоставленной NDK, они все равно не работают. Я прочитал, что Android использует библиотеку Bionic C, и попытался загрузить исходный код для нее, но я не уверен, как создать из нее библиотеку (похоже, это вся сборка ARM).

Верно ли, что библиотека Android C на телефоне отличается от библиотеки Android NDK? Будет ли тот, который включен в NDK, не позволит мне компилировать собственные двоичные файлы, которые я могу выполнить через терминал? Любое руководство здесь приветствуется!

Обновление:

Наконец-то я заставил это работать, используя GCC 4.7.0 в Mac OS X. Я загрузил заголовки Bionic, а затем скомпилировал динамически подключаемый двоичный файл, используя библиотеку C, которая поставляется с Android NDK. Мне удалось получить тестовое приложение для работы на телефоне, используя библиотеку C телефона (двоичный файл был 33 КБ). Я также попытался выполнить статическую линковку с библиотекой C NDK, и это тоже сработало.

Чтобы все это заработало, мне пришлось передать -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.

Для этого эксперимента я использовал только обычные GCC 4.7.0 и Binutils 2.22. Я также скомпилировал GCC с помощью newlib, но на самом деле я вообще не связываю свои двоичные файлы ARM с newlib. Я заставляю GCC / ld напрямую связываться с libc, поставляемым с Android NDK, или, в случае динамических двоичных файлов, с libc на телефоне.


person Synthetix    schedule 29.05.2012    source источник
comment
К вашему сведению, если вы настроили сборку, как если бы вы создавали библиотеку jni (см. Примеры в дистрибутиве NDK), и измените BUILD_SHARED_LIBRARY в Android.mk на BUILD_EXECUTABLE, вы получите исполняемый файл, хотя это неофициальный (может исчезнуть и т. д.) в системе сборки ndk.   -  person Chris Stratton    schedule 30.05.2012
comment
Возможный дубликат Как я могу запустить двоичный файл C (исполняемый файл) в Android из оболочки Android   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 23.06.2016


Ответы (4)


Просто используйте android-ndk. И создайте Android.mk вот так. include $(BUILD_EXECUTABLE) - это то, что сообщает ему о создании исполняемого файла вместо JNI .lib

Android.mk

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
person SonicBison    schedule 09.06.2012
comment
Это было для меня решением. Я безуспешно возился с agcc. Кажется, это использует преимущества системы сборки Android ... Есть ли какие-то объяснения того, как это где-то работает? Спасибо! - person Diego Medaglia; 02.04.2013
comment
$ (NDK_ROOT) /docs/ANDROID-MK.html описывает все макросы. - person SonicBison; 04.04.2013
comment
есть лишний endif - person dashesy; 25.09.2013
comment
@SonicBison - Итак, мне удалось скомпилировать двоичный файл. Теперь есть какое-то конкретное место, куда мы должны поместить двоичный файл? Мое устройство внедрено. Если я выполню CHMOD для 777, будет ли он вести себя как SU и получит ли доступ к системному приложению, например разрешение INEJCT_EVENTS. В основном я хочу вызвать injectEvents в конце дня? - person TorukMakto; 01.02.2014
comment
Я ничего не знаю о INJECT_EVENTS, но быстрый поиск в Google показывает, что приложение должно быть подписано системным (платформенным) ключом. Но в противном случае с root вы можете поместить двоичный файл куда угодно. - person SonicBison; 04.02.2014
comment
@myCodeHurts, вы не должны помещать его на SD-карту, так как не разрешено ничего выполнять оттуда - person JoachimR; 10.05.2014
comment
@SonicBison, требуется ли понятие файла разрешений приложения (т.е. manifest) для таких автономных программ? Я разработал простая программа unix socket, которая имеет проблемы, связанные с разрешениями. Я подумал, что, возможно, я что-то упустил на этапе компиляции, связанный с этим. - person sherrellbc; 20.08.2015
comment
@sherrellbc Нет. Он будет соответствовать обычным разрешениям файловой системы, т.е. убедитесь, что каталог доступен для чтения / записи. Если это устройство без рутирования, то это только в нескольких местах. - person SonicBison; 20.08.2015
comment
@SonicBison, телефон рутирован. Каталог, в который помещаются файлы сокетов, имеет разрешения drwxrwx---, а файл, к которому я пытаюсь подключиться, имеет разрешения srwx---rw-. Я запускаю оба исполняемых файла как root, должно ли это быть проблемой? Без корневого выполнения исполняемых файлов я получаю ошибки разрешений при попытке записи в каталог, как и ожидалось. Однако, как показывает ссылка на мой вопрос выше, я получаю Operation not permitted ошибки при запуске с правами root для системных вызовов connect и _5 _ / _ 6_, тогда как bind работает должным образом. - person sherrellbc; 21.08.2015
comment
@sherrellbc для вашего случая похоже, что он должен работать. В моем случае мы установили 0777, потому что у нас есть разные .apks для подключения к демону. - person SonicBison; 22.08.2015
comment
@SonicBison, на самом деле оказалось, что проблема связана с вызовом remove, а не unlink при инициализации. - person sherrellbc; 24.08.2015

Во-первых, убедитесь, что у вас есть 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:

/ главная / <user> / android-ndk

Mac OS X:

/ Пользователи / <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
person Jared Burrows    schedule 28.05.2013
comment
... вы выполняете там объектный файл? Без привязки? Это действительно работает? - person David Given; 16.08.2015
comment
Да, похоже. Мне, скорее всего, нужно удалить -c. Я написал это некоторое время назад. - person Jared Burrows; 16.08.2015


Попробуйте, может ли оболочка agcc помочь вам, как указано в Блог о хитростях Android. Согласно сообщению в блоге, вы хотите использовать бионическую библиотеку, но ту, которая уже установлена ​​на телефоне, а не какую-то отдельно скомпилированную версию.

person Prof. Falken    schedule 29.05.2012
comment
Зачем в этом случае использовать Crystax вместо официального NDK? - person Mārtiņš Možeiko; 29.05.2012
comment
Нет особой причины, иногда помогает пробовать разные вещи при экспериментировании и обучении. Вот почему я просто оставил комментарий. - person Prof. Falken; 30.05.2012