다른 빌드 시스템과의 차이점
AOSP는 대부분의 make 기반 빌드 시스템과는 다르게 안드로이드 빌드 시스템은 재귀적 makefile을 사용하지 않는다는 점이다. 대신 모든 디렉터리와 하위 디렉터리를 탐색해서 Andoird.mk 파일을 찾아내는 스크립트가 있다. 이 파일을 찾으면 그 위치에서 멈추고 더 이상의 하위 디렉터리는 탐색하지 않는다. Andoird.mk 안에서 하위 디렉터리를 탐색하라고 명시한 경우에만 탐색을 계속 이어나간다. 안드로이드는 Makefile이라는 이름의 makefile의존하지 않는다. 대신 Andoird.mk 파일에서 로컬 모듈들이 어떻게 빌드되어야 하는지를 명시한다. 안드로이드 빌드 시스템의 설정 방식 역시 독특하다. 안드로이드는 셀 환경에서 envsetup.sh 와 lunch로 동적으로 생성하거나 buildspec.mk 파일로 미리 정의해둔 변수들을 활용한다. 또한. 빌드 시스템은 소스 파일과 같은 위치에 객체 파일 등의 중간 출력을 생성하지 않는다. 모든 생성물은 out/ 디렉터리에 저장한다. |
아키텍처
위 그림에서 묘사한 대로 빌드 시스템 입장에서 타당한 진입점은 build/core/ 디렉터리의 main.mk 파일이다. 이 파일은 최상위 makefile을 호출한다. |
설정
빌드 시스템이 시작되면 build/core/config.mk 에서 빌드 설정을 가져온다. 빌드는 envsetup.sh 와 lunch 명령의 조합 또는 최상위 디렉터리에 buildspec.mk 파일을 만드는 방식 중 하나로 설정할 수 있다. 둘 중 어느 것이는 다음 변수 중 일부를 설정해야 한다.
|
envsetup.sh
이름에서 짐작할 수 있듯이 envsetup.sh는 안드로이드의 빌드 환경을 설정하는 데 사용된다. 하지만 이 파일에서는 그중 일부만 설정하며 주로 다음과 같이 AOSP 관련하여 유용한 일련의 쉘 명령을 정의한다. 디렉터리를 탐색하는 데는 croot와 godir 명령이 유용할 것이다. 특히 자바는 패키지명이 디렉터리 구조에 그대로 반영 되기 때문에 상당히 깊은 디렉터리 트리를 만들기도 한다. m과 mm도 유용하다. m은 어느 경로에 있든 전체를 빌드하며, mm은 현재 디렉터리에 있는 모듈만 빌드한다. 예를들어 Launcher를 수정했고 현재 package/apps/Launcher2에 있다면 cd 명령으로 최상위 디렉터리로 돌아가 make 를 실행 하는 대신 mm을 실행하면 해당 모듈만 다시 빌드할 수 있다. 주위할 점은 mm은 전체 트리를 다시 빌드하지 않기 때문 에 의존 모듈이 변경되어도 AOSP 이미지를 다시 생성하지 않는다. 반면 m은 전체 이미지까지 다시 생성한다. |
build/envsetup.sh 실행후
함수 정의
build/core/에만 40개가 넘는 .mk 파일들이 있다. 이처럼 빌드 시스템이 무척 크기 때문에 되도록 코드를 재사용 하는 편이 좋다. 이 때문에 빌드 시스템은 definitions.mk 파일에 많은 함수를 정의한다. 이 파일의 용량도 빌드 시스템 전체 에서 가장 크다. 170개 함수와 2,100 줄의 makefile 코드로 이루어진다.(버전 4 기준) 이 함수들은 빌드 시스템 전반에서 핵심 라이브러리처럼 사용될 뿐만 아니라 때떄로 각 모듈의 Android.mk파일에서 직접 사용하기도 한다. 대부분의 함수 앞에는 동작 방식을 설명하는 주석이 달려있다. |
주요 Make
이쯤 되면 주요 산출물들이 언제 생성되는지 궁금해질 것이다. 램 디스크와 같은 이미지들은 어떻게 생성되고 SDK는 어떻게 합쳐질까? build/core/의 Makefile을 살펴보자 (최상위 디렉터리가 아니므로 착오 없기 바란다.) 다음 정도는 어떻게 생성되는지 살펴보기 바란다.
커널 이미지
|
빌드 청소
make clean을 실행 하는것은 out/ 디렉터리의 내용을 삭제하는 것과 같다. clean은 main.mk 에 정의되어 있다. 다른청소 타깃으로 cleanbuild.mk에 정의 되어 있는 installclean이 있다. installclean은 TARGET_PRODUCT, TARGET_BUILD_VARIANT, PRODUCT_LOCALES를 변경할 때마나 자동으로 실행된다. 예를 들어 lunch를 사용하여 타겟을 변경하고 다음번 make를 실행할 때 일부 빌드 결과물은 installclean으로 자동 정리된다. |
모듈 빌드 템플릿
안드로이드 시스템은 각 모듈의 빌드 방식이 빌드 시스템에 종속되지 않도록 설계되었다. 대신 모듈용 빌드 템플릿을 제공하여 모듈 작성자가 전체 시스템과 독립적으로 모듈을 빌드할 수 있도록 하였다. 템플릿도 다른 빌드 시스템 파일들과 같이 build/core/에 담겨 있다. Android.mk가 특정 템플릿을 가져올 때는 include 지시자를 사용한다. 예) include $(BUILD_PACKAGE) |
LOCAL_* 변수들
결과물
크게 보면 빌드 출력은 세 개의 단계를 거쳐 진행되며 호스트(host)와 타깃(target)이라는 두가지 모드로 동작한다.
out/은 크게 host/ 와 target/ 두 디렉터리로 나누어지는데 어느 쪽이 되는지는 동작모드가 결정한다. 각 디렉터리의 obj/ 디렉터리에는 빌드과정에서 만들어진 여러 중간 생성물들이 들어가게 된다. 가장 관심을 가질 만한 디렉터리는 out/target/product/PRODUCT_DEVICE/ 이다. 해당 제품설정의 .mk 파일에서 PRODUCT_DEVICE로 정의한 결과 이미지가 여기에 저장된다.
|
개별 모듈 빌드하기
모듈을 하나씩 빌드할 수도 있다. 다음은 빌드 시스템에서 Launcher2 모듈(홈 화면) 을 빌드하는 방법이다.
개별 모듈 빌드를 초기화할 수도 있다.
갱신된 모듈을 포함하도록 시스템 이미지를 다시 생성하고 싶으면 명령행에 snod를 추가한다.
|
출처 : 임베디드 안드로이드 : 안드로이드 포팅, 확장, 커스터마이징하기 ( 한빛미디어 (카림 야크무르 지음, 이성주 옮김))
'임베디드 > 안드로이드 포팅' 카테고리의 다른 글
안드로이드 포팅 6-1 네이티브 사용자 공간 ( 파일시스템 ) (0) | 2017.09.01 |
---|---|
안드로이드 포팅 5-1 하드웨어 기초 (0) | 2017.08.30 |
안드로이드 포팅 3-1 기기 추가하기 (2) | 2017.07.27 |
안드로이드 포팅 2-1 ADB 사용하기 (0) | 2017.07.26 |
안드로이드 포팅 1-2 AOSP 빌드하기 (1) | 2017.07.25 |