사실 팁이라 할 것도 없지마는... 희희
안드로이드 프레임워크 소스라는 녀석은 각종 GUI를 아우르는 루트 파일 시스템이기 때문인지,
소스트리만 1GBytes 를 육박하거나 넘는 사이즈를 자랑합니다.
리눅스 커널도 많많치 않게 복잡하고 방대하지만, 그 사이즈는 100MBytes 언더입지요.
여하튼 개발이나 소스 분석시 좀 더 편하게 안드로이드 소스트리를 다루는 방법을 소개함미다.
우선 안드로이드 소스 디렉토리로 이동합니다.
#] source ./build/envsetup.sh
위 커맨드를 실행하면 이제 안드로이드 소스를 편하게 다룰 수가 있게됩니다.
기본적으로 "envsetup.sh" 스크립트는 개발 환경의 편의를 위한 function 들이 구현만 되어있습니다.
source 커맨드를 이용하여 실행하고 난 뒤에는
스크립트 내부의 함수들을 일반 shell 커맨드처럼 사용할 수 있게 됩니다.
예를 들어 몇가지를 살펴 보겠씁미다. 희희
===============================================================================================
root@chlrbgh0:~android-origen# source ./build/envsetup.sh
root@chlrbgh0:~android-origen# help
Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- croot: Changes directory to the top of the tree.
- m: Makes from the top of the tree.
- mm: Builds all of the modules in the current directory.
- mmm: Builds all of the modules in the supplied directories.
- cgrep: Greps on all local C/C++ files.
- jgrep: Greps on all local Java files.
- resgrep: Greps on all local res/*.xml files.
- godir: Go to the directory containing a file.
Look at the source to view more functions. The complete list is:
add_lunch_combo cgrep check_product check_variant choosecombo chooseproduct choosetype choosevariant cproj croot findmakefile gdbclient get_abs_build_var getbugreports get_build_var getprebuilt gettop godir help isviewserverstarted jgrep lunch m mm mmm pid printconfig print_lunch_menu resgrep runhat runtest set_java_home setpaths set_sequence_number set_stuff_for_environment settitle smoketest startviewserver stopviewserver systemstack tapas tracedmdump
root@chlrbgh0:~android-origen#
===============================================================================================
위에서 처럼 source 커맨드 실행이후에 help 커맨드를 실행한 결과를 보시면 일반적인 리눅스 배포판에 제공되는
bash나 ash 등과는 다른 help 메시지가 보입니다. 물론 envsetup.sh 내부의 help function 이 실행된 결과입니다.
개인적으로 자주 사용하게 되고 쓰기도 편해 좋아하는 것이 몇가지 있는데요.
제가 좋아하는 녀석들 위주로 살펴 보겠습니다.
1. choosecombo, lunch
빌드 환경을 셋업해주는 녀석들입니다.
안드로이드 풀 소스를 가지고 개발을 진행할 때에는 PRODUCT 타입을 지정해서 프레임워크와 리눅스 커널을 연동할 HAL(Hardware Abstraction Layer)을 어떤 device나 vendor 용으로 사용할지를 셋업해야 하지 않겠슴미까?
사용 법은 간단함미다.
===============================================================================================
#] choosecombo 1 1 insignal_origen eng
Build for the simulator or the device?
1. Device
2. Simulator
Which would you like? [1] 1
Build type choices are:
1. release
2. debug
Which would you like? [1] 1
Which product would you like? [generic] insignal_origen
Variant choices are:
1. user
2. userdebug
3. eng
Which would you like? [eng] eng
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.3
TARGET_PRODUCT=insignal_origen
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRI54
============================================
root@chlrbgh0:~/android-origen#
===============================================================================================
보다 간편하게는 다음과 같이 lunch 커맨드를 사용해줍니다.
===============================================================================================
root@chlrbgh0:~/android-origen# lunch insignal_origen-eng
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.3
TARGET_PRODUCT=insignal_origen
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRI54
============================================
root@chlrbgh0:~/android-origen#
===============================================================================================
위와 같이 실행하면 insignal 에서 제작한 origen 이라는 PRODUCT 를 eng/device/release 모드로
빌드할 환경을 셋업해줍니다. 츠암 쉽죠잉? 희희
2. godir
안드로이드 내부의 방대한 소스를 분석하고 찾아다닐때 한 줄기 빛과도 같은 커맨드님이심미다.
실행은 아래와 같이 합니다.
예를 들어 카메라 서비스가 존재하는 디렉토리를 찾아가봅시다요!
===============================================================================================
root@chlrbgh0:~/android-origen# godir cameraservice
Creating index... Done
root@chlrbgh0:~android-origen/frameworks/base/services/camera/libcameraservice#
===============================================================================================
아니 세상에 이런 편리한 것이 있나!!! 라고 외칠지 모릅미다 희희
위에서 처럼 최초에 godir 을 실행하면 index 즉, 안드로이드 소스 트리를 파일로 정렬합니다.
godir 에서 인자로 들어가는 cameraservice 가 존재하는 부분만 찾아내서 해당 디렉토리로 이동시켜 주는
친절한 커맨드이지요... 중복되는 디렉토리나 파일 명의 경우 리스팅을 하여 선택할 수 있게도 도와줍니다. :)
3. cgrep, jgrep 등
저는 java는 모르고 어플쪽은 재능이 없음을 심히 깨달아 처다도 안보므로 cgrep 만 살펴 봅니다.
커맨드 네임 그대로 `*.c` 소스를 대상으로 원하는 스트링을 grep 해주는 커맨드이지요.
===============================================================================================
root@chlrbgh0:~/workspace/origen/for-git-android/android-origen# cgrep mMixer
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:188: mMixer = new ALSAMixer;
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:195: if (mMixer) delete mMixer;
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:200: if (mMixer && mMixer->isValid())
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:217: if (mMixer)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:218: return mMixer->setVolume(ROUTE_EARPIECE, volume);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:225: if (mMixer)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:226: return mMixer->setMasterVolume(volume);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:351: if (mMixer)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:352: return mMixer->setCaptureMuteState(ROUTE_EARPIECE, state);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:359: if (mMixer)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:360: return mMixer->getCaptureMuteState(ROUTE_EARPIECE, state);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1020: if (! mParent->mMixer || ! mDevice)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1025: return mParent->mMixer->setVolume (mDevice, (left + right)/2);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1030: if (! mParent->mMixer || ! mDevice)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1033: return mParent->mMixer->setVolume (mDevice, volume);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1178: if (mParent->mMixer)
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1179: return mParent->mMixer->setMasterGain (gain);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1330: initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidPlayback");
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1331: initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidRecord");
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1344: for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1384: for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.cpp:1419: if (mMixer[i]) snd_mixer_close (mMixer[i]);
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.h:40: bool isValid() { return !!mMixer[SND_PCM_STREAM_PLAYBACK]; }
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.h:53: snd_mixer_t *mMixer[SND_PCM_STREAM_LAST+1];
./hardware/sec/exynos4/hal/libaudio-alsa/AudioHardware.h:303: ALSAMixer *mMixer;
root@chlrbgh0:~/workspace/origen/for-git-android/android-origen#
===============================================================================================
원하는 스트링을 프로젝트 소스 내부에서 찾기란 만만치가 않지요...안드로이드처럼 덩치가 크다면 grep 한번 돌리기가 무척 까탈시러울 것입니다...다른 작업을 포기하고 돌려야 하는 불편을 피할 수 있습니다. *.c, *.cpp, *.h 까지 굽어 살펴봐주시는 참 어진 커맨드입니다. :)
추가적으로, 위에서 사용하는 envsetup.sh 스크립트는 모두 function으로 구현되어있으며,
기호에 따라 특정 함수들을 추가해서 사용할 수 도 있습니다. 어차피 스크립트이니까요. :)
댓글