やっと NYAGOS がビルドできた

ここのところずうっと忙しくて放ったらかしだったのだが，ようやく [NYAGOS] を Win64 環境でビルドできるようになった。前回は [Golang](https://golang.org/) でお手軽にできると勘違いして[見事に玉砕](http://qiita.com/spiegel-im-spiegel/items/48a588234072a4977d9c)したが，今回はもう「分かってる」から大丈夫。

最初に言っておくと，この記事は結構長いので，「御託はいいから結果だけ教えてくれ！」って方は以下のページを参考にするとよい。

- [64bit版NYAGOS ビルド手順 - Qiita](http://qiita.com/nocd5/items/a612d69513cdb9a5dda7)

## NYAGOS の要件

[前回](http://qiita.com/spiegel-im-spiegel/items/48a588234072a4977d9c) は 必須だった [nyole] だが，最近のバージョン（4.0.8_0 以降）では（少なくとも起動時には） なくても大丈夫なようだ。これで [NYAGOS] をビルドするための最低限の要件は

- [Go 言語環境](https://golang.org/) ; パッケージ取得時に内部で [git] コマンドを呼び出すため， [git] も導入する必要あり
- [Lua 言語](http://www.lua.org/)

のみとなった。

Go 言語環境の導入については以前書いた拙文を参考にどうぞ。

- [はじめての Go 言語 (on Windows)](http://qiita.com/spiegel-im-spiegel/items/dca0df389df1470bdbfa)

[NYAGOS] 本体以外に以下のパッケージが必要なので， `GOPATH` の設定を忘れないように。

- [mattn/go-runewidth](https://github.com/mattn/go-runewidth)
- [shiena/ansicolor](https://github.com/shiena/ansicolor)
- [atotto/clipboard](https://github.com/atotto/clipboard)

`GOPATH` の設定と外部パッケージの導入については，同じく以前書いた拙文を参考にどうぞ。

- [はじめての Go 言語 (on Windows) その3](http://qiita.com/spiegel-im-spiegel/items/a52a47942fd3946bb583)

[Lua] については [Lua Binaries](http://lua-users.org/wiki/LuaBinaries) にビルド済みのものが置いてある。 Win64 用なら `lua-5.3.0_Win64_bin.zip` を取ってくればいいだろう。この中で [NYAGOS] の動作に必要なのは `lua53.dll` のみである。

## NYAGOS のビルド

では早速ビルドを始めよう。ここでは Go 言語環境は既に導入済みであるとする。

### make.cmd の使い方

[NYAGOS] は GitHub で管理されている。まずは `git clone` コマンドでソースコードを取得する。ビルドに関係があるのは `make.cmd` ファイルである。

`make.cmd` の中身を眺めてみたが，ビルドする際は，やはり素直に `make.cmd` を実行するのがよさそうである。

`make.cmd get` で上述の外部パッケージを取得する。

`make.cmd build` で実際にビルドを開始する。注意しないといけないのは外部コマンドとして `attrib.exe`, `cscript.exe`, `windres.exe` を呼び出す点である。

`attrib.exe` と `cscript.exe` は `C:\Windows\System32` にあるが， `PATH` が通ってない場合は指定する必要がある。

`windres.exe` は開発用のツールなので Windows の基本装備には入っていない。もし `windres.exe` があるなら `PATH` を通しておくとよいだろう。 `make.cmd` では `windres.exe` が見つからなかった場合は `windres.exe` を使用する処理をスキップする。（スキップしてもビルド自体には影響がない）

### ビルド後のファイルコピー

`make.cmd build` でビルドが成功すると `nyagos.exe` ファイルが生成されているはずである。このファイルを含めた以下のファイルを任意の（`PATH` の通った）フォルダにコピーする。

- `nyagos.exe`
- `nyagos.lua`
- `nyagos.d\*.lua`
- `catalog.d\*.lua`

また `lua53.dll` も同じフォルダにコピーする（これがないと `nyagos.exe` が起動に失敗する）。

`nyagos.exe` の起動確認。

```shell
C:\path\to\nyagos>nyagos.exe -h
Usage of nyagos.exe:
  -c="": like `cmd /c`
  -e="": run inline-lua-code
  -f="": run lua script
  -k="": like `cmd /k`

C:\path\to\nyagos>nyagos.exe
Nihongo Yet Another GOing Shell v2015/07/04 Powered by Lua 5.3
Copyright (c) 2014,2015 HAYAMA_Kaoru and NYAOS.ORG
C:/path/to/nyagos>ls nyagos.*
nyagos.exe* nyagos.lua*

nyagos.d:
aliasandset.lua* brace.lua*       open.lua*        swapstdfunc.lua*
aliases.lua*     cdlnk.lua*       su.lua*          trash.lua*
backquote.lua*   comspec.lua*     suffix.lua*
```

## nyole のビルド

最初に述べたように， [nyole] は必須の要件ではなくなったが，こちらも一応ビルドできるようになったのでメモしておく。

### nyole の要件

[nyole] のビルド要件は以下のとおり。

- gcc ビルド環境
- [Lua] 開発環境

[nyole] のソースコードは `git clone` コマンドで取得しておくこと。

[nyole] の `Makefile` を見る限り [TDM-GCC] を前提にしているようだが，今回は敢えて [MSYS2] を使う（将来的にはちゃんとクロスコンパイルできる環境を作らないとだけど，まずは [MSYS2] で代替）。 [MSYS2] で gcc ビルド環境を構築する際は，以下の拙文を参考にどうぞ。

- [MSYS2 による gcc 開発環境の構築 - Qiita](http://qiita.com/spiegel-im-spiegel/items/ba4e8d2418bdfe0c8049)

実は [MSYS2] であれば [Lua] 開発環境をパッケージとして持ってるので簡単に導入できる。

```shell
$ pacman -S mingw-w64-x86_64-lua
依存関係を解決しています...
衝突するパッケージがないか確認しています...

パッケージ (2) winpty-git-1.1.1.148.47a69d0-2
               mingw-w64-x86_64-lua-5.3.1-1

合計ダウンロード容量:  0.48 MiB
合計インストール容量:  2.67 MiB

:: インストールを行いますか？ [Y/n] y
:: パッケージを取得します ...
 mingw-w64-x86_64-lua-5.3.1-1-any        254.1 KiB  1008K/s 00:00 [###########] 100%
 winpty-git-1.1.1.148.47a69d0-2-x86_64   233.8 KiB  1030K/s 00:00 [###########] 100%
(2/2) キーリングのキーを確認                                      [###########] 100%
(2/2) パッケージの整合性をチェック                                [###########] 100%
(2/2) パッケージファイルのロード                                  [###########] 100%
(2/2) ファイルの衝突をチェック                                    [###########] 100%
(2/2) 空き容量を確認                                              [###########] 100%
(1/2) インストール winpty-git                                     [###########] 100%
(2/2) インストール mingw-w64-x86_64-lua                           [###########] 100%

$ lua -v
Lua 5.3.1  Copyright (C) 1994-2015 Lua.org, PUC-Rio
```

パッケージにはビルド用のヘッダファイルやライブラリも含んでいるので，アプリケーションに簡単に組み込める。

### nyole のビルド

先ほど述べたように [nyole] の `Makefile` は [TDM-GCC] を前提に組まれているので [MSYS2] 用に書きなおしてみた。（利用条件はオリジナルの [NYAGOS] のライセンスに合わせます）

```makefile:Makefile.msys2
CC       = g++
LIBS     = -lole32 -loleaut32 -luuid -llua
CPPFLAGS =
LDFLAGS  = -s -static

RM = rm -f

TARGET  = nyole.dll
OBJECTS = nyole.o lua32com.o win32com.o nyole.syso
DEF     = nyole.def

$(TARGET): $(OBJECTS)
	g++ -shared -o $@ $(OBJECTS) $(DEF) $(LIBS) $(LDFLAGS)

nyole.o : nyole.cpp
lua32com.o : lua32com.cpp
win32com.o : win32com.cpp win32com.h
nyole.syso : nyole.rc
	windres.exe --output-format=coff -o nyole.syso nyole.rc

.cpp.o :
	$(CC) -c $(CPPFLAGS) $< -o $@

clean :
	$(RM) $(OBJECTS) $(TARGET)

status:
	lua.exe showver.lua $(TARGET)

package :
	zip -9 nyole-`lua.exe showver.lua nyole.dll`-`gcc -dumpmachine`.zip $(TARGET) readme.md *.lua
```

注意するポイントとしては，リンカオプションに `-static` を必ず付けること。これがないと [MSYS2] 配下の多くの DLL ファイルをごっそり移動するハメになる。

（余談だが， [MSYS2] では [Lua] パッケージに `lua` と `lua.exe` の2つのコマンドが用意されているが，挙動が異なるので注意。ていうか， `lua` コマンドは何故か内部で winpty を呼び出すという奇行をやらかす。たとえば

```shell
$ echo `lua.exe showver.lua nyole.dll`
0.0.0.5

$ echo `lua showver.lua nyole.dll`
output is not a tty
```

てな感じになる。なんでこんな仕様なのか，意味不明）

では早速ビルドしてみよう。

```shell
$ mingw32-make.exe -f Makefile.msys2
g++ -c  nyole.cpp -o nyole.o
g++ -c  lua32com.cpp -o lua32com.o
g++ -c  win32com.cpp -o win32com.o
windres.exe --output-format=coff -o nyole.syso nyole.rc
g++ -shared -o nyole.dll nyole.o lua32com.o win32com.o nyole.syso nyole.def -lole32 -loleaut32 -luuid -llua -s -static

$ mingw32-make.exe -f Makefile.msys2 status
lua.exe showver.lua nyole.dll
0.0.0.5

$ mingw32-make.exe -f Makefile.msys2 package
zip -9 nyole-`lua.exe showver.lua nyole.dll`-`gcc -dumpmachine`.zip nyole.dll readme.md *.lua
  adding: nyole.dll (deflated 61%)
  adding: readme.md (deflated 48%)
  adding: showver.lua (deflated 20%)
  adding: t_filesystemobject.lua (deflated 46%)
  adding: t_folders.lua (deflated 32%)
  adding: t_specialfolders.lua (deflated 45%)
  adding: t_utf8.lua (deflated 42%)
  adding: t_version.lua (deflated 25%)

$ unzip -l nyole-0.0.0.5-x86_64-w64-mingw32.zip
Archive:  nyole-0.0.0.5-x86_64-w64-mingw32.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
   400896  2015-07-05 11:30   nyole.dll
      847  2015-07-04 20:16   readme.md
      173  2015-07-04 21:17   showver.lua
      441  2015-07-04 20:16   t_filesystemobject.lua
      227  2015-07-04 20:16   t_folders.lua
      253  2015-07-04 20:16   t_specialfolders.lua
      430  2015-07-04 20:16   t_utf8.lua
       65  2015-07-04 20:16   t_version.lua
---------                     -------
   403332                     8 files
```

パッケージ化のくだりは普通はいらないと思うけど， [MSYS2] の基本装備には `zip`/`unzip` は入ってないので，パッケージ化を実行するなら `pacman -S` コマンドで導入しておこう。

### nyole の導入

`nyole.dll` ができたら先ほどの `nyagos.exe` のあるフォルダにコピーすればいいのだが，ひとつ問題がある。それは [Lua Binaries](http://lua-users.org/wiki/LuaBinaries) にある `lua53.dll` では今回ビルドした `nyole.dll` が動かないことである。しょうがないので [MSYS2] にある `lua53.dll` をコピーして使っている。ままならないねぇ。まぁ `nyole.dll` は必須要件ではないので，今後の課題としよう。

動作確認としては trash コマンドあたりを実行してみるとよい。

```shell
C:>nyagos.exe
Nihongo Yet Another GOing Shell v2015/07/04 Powered by Lua 5.3
Copyright (c) 2014,2015 HAYAMA_Kaoru and NYAOS.ORG
C:>ls ゴミ.txt
ゴミ.txt
C:>trash ゴミ.txt
C:>ls ゴミ.txt
C:>
```
これで Windows のゴミ箱に `ゴミ.txt` が入ってたら OK。

## 継続調査

今回作ったバイナリはここにおいている： [http://www.baldanders.info/spiegel/archive/nyagos/](http://www.baldanders.info/spiegel/archive/nyagos/)

今後の継続調査項目としては

1. [ConEmu] との連携
1. [MSYS2] で [nyole] をビルドすると `lua53.dll` とリンクできない場合がある問題について調査。あと（今回はスルーしたけど） [nyole] を `-Wall` オプション付きでコンパイルするとちょこちょこワーニングが出るのだが，いいのだろうか。
1. せっかく Go なんだからもっとスマートに [NYAGOS] をビルドしたい。たとえば [constabulary/gb](https://github.com/constabulary/gb) とか使えないだろうか

といったところか。まぁおいおい。

## 追記

最近のバージョンでは Win64 用のバイナリも提供しているためビルドする必要すらありません。感謝！

- [ようやく ConEmu と NYAGOS を導入した — しっぽのさきっちょ | text.Baldanders.info](http://text.baldanders.info/remark/2015/conemu-and-nyagos/)

[NYAGOS]: http://www.nyaos.org/index.cgi?p=NYAGOS "NYAOS.ORG - NYAGOS"
[Lua]: http://www.lua.org/ "The Programming Language Lua"
[nyole]: https://github.com/zetamatta/nyole "zetamatta/nyole"
[git]: https://git-scm.com/ "Git"
[MSYS2]: https://github.com/msys2 "msys2"
[TDM-GCC]: http://tdm-gcc.tdragon.net/ "TDM-GCC : News"
[ConEmu]: http://conemu.github.io/ "ConEmu - Handy Windows Terminal"