Help us understand the problem. What is going on with this article?

NimではじめてのGUI

More than 1 year has passed since last update.

Nim言語の利用の幅を広げるため、GUIアプリケーションを作成してみます。

なぜNim

ネーミング、HPの雰囲気、言語記述などが全体的に好き。
Go、Rustなどもちょこちょこ触りましたが、このへんの比較記事なども含めてNimいいなーと思っています。

http://wolfbash.hateblo.jp/entry/2017/10/02/163017

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を解凍すると、次のような中身になっています。

image.png

.aファイルはリンカが使用するバイナリなので、これをMinGW(gcc)に渡せば、使用できそうですね。

NimからIUPを呼び出せるようにする

Nimのコード内でIUPのライブラリを呼び出す必要があります。
それには、公式のIUPラッパーがありますので、それを使用します。

https://github.com/nim-lang/iup

READMEに従って、次のコマンドでインストールします。

$ nimble install iup

これで環境の準備が完了しました。いよいよプログラムを作ります。

IUPのプログラム

同じくIUPラッパーのGithubにサンプルがありますので、それを使ってみます。

https://github.com/nim-lang/iup/blob/master/examples/menu.nim

menu.nim
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フォルダに放り込みます。
次のような構成になります。

image.png

では、ビルドをしてみましょう。

$ 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ができると思いますので、実行してみましょう。

image.png

:*:・。,☆゚'・:*:・。,ヽ(・NIM・)人(・IUP・)ノ ,。・:*:・゚'☆,。・:*:

やりましたね!

今後やりたいこと

  • nim.cfgを活用してコマンドを短縮すること
  • IUPライブラリをプロジェクトフォルダではなくMinGW側に移動すること(ビルド環境によって異なるので・・・)
  • その他のプラットフォームでのビルド

Nimいかんせん実際のビルド周りの情報が全然見つからなくて辛いので、皆さんもぜひ情報共有してください!

そもそものCビルドについても勉強しないといけないですが。。。orz

kojisaiki
@saikou9901 Software Engineer/Everything is a stream. github: https://github.com/kojisaiki
http://irony9901.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away