안드로이드 프레임워크를 다루거나 시스템 레벨의 커스텀 펌웨어를 개발할 때 가장 먼저 통과해야 하는 관문이 있습니다. 바로 안드로이드 오픈소스 프로젝트인 AOSP(Android Open Source Project)를 직접 빌드해 보는 것입니다.
구글이 친절하게 소스 코드를 공개해 두었지만, 막상 빌드를 시작하려고 하면 엄청난 소스 크기와 까다로운 리눅스 환경 설정 때문에 컴파일 에러를 마주하고 좌절하기 쉽습니다. 그래서 이번 포스팅에서는 우분투(Ubuntu) 환경을 기준으로 AOSP 소스 코드를 안전하게 다운로드하고, 빌드하여, 에뮬레이터나 실제 기기에 플래싱하는 전체 과정을 실무 팁과 함께 차근차근 정리해 보겠습니다.

📌 핵심 요약 3줄
- AOSP 빌드는 고사양의 리눅스(Ubuntu) 환경이 필수적이며, 구글의 수많은 저장소를 관리하기 위해 repo 도구를 기본으로 사용합니다.
- envsetup.sh 스크립트로 환경 변수를 초기화한 뒤, 타겟 기기에 맞는 lunch 콤보를 선택하여 병렬 컴파일(m -j)을 수행합니다.
- 빌드가 완료된 이미지는 emulator 명령어로 가상 가동하거나, fastboot 도구를 이용해 실제 디바이스 파티션에 플래싱할 수 있습니다.
1. AOSP 빌드를 위한 하드웨어 사양 및 환경 검증
AOSP는 수천만 줄의 코드로 이루어진 거대한 프로젝트입니다. 컴파일 도중 메모리가 부족해서 빌드가 터지는 불상사를 막으려면 내 PC가 최소 사양을 만족하는지 먼저 체크해야 합니다. 안드로이드 13 빌드 기준으로 필요한 사양을 표로 정리했습니다.
| 구분 | 최소 요구 사양 | 권장 개발 사양 | 비고 |
| 운영체제 (OS) | Ubuntu 20.04 LTS (64비트) | Ubuntu 22.04 LTS 이상 | 데비안(Debian) 계열 리눅스 표준 |
| 중앙처리장치 (CPU) | Intel / AMD 8코어 이상 | 16코어 / 32스레드 이상 | 코어 수가 많을수록 빌드 속도 비약적 상승 |
| 메모리 (RAM) | 최소 32GB 이상 | 64GB 이상 | 16GB 이하 환경에서는 링크(Link) 단계에서 100% 뻗음 |
| 저장 공간 (Storage) | 최소 400GB 이상의 여유 공간 | 1TB 이상의 NVMe SSD | 소스 다운로드에 약 150GB, 빌드 산출물에 150GB 이상 소모 |
2. 빌드 환경 설정 및 필수 도구 설치
2.1 필수 패키지 및 개발 킷(JDK) 설치
우분투 터미널을 열고 컴파일러와 빌드에 필요한 도구들을 한 번에 설치해 줍니다. 안드로이드 13 버전을 빌드할 때는 OpenJDK 11 버전이 호환됩니다.
# 1. 시스템 업데이트 및 필수 의존성 패키지 설치
sudo apt update && sudo apt upgrade -y
sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib \
libc6-dev-i386 libncurses5 libncurses5-dev lib32ncurses5-dev x11proto-core-dev libx11-dev \
lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip
# 2. 안드로이드 13 빌드용 OpenJDK 11 설치
sudo apt install -y openjdk-11-jdk
# 3. 자바 버전 정상 설치 여부 확인
java -version
2.2 구글 Repo 도구 설치 및 환경 변수 등록
AOSP는 수백 개의 독립된 Git 저장소들이 모여 하나의 거대한 구조를 이룹니다. 이를 유기적으로 제어하기 위해 구글이 배포하는 repo 파이썬 스크립트를 설치하고 경로 환경 변수를 지정해 줍니다.
# 로컬 bin 디렉토리 생성 및 repo 다운로드
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
# 사용 중인 쉘 설정 파일(.bashrc)에 경로 상시 등록
echo 'export PATH=~/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
3. AOSP 소스 코드 동기화 및 컴파일
3.1 소스 코드 다운로드 (Repo Sync)
소스를 저장할 넉넉한 공간의 디렉토리를 만들고, 원하시는 안드로이드 타겟 브랜치 버전을 지정해 초기화한 뒤 다운로드를 시작합니다.
mkdir ~/aosp
cd ~/aosp
# 안드로이드 13 안정화 버전 매니페스트 초기화
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r41
# 현재 PC의 CPU 코어 수(nproc)만큼 병렬로 전체 소스 동기화 (수 시간 소요)
repo sync -j$(nproc)
3.2 빌드 타겟 설정 및 빌드 실행
동기화가 무사히 끝났다면 프레임워크 빌드 스크립트들을 로드하고 컴퓨터가 시뮬레이션할 수 있는 레퍼런스 아키텍처(lunch 콤보)를 선택해 컴파일을 시작합니다.
# 1. 빌드 환경 명령어 세트 로드
source build/envsetup.sh
# 2. 빌드 타겟 선택 (aosp_arm-eng: ARM 아키텍처 에뮬레이터용 엔지니어링 버전)
lunch aosp_arm-eng
# 3. CPU 연산 능력을 최대로 끌어올려 병렬 빌드 시작
m -j$(nproc)
빌드가 정상적으로 완수되면 모든 실행 파일과 펌웨어 컴포넌트들이 out/target/product/generic_arm/ 하위 디렉토리에 시스템 이미지(.img) 형태로 떨어집니다.
4. 빌드 완료 이미지 구동 및 플래싱
4.1 가상 환경(에뮬레이터)에서 부팅 테스트
따로 연결된 하드웨어 장비가 없다면 프레임워크 빌드 환경이 유지된 터미널 상태에서 그대로 내장 에뮬레이터를 호출해 구동해볼 수 있습니다.
# lunch 설정이 잡혀있는 터미널에서 입력
emulator
잠시 후 화면에 안드로이드 로고가 뜨면서 우리가 방금 직접 빌드한 순정 가상 단말기가 정상 작동하는 모습을 볼 수 있습니다.
4.2 실제 레퍼런스 기기(픽셀폰 등)에 플래싱
만약 에뮬레이터용이 아니라 픽셀(Pixel) 시리즈 같은 실제 스마트폰 타겟으로 빌드했다면 부트로더 모드에서 파티션을 밀고 이미지를 주입해야 합니다.
# 1. 디바이스를 스마트폰 부트로더(Fastboot) 모드로 진입시킨 후 PC 연결 확인
fastboot devices
# 2. 기존 사용자 데이터를 모두 밀어버리며(-w) 빌드된 모든 시스템 이미지 한 번에 플래싱
fastboot flashall -w
# 3. 플래싱 완료 후 기기 재부팅
fastboot reboot
🛠️ 개발을 위한 팁 (Tips)
- ccache 활성화로 재빌드 시간 단축: AOSP를 처음 빌드할 때는 몇 시간이 걸리지만, 소스 코드 한두 줄 고치고 다시 빌드할 때 또 그 시간을 기다릴 수는 없습니다. 컴파일러 캐시 도구인 ccache를 켜두면 바뀐 부분만 영리하게 빌드해 주므로 시간이 대폭 줄어듭니다. source build/envsetup.sh 실행 전에 export USE_CCACHE=1과 export CCACHE_DIR=~/.ccache를 입력하고 prebuilts/misc/linux-x86/ccache/ccache -M 50G로 용량을 할당해 보세요.
- 사전 빌드된 제조사 벤더 바이너리(Driver) 누락 주의: 실제 픽셀폰 같은 물리 단말기에 내가 빌드한 AOSP를 올리려면 구글 드라이버 페이지에서 해당 기기 및 빌드 넘버와 일치하는 '독점 바이너리(Proprietary Blobs)' 스크립트를 다운받아 소스 루트 폴더에 풀고 실행한 뒤 빌드해야 합니다. 이걸 빼먹으면 빌드가 성공해서 플래싱이 되더라도 와이파이나 카메라, 센서 등이 아예 작동하지 않는 깡통 폰이 됩니다.
⚠️ 흔히 하는 실수 (Common Mistakes)
- 스왑 메모리(Swap) 미설정으로 인한 컴파일러 크래시: 간혹 빌드가 90% 이상 잘 가다가 internal compiler error: Killed 혹은 ninja: build stopped: subcommand failed 문구와 함께 멈추는 경우가 있습니다. 이는 링크 단계에서 램(RAM) 용량이 순간적으로 고갈되어 우분투 시스템이 컴파일 프로세스를 강제 종료한 것입니다. 물리 램이 32GB 이하 환경이라면 우분투 상에서 최소 16GB 이상의 스왑(Swap) 파일 공간을 미리 생성해 메모리 숨통을 틔워주어야 에러를 피할 수 있습니다.
- repo sync 도중 네트워크 단절에 의한 소스 오염: 다운로드 용량이 워낙 방대하다 보니 무선 와이파이 환경이나 불안정한 네트워크에서 다운로드를 걸어두면 패킷이 깨져 소스 트리가 꼬이는 경우가 생깁니다. 이 상태로 빌드를 돌리면 원인 불명의 자바/C++ 문법 에러가 뿜어져 나옵니다. 되도록 안정적인 유선 랜 환경에서 다운받으시고, 미심쩍을 때는 repo sync -c --force-sync 명령어로 소스 정합성을 다시 맞춰주어야 합니다.
5. 결론
이번 포스팅에서는 안드로이드 생태계의 뿌리라고 할 수 있는 AOSP 소스 코드를 받아 빌드 환경을 구축하고 이를 디바이스에 올리는 대장정을 다뤄보았습니다. 처음 환경 세팅을 할 때는 명령어도 낯설고 에러도 잦아서 진입 장벽이 높게 느껴지지만, 가상 에뮬레이터에 내가 만든 OS 커널 문구가 찍혀 나오는 순간의 희열은 이루 말할 수 없습니다.
플랫폼 개발자나 시스템 보안 연구원에게는 이 빌드 아키텍처 자체가 훌륭한 자산이 되므로 꼭 본인의 리눅스 PC에서 한 번쯤 완주해 보시길 권장합니다. 빌드 중간에 막히는 정체불명의 에러 로그가 있다면 언제든 댓글로 질문을 남겨주세요. 같이 원인을 분석해 봅시다!
'Android System & AOSP Engineering > AOSP Framework & Custom Services' 카테고리의 다른 글
| Android 디바이스 포팅 가이드: BoardConfig 설정과 Device Tree 커널 구성 (0) | 2025.04.20 |
|---|---|
| AOSP 소스 코드 수정 가이드: SystemUI 커스텀 및 Framework 시스템 서비스 추가 (0) | 2025.04.19 |
| Android System API 사용법과 Hidden API 접근 우회 및 커스텀 가이드 (0) | 2025.04.16 |
| Android IPC 기법 총정리: Broadcast부터 AIDL, AOSP 활용까지 (0) | 2025.04.15 |
| Android 프레임워크 동작 원리: 계층 구조부터 Context와 Binder IPC까지 (0) | 2025.04.14 |