Искам да компилирам оригинален двоичен файл за Android, който мога да стартирам в терминал на телефона

От няколко дни се опитвам да компилирам роден двоичен файл за ARM Android, който ще се изпълни на телефона ми с помощта на терминално приложение. Искам да генерирам същия тип двоични файлове като стандартните Posix двоични файлове, инсталирани на телефона като ls, mkdir и т.н. Изтеглих Android NDK под Mac OS X и успях да компилирам прости ELF двоични файлове без грешки. Обаче като ги прехвърля на телефона винаги сегфауват. Тоест, те се връщат към segfault, когато се компилират с -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 lib на телефона (двоичният файл беше 33K). Също така се опитах да се свържа статично с 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 Shell   -  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 не трябва да го поставяте на sdcard, тъй като не е разрешено да се изпълнява нищо от там - person JoachimR; 10.05.2014
comment
@SonicBison, идеята за файл с разрешения за приложение (т.е. манифест) все още ли е необходима за самостоятелни програми като тези? Разработих прост unix socket собствена програма, която има проблеми, които изглежда са свързани с разрешения. Мислех си, че може би съм пропуснал нещо по време на фазата на компилация, свързана с това. - person sherrellbc; 20.08.2015
comment
@sherrellbc Не. Ще отговаря на обикновените разрешения на файловата система, т.е. уверете се, че директорията може да се чете/записва. Ако това е устройство без руутване, това е само на няколко места. - person SonicBison; 20.08.2015
comment
@SonicBison, телефонът е руутнат. Директорията, в която са поставени сокет-файловете, има разрешения drwxrwx---, а файлът, към който се опитвам да се свържа, има разрешения srwx---rw-. Изпълнявам и двата изпълними файла като root, така че трябва ли това да е проблем? Без root изпълнение на изпълнимите файлове получавам грешки при разрешения, когато се опитвам да пиша в директорията, както се очаква. Въпреки това, както показва връзката към въпроса ми по-горе, получавам Operation not permitted грешки, когато стартирам като root както за connect, така и за send/sendto системни извиквания, докато 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

Използването на 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 изпълним файл.

person gfour    schedule 30.05.2012

Опитайте, ако agcc обвивката може да ви помогне, както е посочено в Android-tricks блог. Според публикацията в блога искате да използвате бионичната библиотека, но тази, която вече е инсталирана на телефона, а не някаква отделно компилирана версия.

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