C, C++を学生に教える環境をWindowsで作りたい

#きっかけ／やりたいこと
これまでは学生にVisual StudioでC言語を教えていたけど，初めてプログラミングに触れる学生にはIDEは高機能すぎる（この教育の目的はIDE使用法の習得ではない）．
コンパイルと実行さえできればいいので，そのためだけにWindows環境にコンパイラとエディタを用意したい．
cygwinとかMSYS2とかMinGWとかでコンパイラ用意しろよと言われるのは承知の上で，VirtualBoxでLinux環境を入れる（コンパイルと実行だけのために）．
可能な限り設定は教員側でやってしまって，学生にはプログラミングに集中してもらう．

Windows機でソースコードの編集をさせたい．
エディタはなんでもいいけど，ポータブル版があるエディタを使わせれば設定も持ち出せるので，自宅学習させるときに授業と同じ環境を手軽に作れる．
（エディタについてはこの記事には書かない）

もっといい方法があれば教えてください．


#環境
**配布元ホスト**（教員）

-Windows 8.1 + VirtualBox 5.2.4

**配布先ホスト**（学生）

- Windows 10 + VirtualBox 5.2.4
- Mac OSX El Capitan(10.11.6) + VirtualBox 5.1.30

**ゲスト**

- Ubuntu 16.04 LTS 日本語 Remix

#VirtualBoxでUbuntu日本語Remixのインストール
配布元でVirtuialBox内にUbuntu環境を整える．

##VirtualBoxのインストール
Oracleの[VirtualBoxの配布サイト](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp)から**Oracle VM VirtualBox Base Packages**をダウンロードしてインストールする．
次に同サイトから**Oracle VM VirtualBox Extension Pack**をダウンロードしてインストール．こちらはホスト―ゲスト間の共有フォルダを作成するのに必要．

##VirtualBoxにUbuntuのインストール
日本語化で苦しみたくないので日本語 Remixを使用する．

###ISOイメージの取得
[ubuntu Japanese Teamのサイト](https://www.ubuntulinux.jp/download/ja-remix)からUbuntu 16.04 LTS 日本語 Remix（64bit版）のISOイメージをダウンロードする．

###仮想マシンの作成
VirtualBoxを起動し，左上の「新規」ボタンを押すと「仮想マシンの作成」ダイアログが表示される．
各項目は以下の通りに設定．
**名前**：任意（今回はProgramingAとした）
**タイプ**：Linux
**バージョン**：Ubuntu (64-bit)

![virtualbox.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/2f61b103-484b-0473-0d66-83d02686825d.png)

「次へ」を押すとメモリサイズやハードディスクの設定に移るので，必要に応じて設定する．
今回はデフォルト値（メモリサイズ：1024MB，仮想ハードディスクの作成，ハードディスクのファイルタイプ：VDI，ストレージ：可変サイズ，ハードディスクサイズ：10GB）で設定した．

設定が完了すると作成した仮想マシンが一覧に作成される．
![virtualbox3.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/661f3e77-7edc-5cfe-269e-6f6c8e420a6e.png)

次にISOイメージを起動ディスクとして指定する．作成した仮想マシンを選択し，「設定」ボタンを押すと設定ダイアログが表示される．
「ストレージ > コントローラー:IDE > 空」を選択し，属性にあるディスクアイコンをクリックする．
「仮想光学ディスクファイルを選択」から上でダウンロードしたUbuntuのISOファイルを選択する．
「OK」を押せば，ここまででUbuntuインストールの準備が完了．
![virtualbox4.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/75183572-122a-ac27-4d96-89d24855ad36.png)

###Ubuntuのインストール
仮想マシンを起動する．
2つメッセージが表示されたら今後表示させないために一番右のアイコンをクリックする．
![virtualbox5.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/14367f0c-805f-a10d-e006-a5e2640aa49b.png)

インストール画面が表示されるので，Ubuntuをインストールをクリックする．
![virtualbox6.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/f34e85da-e281-28ca-67a5-952334110e79.png)

続けてUbuntuのインストールの準備では「Ubuntuのインストール中にアップデートをダウンロードする」にチェックを入れる．

次にインストールの種類では「ディスクを削除してUbuntuをインストール」を選択しインストール．ディスクに変更を書き込むか聞かれるので「続ける」をクリックする．

タイムゾーン（Tokyo）とキーボードレイアウト（日本語 > 日本語）はデフォルトのままでOK．

最後にユーザー情報を設定する．
今回はログインでこける学生が出ないように「自動的にログインする」を選択する．
![virtualbox7.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/9ab1fef3-8392-eb1f-c095-93e898f16c6f.png)

「インストールが完了しました」というダイアログが表示されたら「今すぐ再起動する」をクリックしてインストール完了．
かと思ったら「intel_rapl: no valid rapl domains found in pcackege 0」と出て固まってしまった．
そんなときはデバイスメニューの「仮想マシン > リセット」で回復するらしい．
（参考：https://theolizer.com/cpp-school1/cpp-school1-3/）

あと以下のようなダイアログが出たり，
![virtualbox8.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/25a2176b-d98c-f3cc-0ce7-4971dd5e7eee.png)

`sudo apt update` すると，以下のようなエラーでupdateできない場合．

```console
E: Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/cache/app-info -a -e /usr/bin/appstreamcli; then appstreamcli refresh > /dev/null; fi'
E: Sub-process returned an error code
```

`sudo apt upgrade` を先にやればいいっぽい（バグだそう）．そうすると悪さしているappstreamとかがupgradeされて解決するらしい．
（参考：http://fedoranize.seesaa.net/article/438073202.html）

###ロックしない設定
仮想マシンでもアイドル状態が続くと画面がオフになったり，ロックしたりする．
ロックしないよう設定したい．
「システム設定 > 画面の明るさとロック」の設定画面から「次の時間アイドル状態が続けば画面をオフにする」を「しない」に，「ロックする」を「オフ」に設定し，「サスペンドからの復帰時にパスワードを要求する」もチェックを外す．

![virtualbox19.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/afe7af62-951d-f250-f7c7-c0e3b7cacd27.png)

これで学生がパスワードを気にする必要はなくなったはず．

#ホスト(Windows)とゲスト(Ubuntu)間の共有フォルダの作成

###ホスト側のフォルダ作成
ホスト（Windows）側で共有するフォルダを作成する．
場所はどこでもいいし名前は何でもいいが，今回は「shared」という名前のフォルダをデスクトップに作る．

###ゲスト側にGuest Additionsのインストール
次にゲスト（Ubuntu）側にGuest Additionsをインストールしておく．
「デバイス > Guest Additions CD イメージの挿入...」を選ぶと，自動起動のソフトウェアについて聞かれるので実行しインストールする．
![virtualbox11.png](https://qiita-image-store.s3.amazonaws.com/0/224844/4815b736-e84c-b78d-6d45-bec01f1112ab.png)

###共有フォルダの指定
VirtualBoxの仮想マシンの設定ダイアログで「共有フォルダ」を選択し，右上の追加アイコンをクリックする．
![virtualbox9.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/c0cf544a-a7b4-83b7-c954-1dd621279e57.png)
次のようなダイアログが現れるのでフォルダのパスを指定する（プルダウン > その他からフォルダ選択できる）．また，自動マウントにチェックを入れる．

![virtualbox10.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/0a67dbca-733d-bc66-8634-2dd1265811b3.png)

ここまで設定すれば/media/sf_sharedというフォルダにマウントされる．
しかし，このままだとアクセス許可がないので

```bash:terminal
sudo gpasswd -a student vboxsf
```
を実行してstudentを`vboxsf`グループに追加する．

###共有の確認
ゲスト側からファイルを作成してみる．

```bash:terminal
touch media/sf_shared/test.cpp
```
と打って，ホスト側のsharedフォルダにtest.cppができていればOK．

#ターミナル（端末）のエンコーディングの設定
WindowsとUbuntuでやりとりするうえで日本語のエンコーディングが問題になる．
デフォルトではWindowsはShiftJIS，UbuntuではUTF-8のためどちらかに揃えて文字化け対策しなければいけない．
（MacとUbuntuはデフォルトのエンコーディングUTF-8なので問題にならない．）
Windows側でプログラムを書いて保存するので，Ubuntu側のターミナルのエンコーディングをShiftJISに変更しておこう．
ターミナルのメニューから「編集 > プロファイルの設定」を選択し，互換性のタブのエンコーディングをShiftJISに変更する．
（もちろん，Windows側でUTF-8で保存すればターミナルのエンコーディングはUTF-8のままでよい．例えば，エディタとしてSublimeTextを採用し，UTF-8しか扱わないならば，ターミナルはUTF-8のままにする．）

![virtualbox17.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/bcc28b45-00ad-be7e-9784-64d1015a5795.png)


#C, C++の環境の確認
今回入れたUbuntuはgccがすでに入っているようなので，インストールなどは特に何もしなくていい．
あえてするなら，

```bash:terminal
sudo apt upgrade
```
でバージョンをあげておくことくらい？

ということで，Hello Worldの確認だけしておく．
ホスト側でsharedフォルダに以下をhello.cppで保存する．

```c++:hello.cpp
#include <iostream>

using namespace std;

int main(){
    cout<<"こんにちは、世界！"<<endl;
    return 0;
}
```
ゲスト側で共有フォルダに移動し（`cd /media/sf_shared/`），

```bash:terminal
g++ hello.cpp
./a.out
こんにちは、世界！
```
がうまくいけばOK．日本語も文字化けしないはず．

#（蛇足設定）学生がプログラミング以外のところでつまずかないように
学生には以下のことだけをさせたい．

1. プログラムを書く
1. それ（test.cpp）を共有フォルダsharedに保存
1. VirtualBoxの起動
1. コンパイル　g++ test.cpp
1. 実行　./a.out

それを実現するための蛇足設定をしておく．

###ターミナルの自動起動
ターミナルの起動で学生がこけるのを避けるため，起動時のアプリケーションとしてターミナルを登録しておく．
「自動起動するアプリケーションの設定」というアプリケーションを立ち上げ，追加をクリックする．
![virtualbox12.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/d1670bd9-b255-afdf-af53-a55fb2fab2b0.png)
プログラムの追加ダイアログのコマンド欄に「gnome-terminal」と入力して追加をクリックする．名前と説明はなくてもOK．
![virtualbox13.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/3cbab5bb-ef03-1a7c-ceb8-e3b5c09035ad.png)

###ログイン時のフォルダ移動を省略
共有フォルダsf_sharedで作業させることになるので，そのフォルダに移動する．
学生がフォルダの移動でこけるのを避けるため，ターミナル起動時にフォルダを移動しておけばよい．
.bashrcに`cd /media/sf_shared`を追記する．
（usermodを使ってホームディレクトリを変更しておいてもよいが，あまり行儀がよくないのでそれは避けた）

###ターミナルの最大化
ターミナルしか使わせないのだから，ターミナルは最初から最大化しておくほうが混乱しないかもしれない．
（最初からUbuntuをCUIで入れればいいじゃんと思われるかもしれないけど，日本語が×なので避けた）

ターミナル起動時のウインドウサイズを設定するためにdevilspieのGUIツールgdevilspieを使う．

```bash:terminal
sudo apt install gdevilspie
```
でインストールできる（devilspieも同時に入る）.

gdevilspieを起動し，「Start devilspie daemon automatically at login」にはチェックを入れておく（後でもいい）．追加をクリックする．
![virtualbox14.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/0200599d-154f-a2c9-d6cb-9c78b091421e.png)

「create a new rule named:」は適当に名前をつける．
「Matching」のタブで「window_name」にチェックを入れ，「contain」の項目に「student@」でも入力する（windowを一意に指定できさえすればなんでもよい）．
![virtualbox15.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/eb01bed1-6806-8fe8-462e-07713669c1c3.png)

「Actions」のタブに切り替え，「maximize」にチェックを入れて保存する．

![virtualbox16.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/1b74e1c2-f351-9432-e32f-088c70e51398.png)

#仮想イメージのエクスポート

すべての設定が終わったらVirtualBoxで仮想マシンのイメージをエクスポートする．
（エクスポートする前に.bash_historyはクリアしておくとよいかも．`history -c`でクリアできる．）

VirtualBoxのメニューから「ファイル > 仮想アプライアンスのエクスポート」をクリックする．
エクスポートする仮想マシンを選択し，次へで先に進みエクスポートする．
![virtualbox18.PNG](https://qiita-image-store.s3.amazonaws.com/0/224844/6b80bd8c-379b-a4da-aff3-c05c372781eb.png)
エクスポートが完了したらProgramingA.ovaというファイルができているはず．

#学生用Windows機の設定
先ほどエクスポートしたProgramingA.ovaをUSBメモリかダウンロードか何かで学生が使用するWindows機に持ってきておく．

学生が使用するWindows機にVirtualBoxとExtension Packをインストールする．
インストールの方法は上の[VirtualBoxのインストール](#virtualbox%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)参照．

インストールが完了したらVirtualBoxを起動し，「ファイル > 仮想アプライアンスのインポート」をクリックする．
ProgramingA.ovaのファイルを選択し，「次へ」で表示される設定は変更せずにインポートする．

インポートしている間にどこでもいいので（例えばデスクトップに）「shared」という名前のフォルダを作成しておく．

インポートが完了したら，インポートした仮想マシンを選択し，設定をクリックする．
共有フォルダの項目に「shared」という名前の共有フォルダがあれば，そのフォルダのパスを先ほど作成したsharedフォルダに変更する．

ここまで設定して起動すれば，sharedフォルダのプログラムファイルをコンパイル，実行する環境の出来上がり．

#反省
うまくいったと思ったけど，一部のテスト機では32bitしか仮想マシンを作成，インポートできないらしい．Ubuntu 64bitで作ったけど32bitで作ればよかった．．．
と思ったけどUbuntuの日本語Remixは64bitしか配布してない．悩ましい．
（参考：[Virtual Boxで仮想マシン環境を作るときに引っ掛かりがちな？罠。](http://kitaeng.hateblo.jp/entry/2015/10/07/220650)）
（参考：[VirtualBox：仮想マシンの作成で64bit OSを選択可能にする方法](http://did2memo.net/2015/07/10/virtualbox-64-bit-os/)）