本章では開発に不可欠なコンパイラ・ライブラリ・デバッガなどの整備を行う.環境整備はビギナーにとって最も大きな難関である.
はじめに,OS間共通の操作(ブラウザで行う)であるリポジトリのForkについて説明し,その後各OSごとに環境構築手順の説明を行う.その後,OS間で共通の話として,gitや起動オプションについての説明を行う.
本書ではバージョン管理システムとしてgitを用いる.本家のソースコードリポジトリは https://github.com/aburch/simutrans にある.これにForkという操作をして自分のリポジトリにコピーしてから使う.なお,gitやGitHubについてはgit・GitHubについてを参照されたい.
まずは,GitHubのアカウントを作り,それでログインする.ログインした状態で本家リポジトリにアクセスする.下の図のように画面右上に「Fork」というボタンが出現するので,それをクリックする.すると,自分のアカウントにSimutransリポジトリが作成される.例えばGitHubのユーザー名がhimeshi
であれば,himeshi/simutrans
といった具合になる.
このセクションはWindowsを対象とした説明である.macユーザーはmacでの環境構築,linuxユーザーはlinuxでの環境構築を参照されたい.
本書ではシェル環境としてmsys2を用いる.msys2はコマンドプロントのようなものである.以降はこのmsys2を使ってコンパイルやデバッグを行う.まずは, http://www.msys2.org/ からmsys2をダウンロードし,インストールする.ダウンロードボタンはサイトの上部の配置されている.Windowsが64bit版であれば, x86_64とついたものをダウンロードしてウィザードに従ってインストールすればよい.
インストールが終われば自動的にmsys2が起動するが,これは一旦閉じる.スタートメニューからMSYS2の32bit版を起動する.これはSimutransのソースが公式には32bitにしか対応していないことによる.
黒いコマンドライン画面が登場するので,以下のコマンドを打ちこむ.
1
yes | pacman -Syu
すると,出力の最後の方にこのようなメッセージが表示される.
1
2
警告: terminate MSYS2 without returning to shell and check for updates again
警告: for example close your terminal window instead of calling exit
ウィンドウの閉じるボタンでMSYS2を閉じて,再度MSYS2を起動する.(繰り返すが32bitを起動することに注意.)
再起動したら以下のコマンドを打ち,パッケージを更新する.
1
yes | pacman -Su
つづいて,以下のコマンドをMSYS2で実行し,諸々のツールをインストールする.
1
pacman -S git make mingw-w64-i686-toolchain mingw-w64-i686-zlib mingw-w64-i686-bzip2 mingw-w64-i686-libpng mingw-w64-i686-zstd mingw-w64-i686-freetype
インストールするパッケージの選択を求められるので,何も入力せずEnterを押す.つまり,全てのパッケージを導入する.
続いて,simutransの開発リポジトリをダウンロードする.先ほど本家のリポジトリをForkして「自分の」リポジトリを作成した.この自分に所有権があるリポジトリをダウンロードする.
デスクトップ上にソースコードのフォルダを作ると想定する.他のディレクトリに作る場合は適宜cdコマンドで指定するディレクトリを置き換える.
1
2
3
cd /c/Users/UserName/Desktop
git clone https://github.com/himeshi/simutrans.git
cd simutrans
1行目のUserName
は読者のアカウントのユーザーネームに置き換える.URL中のhimeshi
は読者のGitHubユーザーネームに置き換える.これで,デスクトップ上に「simutrans」という名でソースコードフォルダが生成されたはずである.
コンパイルはmakeコマンドで行う.その前に,いくらかの設定が必要である.まずは,その設定ファイルを用意する.
適当なエディタ(TeraPadやSakuraエディタ等.Windowsのメモ帳は改行コードや文字コードの問題があるので使ってはならない.)を用いて 「config.default
」 という名前のテキストファイルを作成する.それを,simutransソースコードのトップディレクトリに配置する.このファイルの作成は手打ちで行ってもよいし,simutransソースコードにあるconfig.templateを利用してもよい.config.defaultは以下のようにする.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BACKEND = gdi
COLOUR_DEPTH = 16
OSTYPE = mingw
DEBUG = 1
STATIC = 1
WITH_REVISION = 8550
WIN32_CONSOLE = 1
MULTI_THREAD = 1
USE_FREETYPE = 1
USE_UPNP = 0
USE_ZSTD = 1
MAKEOBJ_PROGDIR = $(shell pwd)
NETTOOL_PROGDIR = $(shell pwd)
PROGDIR = $(shell pwd)
WITH_REVISION
は本家におけるrevision番号である.GitHubからクローンしている関係上,適切な番号を自分でつける必要がある.(適当な番号でもローカル環境ではさしあたり問題ない.)各行の意味はconfig.templateを参照することで確認できる.
config.defaultをsimutransソースコードのトップディレクトリに置いく.そして,MSYS2上でmake
コマンドを実行し,コンパイルする.MSYS2のディレクトリがsimutransのソースディレクトリになっているか確認してほしい.(pwdコマンドで確認できる.)
1
make -j4
-j4というのは並列数を指定するオプションである.お使いのマシンの論理コア数を指定すると良い.(例えばデスクトップ向けi5ならたいてい論理4コアなので-j4となる.)
コンパイル出力の最後はこのようになる.
1
2
3
4
===> HOSTCXX music/w32_midi.cc
===> HOSTCXX sound/win32_sound.cc
===> RES simres.rc
===> LD sim.exe
「LD
」から始まる行が成功していればコンパイル成功である.このとき,simutransソースコードのトップディレクトリにsim.exeが生成されている.これを適当なSimutrans環境ディレクトリ(pakなどが入ってるところ)にコピーし,実行すればめでたく起動する.
めでたくexeファイルを生成できた.このexeファイルをダブルクリックでそのまま実行しても動作はする.しかし,この実行方法ではこの先の開発で必要になる種々のデバッグ出力を得ることができない.そこで,開発を行うときは必ず「gdb」というデバッガ上でsimutransを動かすことになる.
生成したexeファイルをsimutrans実行ディレクトリにコピーの上,cdコマンドでそこに移動する.例として,simutrans実行ディレクトリをEドライブのsim_testフォルダにしているとすると,gdbでsimutransを走らせる手順は以下のようになる.
1
2
3
4
5
6
7
8
cd /e/sim_test
gdb sim.exe
GNU gdb (GDB) 8.1.1
(中略)
Reading symbols from sim.exe...done.
(gdb) r
Starting program: E:\sim_test\sim.exe
(下に続く)
「gdb sim.exe」でgdbがsim.exeを準備する.準備ができたら,「r
」(run の意味)で起動する.こうすることで,バックトレースなどの貴重なデバッグ情報を得ることができる.
結局のところ,開発のワークフローは以下のようになる.
これをイチイチやるのはあまりに面倒であるから,せめて2〜4は自動化しよう. そのためには,下のようなファイルを作成すればよい.
1
2
3
4
5
6
7
8
9
10
echo "r:just run with gdb"
echo "c:compile and run"
read C
if [ "$C" == "c" ]
then
cd /c/Users/Himeshi/Desktop/simutrans
make -j4
cp sim.exe /e/sim_test/
fi
gdb /e/sim_test/sim.exe
6行目のパスは環境に合わせて変更してもらいたい.まず,「chmod u+x sim.sh
」 で実行権限を付与する.その後,「./sim.sh
」でスクリプトを実行する.すると,コンパイルをするかしないか問われるので,する場合はc
を入力,しない場合はr
を入力すれば,gdbの立ち上げまで自動で行われる.
本セクションではubuntuを動作環境として説明する.
先の節で説明したように,予めGitHubで本家のリポジトリをForkしておく.次に,config.defaultを適当な場所に用意する.このファイルは手打ちしてもよいし,simutransソースコードに含まれているconfig.templateを利用してもよい.ここで作成したconfig.defaultはあとでスクリプトで適切な位置にコピーする.WITH_REVISION
の値はコンパイルするソースのリビジョン番号に置き換える.
1
2
3
4
5
6
7
8
9
10
11
12
13
BACKEND = sdl2
COLOUR_DEPTH = 16
OSTYPE = linux
DEBUG = 1
OPTIMISE = 1
WITH_REVISION = 8550
MULTI_THREAD = 1
USE_FREETYPE = 1
USE_UPNP = 0
USE_ZSTD = 1
MAKEOBJ_PROGDIR = $(shell pwd)
NETTOOL_PROGDIR = $(shell pwd)
PROGDIR = $(shell pwd)
次に,先ほど作成したconfig.defaultと同じディレクトリにシェルスクリプトファイルを作る.このシェルスクリプトで必要なライブラリをインストールし,ソースコードをクローンし,コンパイルを行う.ファイル名は適当にsetup.shとでもしておく.
1
2
3
4
5
6
7
8
9
10
11
sudo apt install make gcc gdb git zlib1g-dev libbz2-dev libpng-dev libsdl2-dev libminiupnpc-dev libfreetype6
wget https://github.com/facebook/zstd/archive/v1.4.4.zip
unzip v1.4.4.zip
cd zstd-1.4.4
make -j4
sudo make install
cd ~/
git clone https://github.com/himeshi/simutrans.git
cd ~/simutrans
cp $(cd $(dirname $0);pwd)/config.default ~/simutrans
make -j4
例によって4行目の「himeshi
」の部分は各自のgithubアカウントに置き換えてほしい.
あとは,このシェルスクリプトを実行
1
2
chmod u+x setup.sh
./setup.sh
すると,ソースコードのトップディレクトリに「sim」という名前の実行ファイルが生成されているはずである.
なお,zstandard(zipやbzip2等のようなファイル圧縮のライブラリ)をソースからコンパイルしているのは,記事執筆2020年4月現在apt
で提供されているzstandardのバージョンが古いためである.リビジョン番号r9028現在,コンパイルにはzstandard 1.4.4以降が必要である.
先の節で説明したように,予めGitHubで本家のリポジトリをForkしておく.
まず,Homebrewをインストールする.ターミナルを開き,以下のコマンドを入力する.このコマンドは手打ちするのではなく,Homebrewのwebページからコピペすると良い.
1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Homebrewのインストールが終わったら,ライブラリをインストールする.引き続き,ターミナル画面で以下のコマンドを入力する.
1
brew install sdl2 libpng miniupnpc freetype zstd
続いて,config.defaultを作成する.適当なエディタを開き,以下のテキストの通りにする.このファイルの作成は手打ちで行ってもよいし,simutransソースコードにあるconfig.templateを利用してもよい.「config.default」という名前でこのファイルをデスクトップに保存する.WITH_REVISION
の値はコンパイルするソースのリビジョン番号に置き換える.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BACKEND = sdl2
COLOUR_DEPTH = 16
OSTYPE = mac
DEBUG = 1
OPTIMISE = 1
WITH_REVISION = 8550
MULTI_THREAD = 1
AV_FOUNDATION = 1
USE_FREETYPE = 1
USE_UPNP = 0
USE_ZSTD = 1
MAKEOBJ_PROGDIR = $(shell pwd)
NETTOOL_PROGDIR = $(shell pwd)
PROGDIR = $(shell pwd)
最後に,simutransソースコードをクローンし,コンパイルを行う.ターミナル画面で以下のコマンドを実行する.URLの「himeshi
」の部分は,読者のGitHubアカウント名に置き換える.
1
2
3
4
5
cd ~/
git clone https://github.com/himeshi/simutrans.git
cp ~/Desktop/config.default ~/simutrans
cd ~/simutrans
make -j4
これで,Macのホームディレクトリ直下にsimutransというフォルダが生成されている.さらに,その中に「sim」というファイル名で実行ファイルが生成されたはずである.実際に動かすときは,simをsimutrans実行ディレクトリ(pakファイルなどが入っている場所)にコピーした上で,ターミナルで
1
2
cd <simが配置された場所>
./sim
と入力すれば起動する.simファイルをダブルクリックすることでも起動することができる.
C++プログラミングでは,ファイルを実行するだけではデバッグに必要な情報が得られない.実際の開発は,lldb というデバッガ上でSimutransを走らせて行う.このようにすると,ただプログラムを実行するだけでは得られない重要なデバッグ情報を得られる.開発の流れは下のとおりである.
コードを編集してから走らせるまでに4ステップもあるので,手順2->5は一つの操作で済ませられるように自動化しよう.自動化にはスクリプトを書いてしまうのが便利である.コードの場所を~/simutrans
(~/
は「ホームディレクトリ直下の」という意味である),テスト環境の場所を~/sim_test
とすれば,make→コピー→lldbで起動の流れは下のようなスクリプトになるだろう.
1
2
3
4
5
6
7
8
9
10
echo "r:just run with gdb"
echo "c:compile and run"
read C
if [ "$C" == "c" ]
then
cd ~/simutrans
make -j4
cp sim ~/sim_test
fi
lldb ~/sim_test/sim
このスクリプトを適当な名前(例えばsim_exec.sh
)をつけて保存する.ファイルを作成したらchmod +x sim_exec.sh
で実行権限を付与する.スクリプトを実際に走らせるときは./sim_exec.sh
のようにする.
デバッガであるlldbが起動すると下のように「target create "sim"
」と表示される.ここで,「r
」(run の意味)と入力すればsimutransが起動する.
1
2
3
(lldb) target create "sim"
Current executable set to 'sim' (x86_64).
(lldb) r
このセクションでは,環境構築におけるOS間共通のトピックを取り上げる.
simutransは数多くの外部ライブラリ等に依存しているため、一発でコンパイルを通すことは容易ではない。適切にsim.exeが生成されていなければコンパイルは失敗している。コンパイルに失敗したときは、以下の順に解決を試みる。
1
Makefile:29: *** Unkown OSTYPE "", must be one of "amiga beos freebsd haiku linux mingw mac openbsd". Stop.
というエラーは、OSTYPEがUnknownですと書いてあるので、config.defaultでOSを指定し忘れたことによるエラーだとわかる。
エラーを目の前にすると絶望感に襲われがちだが、ぜひ諦めずに問題解決に取り組んでほしい。
ソースディレクトリの中を見ると,Makefileという名のファイルがある.MSYS2で実行されたmakeコマンドはMakefileを読んでコンパイルを行う.
ところで,SimutransはWindows,mac,Linux,さらにはBeOSもと様々な環境でコンパイルできるようになっている.Makefileでこれらの変数を定義するのは大変なので,Makefileがconfig.defaultをインポートして,環境変数として使用するのである.これにより,複雑なMakefileを編集することなく,config.defaultを編集するだけで様々な条件下でのコンパイルが可能になるのである.
Simutransは巨大なコードベースであり,不特定多数の人がコードを編集する.このような状況下では,複数人が同時にファイルを編集してその結果が衝突したり,一度行った変更をもとに戻す必要があったり,誰がどんな変更をしたか記録しておく必要があったりといったことが発生する.これらへの解決策がバージョン管理システムである.SimutransではSubversion(通称svn)というバージョン管理システムを採用している.
しかし,バージョン管理システムにおける世間の主流はgitである.特に,外部からプロジェクトに貢献しようとする者にとっては,バージョン管理システムのgitとそのクラウドサービスであるGitHubが圧倒的に便利である.このような状況であるから,simutransではGitHub上にsvnリポジトリのミラーを提供している.我々はそのミラーを本家リポジトリとして使うのである.
gitやGitHubについて詳しく学びたい場合は,『サルでもわかるGit入門』がオススメである.このサイトは,コミットやブランチなどといった重要な概念をわかりやすく説明している.Gitのチュートリアルはコンソールを使って行うのが望ましい.
gitにまつわる種々の操作をコマンドライン上で行うのは初学者にはややハードルが高い.そこで,gitのGUIクライアントであるGitHub Desktopを紹介する.https://desktop.github.com/ からダウンロードしてインストールしてほしい.GitHubアカウントでサインインする.「File」→「Add Local Repository」で,環境構築時にダウンロードしたsimutransソースコードの場所を選択すれば,GitHub Desktopでコードの管理を行えるようになる.
プログラムの開発では,適切なテキストエディタを使用することで生産性が大きく向上する.優秀なエディタは書いている段階でコードのミスを見つけたり,わかりきっている構文を自動で補完してくれたりするのである.Windowsのメモ帳やmacのテキストエディットでコードを書くのは著しく効率が悪い.
お好みのエディタが特にない場合は,Atom の使用をおすすめする.Atomはhttps://atom.io/からダウンロードできる.
Atomは「パッケージ」をインストールすることで様々な機能を搭載できるエディタである.メニューの File -> Settings を選択すると,Settings画面の左側に +install というボタンがあるので,そこから必要なパッケージを検索し,インストールできる.C++のスムーズな開発のために,以下のパッケージをインストールしよう.
simutransには種々の起動オプションが用意されている.用意されている起動オプションは
1
./sim.exe -help
で確認することができる.(Windows環境以外ではexeはつかない.)
よくある開発シチュエーションで,テスト環境には複数のpakがインストールされており,「pak128」を「addonを含めて」読み込み,「test.sve」をロードするというケースがあるだろう.この時,次のようなオプションをつけて起動すればpakの選択やセーブデータの読み込みを全自動で行うことができる.
1
./sim.exe -objects pak128 -addons -load test.sve
起動オプションを毎回入力するのは手間であるから,起動スクリプトに追記すると楽である.デバッガには予め起動オプションを渡す機能があり,gdbで次のようにしてデバッガを起動すれば,「run」の「r
」をデバッガ内で入力するだけで起動オプション付きで起動することができる.
1
gdb --args sim.exe -objects pak128 -addons -load test.sve
lldbの場合は次のようになる.
1
lldb -- sim -objects pak128 -addons -load test.sve