「Delphi/C++Builder on Hyper-V仮想マシン」でAndroid向けの開発環境を作る

これは [Delphi Advent Calendar 2017](https://qiita.com/advent-calendar/2017/delphi) 10日目の記事です。

# この記事が想定する対象読者

この記事は、以下のような方向けを想定して書いています

- Delphi/C++Builderを試してみたいけど、既存の作業環境を汚したくない
- Delphi/C++Builderを仮想マシン上で動かしたいけど、VMware や VirtualBox ではなく、マイクロソフト標準機能である Hyper-V を利用したい
- Delphi/C++Builderを Hyper-V 上の仮想マシンにインストールしたけど仮想マシンから Android に USB 接続できずに困っている

そして記事のタイトルには「Android向けの開発環境を作る」とありますが、Android 向けの開発環境セットアップ手順の詳細は下記の記事やビデオなど、様々なリソースがあります。これらをご覧頂いて手順どおりに行えば基本的な環境構築は特に難しいことも無く完了します。

https://community.embarcadero.com/blogs/entry/howto-configure-android-app-development-japan
https://www.youtube.com/watch?v=RHPPD594ljw

ですので、この記事では Hyper-V に特有の内容に絞ってご説明します。


# Hyper-V 仮想マシンの問題 = Hyper-V のデフォルト設定では USB デバイスを認識しない

この記事でわざわさ Hyper-V を取り上げるのは、デスクトップ環境で Hyper-V 上にインスタンスを作っただけでは USB デバイスを仮想マシンで利用できないからです。Android アプリの開発では Android を USB 接続した上でビルドしたアプリを送り込むのが基本の操作ですが、これが行えないのは困ります。

たとえば、このスクリーンショットはホスト側、ゲスト側でデバイスマネージャを実行中の状態です。Nexus5X はホスト側のデバイスマネージャに表示されていることが分かります。

![ホストマシンと仮想マシンのデバイスマネージャ-ホスト側にNexus5Xが見えている状態.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/d0e4b7a1-3035-d34a-07a3-5f0357a8a419.jpeg)

しかし Hyper-V の仮想マシン設定には USB 関連の設定項目が見当たりません。これでは USB デバイスが使えないように見えてしまいます。

![hyper-vｰ設定画面.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/270ce5a8-a041-9afc-2ce2-c360ac96c0e1.jpeg)

ならば VMware や VirtualBox にすれば良いのでは、という話もありそうですが、Windows 上で Docker for Windows を使いたい場合は Hyper-V を選ばざるを得ません（Docker for Windows は Hyper-V で動作するので）。また、Hyper-V を実行中の環境に VMware や VirtualBox をインストールすることもできません。

さて困りました。しかし、実は、Hyper-V ではUSBデバイスを使うことはできるんです。VMware や VirtualBox とは設定方法が違うだけなのです。しかしこの手順は案外知られていないようなので、本記事では、Hyper-V の仮想マシン内から Android 実機に USB 接続する手順を紹介します。そして Android を USB で接続できたら、さらに設定を調整するとUSB接続無しにネットワーク経由で接続できます。この方法も続けて紹介します。

なお、本記事では Windows 10 Professional Fall Creators Update (Version 1709) 64-bit を使用しています。Hyper-V は 32-bit Windows では利用できませんので、普通に VMware や VirtualBox を使ってください。


# そもそも、なぜ Hyper-V なのか？

この記事で Hyper-V を取り上げるのは、Docker 以外にもう一つあります。それは**「Hyper-V 環境では、新規の仮想マシン作成の際に Windows 10 Enterprise を90日間試用可能な仮想マシンイメージが選択できる」**点にあります。

通常なら仮想マシンへのOSインストールは以下の手順で行いますよね。

- 必要なスペックの仮想マシンを作る
- OSインストール用のISOイメージから起動してインストールする

しかしクラウドサービスでインスタンスを立てる場合にこんな手順は踏みません。選定したスペックのインスタンスで利用可能なOSイメージを選ぶだけです。あるいは Docker を使う場合もゼロからコンテナを作ることはあまりやらず、Docker image を選んで利用します。

これと同様の操作が Hyper-V で行えるのですよ。しかもオープンソースのOSではなく、Windows 10で。これはとても便利だと思います。アプリケーションの試験実行や何かの作業手順の確認など、様々な用途に利用できます。ただし初回だけはインターネット側から仮想マシンイメージをダウンロードするための待ち時間が必要ですし、ローカルにダウンロードしたイメージからインスタンスが立ち上がるまでの待ち時間も必要です。

でもこういった環境を用いれば Delphi/C++Builder/RAD Stuidoのトライアル版を試してみたいと考えた場合にも、試験環境がカンタンに作成できるのです。


# Hyper-V から Android に接続するための方法２つとは？

Hyper-V で仮想マシンを作成し、Delphi/C++Buidlerのトライアル版のインストールが済んでいたら、いよいよ本記事の目的である、Hyper-V の仮想マシンから Android に接続する話に進みます。

## 1. Hyper-V の RemoteFX USB リダイレクトを利用する

Hyper-V には RemoteFX USBリダイレクトという機能があります。これを用いればゲストマシン側に Android デバイスを接続・認識させることができます。このスクリーンショットは実際に RemoteFX USB リダイレクトを用いた状態です。ホストマシン側のデバイスマネージャからは Nexus 5x が消えていて、ゲストマシン側のデバイスマネージャに Nexus 5X が見えています。

![ホストマシンと仮想マシンのデバイスマネージャ-ゲスト側にNexus5Xが見えている状態.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/1717917a-3db4-d10a-be83-748b388454f6.jpeg)

しかし Hyper-V の仮想マシン設定を開いてみても USB の項目が見当たりません。先程のスクリーンショットをもう一度引用しますが、ご覧のとおりです。

![hyper-vｰ設定画面.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/270ce5a8-a041-9afc-2ce2-c360ac96c0e1.jpeg)

VMware や VirtualBox, Parallels に慣れた方なら、ここで諦めてしまいそうですが、実はシンプルかつ肝心なポイントが２つあるのです。

1. Hyper-V では仮想マシン設定から USB を設定するのではなく、**仮想マシンへの接続時に設定しなければならない**
2. Hyper-V仮想マシンで使用したいUSBデバイスは、**Hyper-V仮想マシンへの接続を始める前にホストマシンに接続しておく**

では早速、やってみましょう。Android 実機を接続の後、Hyper-V マネージャから仮想マシンへの接続を開始しますと、次のダイヤログが表示されているはずです。

通常はここで「接続」を選ぶだけですけど、ここで、あえて**「オプションの表示」を選びます**。

![connection-config-0.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/12164e2b-b3a8-6c40-014d-a24bf92b5496.jpeg)

さらに「**ローカルデバイスとリソース」の「詳細」**を開き…
![connection-config-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/0a0d3300-0c7c-978d-198a-cabdca71364c.jpeg)

**「その他のサポートされているRemoteFX USB デバイス」**を開いてみると、Android 実機が認識されているはずです。**Windows10のバージョンによっては「その他のサポートされているプラグアンドプレイ(PnP)デバイス」と表記**されているかもしれません。これにチェックを入れて接続を行えばよいのです。
![connection-config-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/640ff227-2cdf-61c8-52cf-e6a68afbde1d.jpeg)

これで準備は完了しました。やってみると案外単純なのですが、VMwareやVirtualBoxの経験で設定方法を探していたら、この方法を見つけることはできないでしょう。

ここまで準備して接続すれば、Hyper-V 仮想マシンが Android と USB 接続した状態になっています。デバイスマネージャ等で接続できていることを確認してください。


## 2. adb でネットワーク経由の接続を作る

ここまでの作業で Hyper-V 仮想マシンから Android に USB 接続できるようになりました。

でも、これを毎回行うのは、ちょっとめんどくさいですね。

そこで、ここではさらに設定を変えて、TCP/IP ネットワーク経由で接続することにします。Android 実機への接続は adb を使用していますが、adb では USB 接続の他に LAN 接続もサポートされています。ただし LAN 接続はデフォルトでは無効であり、USB 接続した状態から設定変更します。

Windows環境では AndroidSDk に adb.exe が含まれていますので、これを使います。Delphi/C++BuilderでAndroid向け開発環境構築を行った場合は、以下のようなパスに adb.exe が配置されています。（この例では 10.2 Tokyo でのパスを示しています）

```
C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-*\platform-tools
```

または、Delphi/C++BuilderのSDKマネージャで adb の場所を確認することもできます。

![SDKマネージャ.png](https://qiita-image-store.s3.amazonaws.com/0/149350/91fb38dc-120e-1610-b479-7263bdef4e74.png)


場所が確認できたら adb コマンドが実行できるように環境を整えて ```adb devices``` と実行します。

```
> adb devices
List of devices attached
xxxxxxxxxxx devices
```

xxxxxxxxxxx の部分には実際に接続中の Android の情報が出力されているはずです。このように表示されていれば、USB 接続された Android が認識出来ています。何も表示されない場合は実機側のUSBデバッグ機能が有効かどうか、あるいはHyper-V仮想マシンがUSBデバイスとして認識されているかどうかを確認してください。


接続できていたら、さらに次のようにコマンドを実行します。AndroidデバイスのIPアドレスは Android 上の設定アプリで確認してください。

```
adb tcpip 5555
adb connect [AndroidデバイスのIPアドレス]
adb devices
```

この３つのコマンドがすべて実行できていれば、List of devices attached にはUSB接続とネットワーク接続の２つのデバイスが見えているはずです。

![adb.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/a4da0eb9-d87a-3914-6a12-6c0eb7c5980e.jpeg)

ここでさらにUSB接続を外して ```adb devices``` を実行します。今度はネットワーク接続のデバイスだけが見えている状態になりました。


これでネットワーク経由での Android 向け接続設定ができました。次回以降は adb connect [AndroidデバイスのIPアドレス] だけでOKです。
 
なお、この状態は 5555 ポートが開いた状態なので、社外に持ち出さない端末で行うのが良いと思います。またネットワーク経由のデバッグを無効化するには、```adb usb [androidデバイスのIPアドレス]``` と実行します(USB接続が有効な状態で ```adb usb``` でも可能)


ネットワーク経由の adb が設定できたら、Delphi/C++Builder の IDE から認識できることを確かめます。

Delphi/C++Builder を起動してビルドターゲットを Android に変更し、デバイス選択のリストボックスに以下のスクリーンショットのようにネットワーク接続のデバイスが見えていればOKです。

![ネットワーク接続のAndroidをIDEから![create-new-windows10-dev-environment-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/b1adb6d8-dab5-571d-0611-ac9b049a029a.jpeg)
![create-new-windows10-dev-environment-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/7b16b224-6750-92ee-81d5-f29a48151c64.jpeg)
![create-new-windows10-dev-environment-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/fd30b6d6-65db-6eac-2dee-b3505cd9505e.jpeg)
認識している.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/a9aa9c39-cb3b-e4b5-da22-01af41c9b293.jpeg)

これで、Hyper-V でも Android 向けの開発が行える環境ができあがりました。USB 接続でも WiFi 接続でも、お好みの方法を選んで開発していただけます。


# 補足：Hyper-V 上への Windows 10 のインストールについて

Hyper-Vで新規仮想マシンを作成の際に「クイック作成」を選ぶと、"Windows 10 dev environment" での環境構築が行われます。

仮想マシンのインストール用にOSのライセンスを調達済みの場合はこの手順ではなく「新規］作成を行ってください。

![create-new-windows10-dev-environment-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/9d307702-5562-e562-5967-197b0d0f8c43.jpeg)

![create-new-windows10-dev-environment-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/149350/eff828e0-d6ec-8dd7-3fbb-6637778650f9.jpeg)

ちなみにこの画面ではディスクが足りない、と指摘されていますね。このスクリーンショットはすでに作成済みの仮想マシンがある状態で、さらに新規の仮想マシン作成を選択しているためにディスク容量が少々不足しています。

今時の統合開発環境を仮想マシンで全部入りでインストールすると、OS込みで60ギガバイト以上ののディスク・スペースが必要となります。実際に環境を作る場合はディスク容量を十分に確保の上でお試し頂ください。