Nim言語の利用の幅を広げるため、GUIアプリケーションを作成してみます。
なぜNim
ネーミング、HPの雰囲気、言語記述などが全体的に好き。
Go、Rustなどもちょこちょこ触りましたが、このへんの比較記事なども含めてNimいいなーと思っています。
Nimを実行するまで
Windows
:10
nim
:0.18.0
MinGW
:6.3.0
ここまでは通常のNimの開発環境です。こちらのページに従って簡単に構成できます。
https://nim-lang.org/install_windows.html
GUIを作成する環境
使用するライブラリ:IUP
NimでGUIを作成するのには、IUPというGUIライブラリを使用します。
このIUPはNimに限ったGUIライブラリではなく、もともとLuaなど、Cを中心としたビルド環境でマルチプラットフォームでネイティブGUIを開発するためのライブラリのようです。
一度Nimをビルドするとわかりますが、Cにトランスパイル(と言っていいかな)されてからビルドされるので、IUPが使用できるというわけですね。
※もっと詳しい人、教えてください。。。
IUPをとってくる
次の場所にIUPのライブラリがあります。
https://sourceforge.net/projects/iup/files/
この時点での最新バージョン、3.24
を選択します。
Windows64bit + MinGWに該当するIUPのライブラリをダウンロードします。
https://sourceforge.net/projects/iup/files/3.24/Windows%20Libraries/Static/iup-3.24_Win64_mingw4_lib.zip/download
ダウンロードしたZIPを解凍すると、次のような中身になっています。
.a
ファイルはリンカが使用するバイナリなので、これをMinGW(gcc)に渡せば、使用できそうですね。
NimからIUPを呼び出せるようにする
Nimのコード内でIUPのライブラリを呼び出す必要があります。
それには、公式のIUPラッパーがありますので、それを使用します。
READMEに従って、次のコマンドでインストールします。
$ nimble install iup
これで環境の準備が完了しました。いよいよプログラムを作ります。
IUPのプログラム
同じくIUPラッパーのGithubにサンプルがありますので、それを使ってみます。
import iup
discard iup.open(nil, nil)
var fileItemLoad = iup.item("Load", "")
var fileItemSave = iup.item("Save", "")
var fileItemClose = iup.item("Close", "")
var fileMenu = iup.menu(fileItemLoad, fileItemSave, fileItemClose, nil)
var mainMenu = iup.menu(iup.subMenu("File", fileMenu), nil)
discard iup.setHandle("mainMenu", mainMenu)
var dlg = iup.dialog(nil)
iup.setAttribute(dlg, "TITLE", "iupTabs")
iup.setAttribute(dlg, "SIZE", "200x100")
iup.setAttribute(dlg, "MENU", "mainMenu")
discard iup.showXY(dlg, IUP_CENTER, IUP_CENTER)
discard iup.mainLoop()
iup.close()
IUPのライブラリを今回はプロジェクトフォルダのiupフォルダに放り込みます。
次のような構成になります。
では、ビルドをしてみましょう。
$ nim c -d:release --dynlibOverride:iup -L:iup/libiup.a -L:iup/libiupcd.a -L:iup/libiupim.a -L:-lgdi32 -L:-luser32 -L:-lcomdlg32 -L:-lcomctl32 -L:-lole32 -L:-luuid menu.nim
これはNimからCにトランスパイルされたあと、次のようなコンパイルが内部で行われています。
gcc.exe -o C:\○○○\menu.exe C:\○○○\nimcache\menu.o C:\○○○\nimcache\stdlib_system.o C:\○○○\nimcache\stdlib_iup.o iup/libiup.a iup/libiupcd.a iup/libiupim.a -lgdi32 -luser32 -lcomdlg32 -lcomctl32 -lole32 -luuid
32とついてるのは全部Win32のライブラリですね。からっきしですが・・・
gdi32
: 画面描画
user32
: ユーザ周り?
comdlg32
: コモンダイアログ
comctl32
: コモンコントロール(ボタンとか?)
ole32
: リンカ?( https://ja.wikipedia.org/wiki/Object_Linking_and_Embedding )
uuid
: UUID(何に使ってるんでしょ?)
※詳しい人、教えてください。。。
とりあえずこれでexeができると思いますので、実行してみましょう。
:*:・。,☆゚'・:*:・。,ヽ(・NIM・)人(・IUP・)ノ ,。・:*:・゚'☆,。・:*:
やりましたね!
今後やりたいこと
-
nim.cfg
を活用してコマンドを短縮すること - IUPライブラリをプロジェクトフォルダではなくMinGW側に移動すること(ビルド環境によって異なるので・・・)
- その他のプラットフォームでのビルド
Nimいかんせん実際のビルド周りの情報が全然見つからなくて辛いので、皆さんもぜひ情報共有してください!
そもそものCビルドについても勉強しないといけないですが。。。orz