카테고리 보관물: Android

Cygwin에서 Android systrace 실행 문제

2014년 8월 현재, Cygwin으로 systrace를 사용하려고 하면 zlib 관련한 error가 나면서 동작하지 않는다.

$ python systrace.py -o output.html gfx input view wm am video hal dalvik
capturing trace... done
downloading trace... done

Traceback (most recent call last):
  File "systrace.py", line 286, in <module>
    main()
  File "systrace.py", line 231, in main
    decoded_chunk = dec.decompress(chunk)
zlib.error: Error -3 while decompressing: incorrect header check

AOSP project의 이 링크에 보면 문제를 해결하기 위한 patch가 올려져 있는데 comment를 보니 한동안 받아들여 지지 않다가 현재 source와 달라져서 적용할 수 없게 된 모양이다. 같은 동작을 하도록 약간만 수정해서 이렇게 고쳐 보니 좀 지저분하긴 해도 zlib error 없이 Cygwin에서 systrace를 사용할 수 있었다.

diff --git a/systrace.py b/systrace.py
index 387f413..0d3be25 100644
--- a/systrace.py
+++ b/systrace.py
@@ -205,8 +205,12 @@ def main():
       data = ''.join(data)

       # Collapse CRLFs that are added by adb shell.
-      if data.startswith('\r\n'):
-        data = data.replace('\r\n', '\n')
+      if sys.platform == 'cygwin':
+        if data.startswith('\r\r\n'):
+          data = data.replace('\r\r\n', '\n')
+      else:
+        if data.startswith('\r\n'):
+          data = data.replace('\r\n', '\n')

       # Skip the initial newline.
       data = data[1:]


Emacs에서 Android 개발 환경 사용

AOSP에는 Emacs에서 Android 개발환경을 사용할 수 있도록 몇몇 el file들을 제공하는데, platform  module build를 주로 하게 되는 나로써는 사용에 부족함이 없는 것 같다. Module build와 기본적인 ADB 조작을 지원하는 이 script들의 기능이 부족하다고 느낀다면 Android 개발환경을 보다 적극적으로 지원하는 android-mode와 같은 project를 고려해 보는것도 좋을 것이다.

buildspec.mk 설정

사실 이 기능은 그동안 사용하지 않았었는데, AOSP에서 지원하는 el script들을 사용하려면 설정해 주어야 한다. 간단한 과정을 거쳐 설정해 놓고 보니 shell에서도 사전설정 없이 ‘make target’ command만으로 build를 할 수 있어서 편하다. 대신 ‘cd $OUT’이나 ‘croot’ 같은 이동 command들을 사용할 수 없다는 것은 불편한 점이다.

<ANDROID_ROOT>/build/buildspec.mk.default file을 복사해서 환경에 맞게 수정한 다음 <ANDROID_ROOT> 위치에 놓아두면 build 명령을 내릴때 자동으로 참조된다. 기본적으로 TARGET_PRODUCT, TARGET_BUILD_VARIANT 정도만 수정하면되는데 특이한 build환경을 사용하고 있다면 나머지 항목들은 읽어보고 자신에 맞게 수정하자.

# Choose a product to build for. Look in the products directory for ones
# that work.
ifndef TARGET_PRODUCT
  TARGET_PRODUCT:=product_name
endif

# Choose a variant to build. If you don't pick one, the default is eng.
# User is what we ship. Userdebug is that, with a few flags turned on
# for debugging. Eng has lots of extra tools for development.
ifndef TARGET_BUILD_VARIANT
  TARGET_BUILD_VARIANT:=eng
endif

el file들 복사 및 설정

<ANDROID_ROOT>/development/ide/emacs/ 안에 있는 file들을 Emacs 환경 directory로 복사한 다음 해당 file이 load되도록 init file을 수정한다.

mkdir ~/.emacs.d/android.el
cp <ANDROID_ROOT>/development/ide/emacs/*.el ~/.emacs.d/android.el/ android-common.el android-compile.el android-host.el

다음을 init file에 붙여 넣으면 된다.

; Load Android tools
(add-to-list 'load-path "~/.emacs.d/android.el/")
(require 'android-host)
(require 'android-compile)


사용

편집 중인 file의 module을 build하려면 ‘M-x android-compile’을 입력 하면 된다. 그 외의 ADB에 관련한 명령어 들은 android-host.el script에 설명되어 있다.

;; C-x a a android-adb-root
;; C-x a r android-adb-remount
;; C-x a s android-adb-sync
;; C-x a b android-adb-shell-reboot-bootloader
;; C-x a f android-fastboot-flashall

Android의 외부 프로젝트들 (external directory)

Android의 external directory 아래에는 external project들이 들어 있는데, 150개가 넘는 외부 프로젝트들을 보고 있으면 ‘바퀴를 재발명하지 말라’는 격언이 떠오른다.

Jellybean version이 release되었을 때 궁금해서 여기저기 찾아보고 처음으로 문서로 만들었는데 Kikat이 나온김에 최신 버전에 맞춰서 업데이트 했다. 다른 reference없어서 README file을 읽어보고 그게 없으면 web에서 찾아 보고 해서 만든 것이어서 오류의 가능성이 있긴 하지만 궁금해 하는 많은 사람들에게 도움이 되길 바라며 Google docs에 작성한 문서를 공개한다.

Screenshot

알림)
1. 검은색은 마지막 버전에서 빠진것, 파란색은 최종 버전에서 추가된 것을 의미합니다. (2012년 12월 현재 최종버전은 Kitkat)
2. 오류가 있을 수 있으니 주의 하세요. Feedback 환영합니다.

 

Mac용 AndroidStudio에서 새로운 프로젝트를 만들지 못하는 문제

Mac용 AndroidStudio v0.2.3을 설치하고 처음으로 ‘New Project’를 만드는데 마지막 단계에서 “Failed to import Gradle project:” error popup이 뜨면서 제대로 되지 않는다. 실제로는 project directory와 file들도 모두 생기는데 project가 등록되지 않는다. Error log로 봐서는 build와 관련이 있는 Gradle이 제대로 동작하지 못한 문제인것 같다.

Log는 “~/Library/Logs/AndroidStudioPreview/idea.log”에서 볼 수 있다.

Failed to import Gradle project: /Users/YOUR_ID/.gradle/wrapper/dists/gradle-1.6-bin/72srdo3a5eb3bic159kar72vok/gradle-1.6-bin.zip.lck (No such file or directory)

Android developer page에 Gradle의 import와 관련된 문제가 발생했을 때 Android SKD Manager를 띄워서 Extras 아래에 있는  ‘Android Support Repository’ 항목을 선택해주어야 한다는 내용이 니와 있어서 따라 했는데도 문제가 계속 생겼다.

Home directory에서 permission error가 나는게 이상해서 home directory의 permission을 보니 내 home directory에 owner가 write permission이 없다!! (읭?)

Home directory에 write permission을 줄까 하다가 mac의 보안정책 원래 그럴지도 모르니 그냥 message가 불평하는 대로 ~/.gradle directory를 만들어 주었더니 잘 돌아간다. lol

sudo mkdir ~/.gradle
sudo chown YOUR_ID:staff ~/.gradle

Android NDK build architecture 변경하기

아무 설정 없이 ndk를 build 하면 다음과 같이 arm용 library가 만들어진다.

$ <NDK_PATH>/ndk-build 
Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup       : libs/armeabi/gdb.setup
Compile thumb  : hello-jni <= hello-jni.c
SharedLibrary  : libhello-jni.so
Install        : libhello-jni.so => libs/armeabi/libhello-jni.so
$ file obj/local/armeabi/libhello-jni.so 
obj/local/armeabi/libhello-jni.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped

NDK에서 build되는 binary의 architecture를 변경하려면 APP_ABI를 선언해 주어야 하는데, Android.mk에 추가해서는 제대로 동작하지 않는다. JNI directory 아래에 Application.mk file을 만들고  APP_ABI값에 build할 architecture를 설정해 준다. 다음은 x86 바이너리를 생성하는 예제이다.

$ cat jni/Application.mk 
APP_ABI := x86
$ <NDK_PATH>/ndk-build 
Gdbserver      : [x86-4.6] libs/x86/gdbserver
Gdbsetup       : libs/x86/gdb.setup
Compile x86    : hello-jni <= hello-jni.c
SharedLibrary  : libhello-jni.so
Install        : libhello-jni.so => libs/x86/libhello-jni.so
$ file obj/local/x86/libhello-jni.so 
obj/local/x86/libhello-jni.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped

* Build에 사용되는 toolchain은 <NDK_PATH>/toolchains/<architecture>-<version>의 형태로 위치한다.