Ubuntu16.04でAndroidROMを構築する方法
序章
Android は、今日世界で最も人気のあるオペレーティングシステムです。 何百もの異なる相手先ブランド供給(OEM)は、無料でオープンソースであり、アプリとサービスの大規模なエコシステムが構築されているため、デバイスにインストールすることを選択します。 残念ながら、多くのOEMは、Androidの無線(OTA)アップデートを定期的にプッシュしていません。 また、他のOEMは、デバイスの発売後、限られた期間のみ更新を提供します。 さらに、OEMは、Androidを大幅にカスタマイズして、デバイスが独自のルックアンドフィールを備えていることを確認する傾向があります。 それらのカスタマイズには、代替ランチャー、テーマ別システムユーザーインターフェイス、およびプリインストールされたアプリが含まれます。
これらのカスタマイズをすべて削除する場合、またはデバイスで純粋なAndroidの最新バージョンを実行する場合は、新しいファームウェアを自分でビルドできます。 Androidの改造コミュニティでは、このようなファームウェアは通常ROMと呼ばれ、読み取り専用メモリの略です。
このチュートリアルでは、 Android Open Source Project 、または略してAOSPに基づくAndroidOreoROMを構築します。 このチュートリアルをデバイスに依存せず一般的なものにするために、AOSPエミュレーターのみを対象としますが、実際のデバイスにも同じ手法を適用できます。
前提条件
フォローできるようにするには、次のものが必要です。
- Ubuntu 16.04初期サーバーセットアップガイドに従ってセットアップされた、少なくとも16 GBのRAM、4つのCPU、および120GBのストレージスペースを備えた1つのUbuntu16.04 x64サーバー(sudo非rootユーザーとファイアウォールを含む) 。 コンパイルプロセスには大量のRAMが必要であり、CPUが多いほどコンパイル時間が短縮されます。 さらに、ダウンロードしてビルドするファイルは非常に大きくなります。 DigitalOceanには高CPUドロップレットがあり、このプロジェクトに最適かもしれません。
- Ubuntu16.04にGitをインストールする方法に従ってGitをインストールします。
ステップ1—スクリーンセッションを開始します
このチュートリアルで実行するコマンドの一部は、数時間実行される可能性があります。 コマンドの実行中にPCとサーバー間のSSH接続が中断されると、コマンドは突然終了します。 このような状況を回避するには、screen
ユーティリティを使用します。このユーティリティを使用すると、1つの端末で複数のコンソールセッションを実行できます。 screenを使用すると、実行中のセッションから切り離して、後で再接続できます。 Screenを初めて使用する場合は、UbuntuでのScreenの使用に関するこのチュートリアルで詳細を確認してください。
新しいscreen
セッションを開始します。
- screen
画面を初めて実行すると、使用許諾契約が表示されます。 Enterを押してライセンスに同意します。
この時点から、SSH接続が失敗した場合でも、長時間実行されるコマンドはバックグラウンドで実行され続けます。 SSH接続を再確立すると、screen -r
を実行してセッションを再開できるようになります。
次に、Androidをコンパイルするために必要なコンポーネントをインストールしましょう。
ステップ2—依存関係のインストール
AOSPソースコードは、いくつかの異なるGitリポジトリに分散しています。 ユーザーがこれらすべてのリポジトリを簡単にダウンロードできるようにするために、AOSPコミュニティはrepoと呼ばれるコマンドラインツールを作成しました。
wget
を使用してツールの最新バージョンをダウンロードし、~/bin
ディレクトリに保存します。 まず、~/bin
ディレクトリを作成します。
- mkdir -p ~/bin
次に、repo
スクリプトをダウンロードします。
- wget 'https://storage.googleapis.com/git-repo-downloads/repo' -P ~/bin
注:別のサイトからダウンロードしたマシンでスクリプトを実行する際のセキュリティが心配な場合は、スクリプトの内容を調べてください。
- less ~/bin/repo
スクリプトの内容に慣れたら、このチュートリアルを続けてください。
chmod
を使用して、現在のユーザーにrepo
を実行する権限を付与します。
- chmod +x ~/bin/repo
repo
ツールは内部でGitを使用し、ユーザー名とメールアドレスを指定してGit構成を作成する必要があります。 これを行うには、次のコマンドを実行します。
- git config --global user.name "your name"
- git config --global user.email "your_email@your_domain.com"
Androidのソースコードは、主にJava、C ++、およびXMLファイルで構成されています。 ソースコードをコンパイルするには、OpenJDK 8、GNUCおよびC++コンパイラ、XML解析ライブラリ、ImageMagick、およびその他のいくつかの関連パッケージをインストールする必要があります。 幸い、apt
を使用してすべてをインストールできます。 その前に、サーバーのパッケージリストを更新してください。
- sudo apt-get update
リストが更新されたら、依存関係をインストールします。
- sudo apt-get install openjdk-8-jdk android-tools-adb bc bison build-essential curl flex g++-multilib gcc-multilib gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc yasm zip zlib1g-dev
依存関係がダウンロードされたら、repo
スクリプトを使用してAndroidソースを取得できます。
ステップ3—ソースコードをダウンロードする
repo
スクリプトを使用して、ワークスペースを準備するためのいくつかのタスクを実行します。 ダウンロードするAndroidソースを保存するための新しいディレクトリを作成します。
- mkdir -p ~/aosp/oreo
このチュートリアルの残りの部分ではこのディレクトリで作業するので、今すぐこのディレクトリに切り替えてください。
- cd ~/aosp/oreo
ディレクトリは、AOSP マニフェストリポジトリで初期化する必要があります。これは、default.xml
という名前のXMLファイルを含む特別なGitリポジトリであり、AOSPコードベースを形成する他のすべてのGitリポジトリのパスを指定します。
AOSPコードツリー全体を操作するのは面倒な場合があります。 したがって、関心のある特定のリビジョンまたはブランチの名前を追加で指定する必要があります。 このチュートリアルでは、Oreo ROMをビルドしているため、ビルドIDがOPD1.170816.025
であるandroid-8.0.0_r33
ブランチを使用します。 利用可能なすべてのビルドIDとブランチ名のリストは、AOSPの公式コードネーム、タグ、およびビルド番号ページから入手できます。
さらに、このチュートリアルでは、コードツリーのコミット履歴全体は必要ありません。 履歴を1
の深さまで切り捨てることで、時間とストレージスペースの両方を節約できます。
したがって、repo init
コマンドを使用してディレクトリを初期化し、次のオプションを指定します。
- repo init -u https://android.googlesource.com/platform/manifest -b android-8.0.0_r33 --depth=1
カラー表示を有効にするように求められたら、 Y を押してから、Enterを押します。
最後に、repo sync
コマンドを実行して、さまざまなリポジトリから実際のAOSPファイルをダウンロードします。
- repo sync
上記のコマンドは30GBを超えるデータをダウンロードするため、完了するまでしばらくお待ちください。 それが完了したら、コンパイルを高速化するためにキャッシュを設定します。
ステップ4—コンパイラキャッシュの準備
ビルドを高速化するために、コンパイラキャッシュを使用できます。 その名前が示すように、コンパイラキャッシュは、すでにコンパイルされているROMの部分の再コンパイルを回避するのに役立ちます。
コンパイラキャッシュの使用を有効にするには、USE_CCACHE
という名前の環境変数を設定します。
- export USE_CCACHE=1
十分な空きディスク容量がない限り、キャッシュが大きくなりすぎないようにするため、キャッシュのサイズを制限できます。 単一のデバイス用にROMを構築している場合は、15GBに制限できます。 これを行うには、ccache
コマンドを使用します。
- prebuilts/misc/linux-x86/ccache/ccache -M 15G
この変更を行ったことを確認する出力が表示されます。
OutputSet cache size limit to 15.0 Gbytes
コンパイルする前に、もう1つ最適化を行う必要があります。 次にそれをしましょう。
ステップ5—ジャックの構成
ROMのほとんどのJavaベースの部分の構築を担当するJackサーバーは、大量のメモリを必要とします。 メモリ割り当てエラーを回避するために、ANDROID_JACK_VM_ARGS
という名前の環境変数を使用して、ジャックが使用できるメモリの量を指定できます。 通常、サーバーのRAMの約50% ofを割り当てるだけで十分です。 この環境変数は、他のコンパイル設定も指定します。
次のコマンドを実行して、8 GBのRAMをJackサーバーに割り当て、Jackが必要とするデフォルトのコンパイルオプションを保持します。
- export ANDROID_JACK_VM_ARGS="-Xmx8g -Dfile.encoding=UTF-8 -XX:+TieredCompilation"
これで、AndroidROMを構築する準備が整いました。
ステップ6—ビルドを開始する
AOSPコードツリーには、envsetup.sh
という名前のスクリプトが含まれています。このスクリプトには、ビルド関連のヘルパー関数がいくつかあります。 mm
、mma
、mmm
などのヘルパー関数の多くは、make
コマンドのショートカットとして機能しますが、lunch
特に、ROMのCPUアーキテクチャ、およびビルドのタイプを決定する重要な環境変数を設定します。
スクリプトを入手して、ヘルパー関数にアクセスします。
- source build/envsetup.sh
Outputincluding device/asus/fugu/vendorsetup.sh
including device/generic/car/car-arm64/vendorsetup.sh
including device/generic/car/car-armv7-a-neon/vendorsetup.sh
including device/generic/car/car-x86_64/vendorsetup.sh
including device/generic/car/car-x86/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips64/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/google/dragon/vendorsetup.sh
including device/google/marlin/vendorsetup.sh
including device/google/muskie/vendorsetup.sh
including device/google/taimen/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/linaro/hikey/vendorsetup.sh
including sdk/bash_completion/adb.bash
次に、lunch
を実行し、デバイスのコードネームを、eng
、userdebug
、またはuser
のいずれかのビルドタイプの接尾辞としてデバイスに渡します。 。 eng
およびuserdebug
ビルドタイプはテスト目的に最適なROMになりますが、user
ビルドタイプは実稼働での使用をお勧めします。
AOSP ARMエミュレータで実行できるテストROMを構築するには、aosp_arm-eng
をlunch
コマンドに渡します。
- lunch aosp_arm-eng
この出力が表示され、環境設定が示されます。
Output============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.0.0
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPD1
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.4.0-104-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPD1.170816.025
OUT_DIR=out
AUX_OS_VARIANT_LIST=
============================================
最後に、make
を実行してビルドを開始します。 make
は並列ジョブをサポートしているため、-j
オプションを使用して、サーバーで使用可能なCPUの数と同じ数の並列ジョブを設定することでビルドを大幅に高速化できます。
nproc
コマンドを使用して、使用しているCPUの数を確認します。
- nproc
このコマンドは、CPUの数を返します。
Output8
次に、この番号をmake
とともに使用して、並列実行を指定できます。
- make -j8
8つのCPUを使用している場合でも、サーバー上でアクティブなCPUを集中的に使用するプロセスが他にない場合は、ビルドが完了するまで1時間以上待つ必要があります。 ビルドの期間は、RAMの量とCPUの数に正比例します。 より高速なビルドが必要な場合は、最大32個のCPUと48GBのメモリをサポートする専用の高CPUドロップレットの使用を検討してください。
注:ビルド中に多くの警告メッセージが生成されます。 あなたはそれらを安全に無視することができます。
ROMの準備が整うと、ビルドが正常に完了したことを示すメッセージが表示されます。 ビルドの正確な期間も確認できます。
Output...
Creating filesystem with parameters:
Size: 2147483648
Block size: 4096
Blocks per group: 32768
Inodes per group: 8192
Inode size: 256
Journal blocks: 8192
Label: system
Blocks: 524288
Block groups: 16
Reserved block group size: 127
Created filesystem with 2266/131072 inodes and 178244/524288 blocks
[100% 63193/63193] Install system fs i... out/target/product/generic/system.img
out/target/product/generic/system.img+ maxsize=2192446080 blocksize=2112 total=2147483648 reserve=22146432
#### make completed successfully (01:05:44 (hh:mm:ss)) ####
物事が正しく構築されていることを確認しましょう。
ステップ7—ビルドの確認
ビルドプロセスの出力は、ROMを形成する複数のファイルシステムイメージで構成されます。 それらはout/target/product/generic/
ディレクトリにあります。
- ls -l out/target/product/generic/*.img
Output-rw-r--r-- 1 sammy sammy 69206016 Jan 5 18:51 out/target/product/generic/cache.img
-rw-rw-r-- 1 sammy sammy 1699731 Jan 5 19:09 out/target/product/generic/ramdisk.img
-rw-r--r-- 1 sammy sammy 2147483648 Jan 5 19:10 out/target/product/generic/system.img
-rw-r--r-- 1 sammy sammy 576716800 Jan 5 19:09 out/target/product/generic/userdata.img
ROMをテストするには、emulator
コマンドを実行して、ROMを使用してエミュレーターを起動してみます。 GUI以外の環境にいる場合は、必ず-no-window
および-noaudio
フラグを渡してください。
- emulator -no-window -noaudio > /dev/null 2>&1 &
エミュレータが正常に起動したかどうかを確認するには、1分待ってから、Androidデバッグブリッジツールadb
を使用して、エミュレータでシェルを開きます。
- adb shell
ROMに問題がない場合は、エミュレータで実行されているシェルからのプロンプトが表示されます。
Output* daemon not running; starting now at tcp:5037
* daemon started successfully
generic:/ #
exit
と入力してENTER
を押すか、CTRL+D
を押して、このシェルを終了します。
注:エミュレーターが起動する前にシェルを開こうとすると、エミュレーターがオフラインであることを通知するエラーメッセージが表示されます。 しばらく待ってから、もう一度やり直してください。
トラブルシューティング
ビルドが失敗した場合、最も可能性の高い原因はメモリ不足です。 これを修正するには、最初に次のコマンドを実行してJackサーバーを強制終了します。
- jack-admin kill-server
次に、ビルドを再開しますが、許可される並列ジョブは少なくなります。 たとえば、並列ジョブの数を2つに減らす方法は次のとおりです。
- make -j2
ディスク容量が不足しているためにビルドが失敗した場合は、以前のビルドの結果をクリーンアップせずに、複数回ビルドしようとしている可能性があります。 以前のビルドの結果を破棄するには、次のコマンドを実行できます。
- make clobber
または、DigitalOceanの Block Storage を使用して、ドロップレットにディスク容量を追加することもできます。
結論
このチュートリアルでは、AndroidOreo用のAOSPベースのROMを正常に構築しました。 今日学んだテクニックは、 LineageOSやResurrectionRemix OS など、AOSPのすべてのフォークにも適用できます。 Androidアプリの開発経験がある場合は、AOSPコードベースのごく一部を変更して、ROMに個人的なタッチを与えることに興味があるかもしれません。
AOSPソースコードの作成について詳しくは、GoogleグループのAndroidBuildingフォーラムをご覧ください。