前書き

Androidは、今日世界で最も人気のあるオペレーティングシステムです。 何百もの異なる相手先商標製造会社、またはOEMは、無料でオープンソースであり、アプリやサービスの大規模なエコシステムが構築されているため、デバイスにインストールすることを選択します。 残念ながら、多くのOEMはAndroidの無線(OTA)アップデートを定期的にプッシュしません。 また、他のOEMは、デバイスの発売後、限られた期間のみ更新を提供します。 さらに、OEMはAndroidを大幅にカスタマイズして、デバイスの外観がユニークになるようにします。 カスタマイズには、代替ランチャー、テーマシステムのユーザーインターフェイス、プリインストールアプリが含まれます。

これらのカスタマイズをすべて削除する場合、またはデバイスで純粋なAndroidの最新バージョンを実行する場合は、自分用に新しいファームウェアをビルドできます。 Android改造コミュニティでは、このようなファームウェアは通常ROMと呼ばれ、Read Only Memoryの略です。

このチュートリアルでは、https://source.android.com/ [Android Open Source Project]、または略してAOSPに基づいたAndroid Oreo ROMを構築します。 このチュートリアルをデバイスに依存せず汎用的にするために、AOSPエミュレーターのみをターゲットにしますが、実際のデバイスにも同じ手法を適用できます。

前提条件

フォローするには、次のものが必要です。

ステップ1-スクリーンセッションを開始する

このチュートリアルで実行するコマンドの一部は、数時間実行される可能性があります。 コマンドの実行中にPCとサーバー間のSSH接続が中断されると、コマンドは突然終了します。 このような状況を回避するには、単一の端末で複数のコンソールセッションを実行できる「+ screen +」ユーティリティを使用します。 画面を使用すると、実行中のセッションから切り離して、後で接続できます。 Screenを初めて使用する場合は、https://www.digitalocean.com/community/tutorials/how-to-install-and-use-screen-on-an-ubuntu-cloud-server [このチュートリアルをご覧くださいUbuntuでスクリーンを使用]。

新しい `+ screen +`セッションを開始します。

screen

初めて画面を実行すると、ライセンス契約が表示されます。 * Enter *を押してライセンスを受け入れます。

この時点から、SSH接続が失敗しても、長時間実行されるコマンドはバックグラウンドで実行され続けます。 SSH接続を再確立すると、「+ screen -r +」を実行してセッションを再開できます。

次に、Androidのコンパイルに必要なコンポーネントをインストールします。

ステップ2-依存関係のインストール

AOSPソースコードは、いくつかの異なるGitリポジトリに分散しています。 ユーザーがこれらすべてのリポジトリをダウンロードしやすくするために、AOSPコミュニティはhttps://storage.googleapis.com/git-repo-downloads/repo [+ repo +]というコマンドラインツールを作成しました。

`+ wget `を使用してツールの最新バージョンをダウンロードし、 `〜/ bin `ディレクトリに保存します。 まず、 `〜/ bin +`ディレクトリを作成します:

mkdir -p ~/bin

次に、 `+ repo +`スクリプトをダウンロードします。

wget 'https://storage.googleapis.com/git-repo-downloads/repo' -P ~/bin

現在のユーザーに `+ repo `を実行する許可を与えるには、 ` chmod +`を使用します。

chmod +x ~/bin/repo

`+ repo +`ツールは内部でGitを使用するため、ユーザー名とメールアドレスを指定してGit設定を作成する必要があります。 それを行うには、次のコマンドを実行します。

git config --global user.name ""
git config --global user.email ""

Androidのソースコードは、主にJava、C 、およびXMLファイルで構成されています。 ソースコードをコンパイルするには、OpenJDK 8、GNU Cおよび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 manifest repositoryで初期化する必要があります。これは、他のすべてのパスを指定する `+ default.xml +`という名前のXMLファイルを含む特別なGitリポジトリーです。一緒にAOSPコードベースを形成するGitリポジトリ。

AOSPコードツリー全体を操作するのは面倒です。 したがって、関心のある特定のリビジョンまたはブランチの名前を追加で指定する必要があります。 このチュートリアルでは、Oreo ROMを構築するため、ビルドIDが `+ OPD1.170816.025 `の ` android-8.0.0_r33 +`ブランチを使用します。 AOSPの公式https://source.android.com/setup/build-numbers [コード名、タグ、ビルド番号]ページから、利用可能なすべてのビルドIDとブランチ名のリストを取得できます。

さらに、このチュートリアルではコードツリーのコミット履歴全体を必要としません。 履歴を「1」の深さに切り捨てることで、時間とストレージスペースの両方を節約できます。

したがって、 `+ repo init +`コマンドを使用してディレクトリを初期化し、これらのオプションを指定します。

repo init -u https://android.googlesource.com/platform/manifest -b  --depth=

カラー表示を有効にするように求められたら、* Y を押してから Enter *を押します。

最後に、 `+ repo sync +`コマンドを実行して、さまざまなリポジトリから実際のAOSPファイルをダウンロードします。

repo sync

上記のコマンドは30 GBを超えるデータをダウンロードするため、完了するまでしばらくお待ちください。 それが完了したら、キャッシュを設定してコンパイルを高速化します。

手順4-コンパイラキャッシュの準備

ビルドを高速化するために、コンパイラキャッシュを使用できます。 その名前が示すように、コンパイラキャッシュは、既にコンパイルされているROMの部分を再コンパイルすることを回避するのに役立ちます。

コンパイラキャッシュの使用を有効にするには、 `+ USE_CCACHE +`という名前の環境変数を設定します。

export USE_CCACHE=1

十分な空きディスク容量がない限り、キャッシュが大きくなりすぎないように、サイズを制限できます。 単一のデバイス用にROMを構築する場合、15 GBに制限できます。 そのためには、 `+ ccache +`コマンドを使用します。

prebuilts/misc/linux-x86/ccache/ccache -M

この変更を行ったことを確認する出力が表示されます。

OutputSet cache size limit to  Gbytes

コンパイルする前に、さらに最適化を行う必要があります。 次はそれをしましょう。

ステップ5-ジャックの構成

ROMのJavaベースのほとんどの部分の構築を担当するJackサーバーには、大量のメモリが必要です。 メモリ割り当てエラーを回避するために、 `+ ANDROID_JACK_VM_ARGS +`という名前の環境変数を使用して、ジャックが使用できるメモリの量を指定できます。 通常、サーバーのRAMの約50%を割り当てれば十分です。 この環境変数は、他のコンパイル設定も指定します。

次のコマンドを実行して8 GBのRAMをJackサーバーに割り当て、Jackが必要とするデフォルトのコンパイルオプションを保持します。

export ANDROID_JACK_VM_ARGS="-Xmx -Dfile.encoding=UTF-8 -XX:+TieredCompilation"

これで、Android ROMを作成する準備が整いました。

ステップ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 +`のいずれかです。 `+ young`および + userdebug`ビルドタイプはテスト目的に最適なROMになりますが、 `+ user and`ビルドタイプは実稼働環境での使用をお勧めします。

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

このコマンドは、CPUSの数を返します。

Output8

次に、この番号を `+ make +`で使用して、並列実行を指定できます。

make -j

CPUが8個でも、サーバーでアクティブなCPU集中型プロセスが他にない場合、ビルドが完了するまで1時間以上待つ必要があります。 ビルドの期間は、RAMの量と使用しているCPUの数に直接比例します。 より高速なビルドが必要な場合は、最大32個のCPUと48 GBのメモリをサポートする専用のhttps://www.digitalocean.com/products/compute/high-cpu/[High CPU Droplets]の使用を検討してください。

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 `コマンドを実行して、それでエミュレータを起動してみてください。 GUI以外の環境にいる場合は、必ず「 -no-windows」および「+ -no audio +」フラグを渡してください。

emulator  > /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 -j

十分なディスク容量がないためにビルドが失敗した場合は、おそらく以前のビルドの結果をクリーンアップせずに複数回ビルドしようとしています。 以前のビルドの結果を破棄するには、次のコマンドを実行できます。

make clobber

または、DigitalOceanのhttps://www.digitalocean.com/community/tutorials/how-to-use-block-storage-on-digitalocean [ブロックストレージ]を使用して、ドロップレットにディスクスペースを追加することもできます。

結論

このチュートリアルでは、Android Oreo用のAOSPベースのROMを正常に構築しました。 今日学んだテクニックは、https://lineageos.org/ [Lineage OS]やhttp://www.resurrectionremix.com/[Resurrection Remix OS]など、AOSPのすべてのフォークにも適用できます。 Androidアプリの開発経験がある場合は、AOSPコードベースの小さな部分を変更して、ROMに個人的なタッチを与えることに興味があるかもしれません。

AOSPソースコードの作成の詳細については、Googleグループでhttps://groups.google.com/forum/?fromgroups#!forum/android-building[Android Building forum]をご覧ください。