'프로그래밍/Google Android'에 해당되는 글 27건
- 2012.06.14 file permission과 file ownership (part2) 1
- 2012.06.14 ndk-gdb가 잘 동작하지 않는 경우 한가지 - run-as에 문제가 있을때 해결법 (1편)
- 2012.06.13 안드로이드 시스템 개발시 유용한 정보 모음 #1
- 2012.06.09 Tips in developing with NDK
- 2010.10.18 Running a simple hello bare metal app on Android emulator
- 2010.10.01 Let test okl4_android examples on android_emulator under windows OS
- 2010.09.08 Android Tips #2
- 2010.06.01 How to use adb on Samsung android phone
- 2010.03.29 Android NDK 사용 팁 --- 갱신중
- 2010.03.15 Building/Debugging android native C applications
어떤 ndk 프로젝트를 개발하다가 디버깅하기 위해 ndk-gdb를 실행하면 다음과 같은 오류를 내놓으면서 진행되지 않는 문제가 있다.
Found package name: com.louis.testnative
ABIs targetted by application: armeabi
Device API Level: 10
Device CPU ABIs: armeabi-v7a armeabi
Compatible device ABI: armeabi
Using gdb setup init: ./libs/armeabi/gdb.setup
Using toolchain prefix: /cygdrive/c/NVPACK/android-ndk-r8//toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-
Using app out directory: ./obj/local/armeabi
Found debuggable flag: true
Found device gdbserver: /data/data/com.louis.testnative/lib/gdbserver
ERROR: Could not extract package's data directory. Are you sure that
your installed application is debuggable?
로그에서 보여지다시피 패키지는 찾았으나 아래 로그에서는 패키지를 못찾겠다고 에러를 출력하는데 이때 의심해 봐야 할 것이 /system/bin/run-as의 버그를 의심해야 한다.
관련내용은 다음 링크(http://code.google.com/p/android/issues/detail?id=16391)
이미 패치가 나와 있는 관계로 수정해서 새로운 run-as를 만들어 이전과 똑같은 위치에 넣어두고 시스템을 재시작하면 오류가 해결된다.(확인요망)
새로 만든 run-as를 /system/bin에 넣어줄때 몇가지 주의해야 할 사항이 있는데 이는 별도의 게시물로 해서 좀더 자세하게 설명한다.
1. adb shell로 실행하는 명령어를 root권한으로 실행하게 만들려면
안드로이드 루트 폴더에 default.prop이라는 파일을 찾아서 ro.secure=1로 되어 있는 부분을 ro.secure=0으로 바꿔주고 시스템을 재시작한다.(검증 되지 않음)
재시작후 adb root를 실행하면 adbd가 root권한을 갖게 되어서 이후 adb shell [명령어] 들은 모두 root권한으로 실행되게 된다고 한다.
2.
Building android native application
(Referred to following link: http://software.intel.com/en-us/articles/ndk-android-application-porting-methodologies/)
0. Prerequisites
1. Need to install Tegra android development pack from here
2. Install latest cygwin with development tools including gcc, unzip and etc.
1. Download a zipped source code from here.
2. Build apk file
<Added>
Set environment variable ANDROID_HOME to $ANDROID_SDK_DIR
</Added>
a. $ ndk-build NDK_DEBUG=1 APP_ABI="armeabi armeabi-v7a x86"
b. $ android.bat update project --path .
If you see a error something like "Error: The project either has no target set or the target is invalid.", then you need to define what target you want to use using "--target" option. For example,
b-1. $ android.bat update project --path . -t android-15
c. $ ant -f build.xml debug
<fix>
f-1. If the compilation fails here with message "sdk.dir is not defined" then use following command to define sdk.dir manually.
ant -Dsdk.dir=$ANDROID_HOME -f build.xml debug
f-2. With cygwin env, check all project folder including subdirectory set to readable and writable.
$(PROJECT_HOME) chmod -R a+rw *
</fix>
[Otional 1] If you want to check whether generated apk is valid or not, run below command and see the output message. Below shows an example.
o-1.
$ unzip -l bin/HelloGdbServer-debug.apk
Archive: bin/HelloGdbServer-debug.apk
Length Date Time Name
--------- ---------- ----- ----
2200 06-09-2012 17:25 res/drawable/icon.png
864 06-09-2012 19:06 res/layout/main.xml
1500 06-09-2012 19:06 AndroidManifest.xml
1296 06-09-2012 19:06 resources.arsc
3976 06-09-2012 19:06 classes.dex
125208 04-24-2012 23:20 lib/armeabi/gdbserver
10052 06-09-2012 18:52 lib/armeabi/libhello-gdbserver.so
125208 04-24-2012 23:20 lib/armeabi-v7a/gdbserver
10060 06-09-2012 18:52 lib/armeabi-v7a/libhello-gdbserver.so
214328 04-24-2012 23:20 lib/x86/gdbserver
2504 06-09-2012 18:52 lib/x86/libhello-gdbserver.so
881 06-09-2012 19:06 META-INF/MANIFEST.MF
934 06-09-2012 19:06 META-INF/CERT.SF
776 06-09-2012 19:06 META-INF/CERT.RSA
--------- -------
499787 14 files
Debugging NDK application
In the project folder, run below command.
$ ndk-gdb --force --start --verbose
Android NDK installation path: /cygdrive/c/NVPACK/android-ndk-r8/
Using default adb command: /cygdrive/c/NVPACK/android-sdk-windows/platform-tools/adb
ADB version found: Android Debug Bridge version 1.0.29
Using ADB flags:
Using auto-detected project path: .
Found package name: com.example.hellogdbserver
ABIs targetted by application: x86
Device API Level: 15
Device CPU ABI: x86
Compatible device ABI: x86
Using gdb setup init: ./libs/x86/gdb.setup
Using toolchain prefix: /cygdrive/c/NVPACK/android-ndk-r8//toolchains/x86-4.4.3/prebuilt/windows/bin/i686-android-linux-
Using app out directory: ./obj/local/x86
Found debuggable flag: true
Found device gdbserver: /data/data/com.example.hellogdbserver/lib/gdbserver
Found data directory: '/data/data/com.example.hellogdbserver'
Found first launchable activity: .HelloGdbServer
Launching activity: com.example.hellogdbserver/.HelloGdbServer
## COMMAND: /cygdrive/c/NVPACK/android-sdk-windows/platform-tools/adb shell am start -n com.example.hellogdbserver/.HelloGdbServer
Starting: Intent { cmp=com.example.hellogdbserver/.HelloGdbServer }
Error while mapping shared library sections:
libOpenglSystemCommon.so: No such file or directory.
Error while mapping shared library sections:
gralloc.goldfish.so: No such file or directory.
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
(gdb) list
1 /*
2 * Copyright (C) 2010 Max Vilimpoc
(gdb) Line number 31 out of range; jni/hello-gdbserver.c has 30 lines.
c
Continuing.
[New Thread 2259]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 2259]
0xad5bd4af in Java_com_example_hellogdbserver_HelloGdbServer_invokeCrash (
env=0x8534500, clazz=0xb49b6c70) at jni/hello-gdbserver.c:29
29 *crasher = 0xdeaddead;
(gdb) bt
#0 0xad5bd4af in Java_com_example_hellogdbserver_HelloGdbServer_invokeCrash (
env=0x8534500, clazz=0xb49b6c70) at jni/hello-gdbserver.c:29
#1 0xb72a3b80 in ?? ()
#2 0x08534500 in ?? ()
Error case #1.
If you cannot see debug symbols, need to check gdb.debug file whether it has wrong line ending codes. If such case, then run below command to convert dos style line ending to Unix style so that gdb can parse it to display symbols correctly. After this conversion, restart ndk-gdb command above then you will see debug symbol.
$ tr -d '\012' < libs/x86/gdb.setup | tr '\015\015' '\012\012' > libs/x86/gdb.setup
emulator @fry -kernel ./test.bin
Let test okl4_android examples on android_emulator under windows OS
프로그래밍/Google Android 2010. 10. 1. 16:37./android-configure --prefix=/d/work/local
make
make install
./android-configure.sh --sdl-config=/d/work/local/bin/sdl-config
make
./qemu/objs/emulator.exe @cupcake -os-type okl4 -show-kernel -verbose -kernel ../images/image.boot.bin
| 추가 옵션 9월4일, 오전1시45분 |
suggestions.
Again (as a summary):
1. You need a double buffering frame-buffer driver.
2. You need MMAP() support on the /data file system.
3. You need all the Android specific kernel code enabled in your
kernel.
4. You need enough RAM to run all the Android code (start with
192meg).
5. You need various other features of the Linux kernel enabled and
running (see a config file from a running Android build).
6. You may need specific support for your board (drivers and/or
binding subsystems to drivers).
7. You may need specific support for your processor architecture (and
don't assume all architectures are equal).
8. You need a working fake (if not real) power management driver.
You also need to be able to use logcat to see the userland log
messages to see where the system is really dieing.
# bash for loop
VAR="test.so"
defpath=out/apps/$1/armeabi
target_lib_path=/system/sd/expstick/lib
target_bin_path=/data/tmp
cd $defpath
echo "Current path is " "$(pwd)"
for f in $( ls . ); do
# echo $f
if test -f $f ; then
echo $f "is a file"
# search ".so"
if [[ "$f" =~ t*.so ]]
then
#echo $f "is dynamic library"
echo $f " Install to " $target_lib_path
adb push ./$f $target_lib_path
else
if test -x $f ;
then
#echo $f "is executable"
echo $f " Install to " $target_bin_path
adb push ./$f $target_bin_path
adb shell chmod 4777 $target_bin_path/$f
fi
fi
else
echo $f "is not a file"
fi
done
Original Link: http://betelco.blogspot.com/2010/01/buildingdebugging-android-native-c.html
Building/Debugging android native C applications
If you are reading this post just because you have googled the magic keywords ("android" + "native code") then you should know that there is an easier way to build native applications using android makefiles ("Android.mk" and "Application.mk").
The method I'm describing here is only useful if you want to understand how things work in order to create more complexstandard GNU makefiles. This is also useful if you would like to create your own GNU autotools wrappers to compile projects using GNU configure.
I'm using Windows Vista as host machine but any other supported platforms (e.g. linux-x86 or darwin-x86) should work.
I have tested both the NDK (1.6) and SDK (2.1) on:
- Windows XP (32-bit) and Vista (64-bit)
- Mac OS X Snow Leopard
- Ubuntu Intrepid
If you need information on how to install the SDK, visit this address http://developer.android.com/sdk/installing.html.
If the "SDK setup" fail to update the installed packages you can change the remote site URL from https://dl-ssl.google.com/android/repository/repository.xml to http://dl-ssl.google.com/android/repository/repository.xml (change the URL scheme from HTTPS to HTTP) or try to disable your anti-virus or firewall.
I have installed the SDK version 2.1 under c:/android-sdk (a.r.a /cygdrive/c/android-sdk).
Add an environment variable named ANDROID_SDK_ROOT pointing to the SDK root directory.
Important: You should add "$ANDROID_SDK_ROOT/tools" directory to the $PATH environment variable.
Under *nix:
export PATH=$ANDROID_SDK_ROOT/tools:$PATH
set PATH=%ANDROID_SDK_TOOLS%;%PATH%
If you are using Windows XP or Vista as host machine then you MUST install Cygwin Devel package with GNU Make (3.81 or later) before installing the NDK.
It should also work with MinGW.
Installing the Android NDK
I have uncompressed the NDK version 1.6 under c:/android-ndk (a.r.a /cygdrive/c/android-ndk).
Add an environment variable named ANDROID_NDK_ROOT pointing to the NDK root directory.
To install the NDK:
cd $ANDROID_NDK_ROOT
build/host-setup.sh
cd $ANDROID_NDK_ROOT
make -APP=hello-jni
Android NDK: Building for application 'hello-jni'
Compile thumb : hello-jni <= sources/samples/hello-jni/hello-jni.c SharedLibrary : libhello-jni.so Install : libhello-jni.so => apps/hello-jni/project/libs/armeabi
Creating an AVD
AVD stands for Android Virtual Device and can be seen as a device profile (keyboard, dialing pad, skin, screen dimensions, appearance ...) to load into your emulator. You can create as many AVDs as you need.
To create an AVD named "avdtest" targeting platform 2.1 (targetID=android-7):
android create avd -n avdtest -t android-7
Created AVD 'avdtest' based on Android 2.1, with the following hardware config: hw.lcd.density=160
Here I will create a basic test.c file under C:\tmp with the following content:
#include
int main(int argc, char **argv)
{
int i = 1;
i+=2;
printf("Hello, world (i=%d)!\n", i);
return 0;
}
Just create an empty file named makefile (without any extension) under C:\tmp (which is the same directory as test.c).
Now We will fill the makefile step by step.
Add application name, $ROOT directory, install directory and the NDK platform version:
APP := test
ROOT:=/cygdrive/c
NDK_PLATFORM_VER := 1.5
INSTALL_DIR := /data/tm
ANDROID_NDK_ROOT:=$(ROOT)/android-ndk
ANDROID_NDK_HOST:=windows
ANDROID_SDK_ROOT:=$(ROOT)/android-sdk
PREBUILD:=$(ANDROID_NDK_ROOT)/build/prebuilt/$(ANDROID_NDK_HOST)/arm-eabi-4.2.1
BIN := $(PREBUILD)/bin
Add GCC options:
CPP := $(BIN)/arm-eabi-g++
CC := $(BIN)/arm-eabi-gcc
CFLAGS :=
LDFLAGS := -Wl
- all: $(APP)
- OBJS += $(APP).o
- $(APP): $(OBJS)
- $(CPP) $(LDFLAGS) -o $@ $^
- %.o: %.c
- $(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@
- install: $(APP)
- $(ANDROID_SDK_ROOT)/tools/adb push $(APP) $(INSTALL_DIR)/$(APP)
- $(ANDROID_SDK_ROOT)/tools/adb shell chmod 777 $(INSTALL_DIR)/$(APP)
- shell:
- $(ANDROID_SDK_ROOT)/tools/adb shell
- run:
- $(ANDROID_SDK_ROOT)/tools/adb shell $(INSTALL_DIR)/$(APP)
- clean:
- @rm -f $(APP).o $(APP)
To build the application, switch to the directory where you have created both files and then:
make
To resolve this issue, add the Bionic header files to $CFLAGS variable like this:
CFLAGS := -I$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/include
rt0.o: No such file: No such file or directory
LDFLAGS := -Wl -nostdlib
test.c:(.text+0x34): undefined reference to `printf'
test.c:(.text+0x3c): undefined reference to `exit'
LDFLAGS := -Wl -L$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
LDFLAGS += -nostdlib -lc
/cygdrive/c/android-ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.so: undefined reference to `dl_unwind_find_exidx'
LDFLAGS := -Wl,-rpath-link=$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib -L$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
/cygdrive/c/android-ndk/build/prebuilt/windows/arm-eabi-4.2.1/bin/../lib/gcc/arm
-eabi/4.2.1/../../../../arm-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 000082c8
LDFLAGS := -Wl,--entry=main,-rpath-link=$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib -L$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
LDFLAGS += -nostdlib -lc
Testing your application
Before testing your application you MUST run the emulator like this:
emulator -avd avdtest
To install the application on the emulator, open a new console and go to to directory where you have created test.c andmakefile. Install your application on the emulator like this:
make install
/cygdrive/c/android-sdk/tools/adb push test /data/tmp/test
304 KB/s (2493 bytes in 0.008s)
/cygdrive/c/android-sdk/tools/adb shell chmod 777 /data/tmp/test
make run
/cygdrive/c/android-sdk/tools/adb shell /data/tmp/test
/data/tmp/test: not found
I spent hours searching and I found that this error happens because the loader fails to load the application because it cannot found a proper linker.
To specify a search directory for the dynamic linker (at run time) you MUST change the link options like this:
LDFLAGS := -Wl,--entry=main,-rpath-link=$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib,-dynamic-linker=/system/bin/linker -L$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
LDFLAGS += -nostdlib -lc
The console will print the expected result ("hello, world (i=3)!") but just after we have an segmentation fault error("[1] Segmentation fault /data/tmp/test").
To resolve this issue you can exit the program (exit(0);) just before the main function returns (return 0;). You should also include
If you retry the build&&run process (make clean && make && make install && make run) then you should have:
/cygdrive/c/android-sdk/tools/adb shell /data/tmp/test
Hello, world (i=3)!
Debugging your application
Before doing anything you MUST copy the gdbserver file to the emultor.
This file is under $BIN ($ANDROID_NDK_ROOT/build/prebuilt/$ANDROID_NDK_HOST/arm-eabi-4.2.1/bin).
Copy gdbserver to the emulator like this:
adb push gdbserver $INSTALL_DIR/gdbserver
adb shell chmod 777 $INSTALL_DIR/gdbserver
adb forward tcp:1234: tcp:1234
Now it's time to run the server:
adb shell $INSTALL_DIR/gdbserver :1234 $INSTALL_DIR/$APP
If all is OK the the server will print something like this:
Process /data/tmp/test created; pid = 246
Listening on port 1234
- debug:
- $(GDB_CLIENT) $(APP)
GDB_CLIENT := $(BIN)/arm-eabi-gdb
To generate debug symbols you MUST change the makefile like this (should not be hard coded like this):
DEBUG = -g
CFLAGS := $(DEBUG) -I$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/include
Connect to the server (from the same console) like this:
target remote :1234
b main
c
n
p i
#$1 = 1
n
#9 printf("Hello, world (i=%d)!\n", i);
p i
#$2 = 3
c
#Program exited normally.
The final makefile and test.c files are shown below:
- makefile
- OBJS += $(APP).o
- $(APP): $(OBJS)
- $(CPP) $(LDFLAGS) -o $@ $^
- %.o: %.c
- $(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@
- install: $(APP)
- $(ANDROID_SDK_ROOT)/tools/adb push $(APP) $(INSTALL_DIR)/$(APP)
- $(ANDROID_SDK_ROOT)/tools/adb shell chmod 777 $(INSTALL_DIR)/$(APP)
- shell:
- $(ANDROID_SDK_ROOT)/tools/adb shell
- run:
- $(ANDROID_SDK_ROOT)/tools/adb shell $(INSTALL_DIR)/$(APP)
- debug:
- $(GDB_CLIENT) $(APP)
- clean:
- @rm -f $(APP).o $(APP)
APP := test
ROOT:=/cygdrive/c
INSTALL_DIR := /data/tmp
NDK_PLATFORM_VER := 1.5
ANDROID_NDK_ROOT:=$(ROOT)/android-ndk
ANDROID_NDK_HOST:=windows
ANDROID_SDK_ROOT:=$(ROOT)/android-sdk
PREBUILD:=$(ANDROID_NDK_ROOT)/build/prebuilt/$(ANDROID_NDK_HOST)/arm-eabi-4.2.1
BIN := $(PREBUILD)/bin
GDB_CLIENT := $(BIN)/arm-eabi-gdb
DEBUG = -g
CPP := $(BIN)/arm-eabi-g++
CC := $(BIN)/arm-eabi-gcc
CFLAGS := $(DEBUG) -I$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/include
LDFLAGS := -Wl,--entry=main,-rpath-link=$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib,-dynamic-linker=/system/bin/linker -L$(ANDROID_NDK_ROOT)/build/platforms/android-$(NDK_PLATFORM_VER)/arch-arm/usr/lib
LDFLAGS += -nostdlib -lc
all: $(APP)
- test.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int i = 1;
i+=2;
printf("Hello, world (i=%d)!\n", i);
exit(0);
return 0;
}