【Nim】32bitバイナリにコンパイルする方法
背景
64bitのWindows10上で、Nimのプログラムを32bitのdllにコンパイルをしたかったんですが、意外と手間取ったのでメモを残しておきます。
ちなみに、適当に--cpu:i386とか指定するとこんなエラーがでましたw

環境
Windows 10
Nim 1.6.6
choosenim v0.8.4
手順
1 i386コンパイラをダウンロード
まず、Nimを普通に入れた段階ではmingwの64bitしかインストールしてくれていないので、mingw32をダウンロードします。
Nim公式のCompiler dependencies からmingw32.7zをダウンロードしてください。
ダウンロードした7zを、mingw64フォルダがあるディレクトリに配置して、解凍してください。
Nimをchoosenimでインストールした場合は、以下のディレクトリのはずです。
C:\Users\USER_NAME\.choosenim\toolchains\
(choosenimでない場合はわかりませんがuserディレクトリの隠しフォルダだと思われます。.nimbleとか)
2 PATHを通す
そしたらmin32/binにPATHを通してください。
3 コンパイル😎
コンパイルしましょう。
a. .exeにコンパイル
hello.nim をコンパイルしたいとすると
-
--gcc.path=に32bitコンパイラへのパスを渡す -
--cpuでi386アーキテクチャを指定する
nim c --gcc.path=PATH_TO_MINGW32\mingw32\bin --cpu=i386 -r hello.nim
b. .dllにコンパイル
toDll.nim をコンパイルしたいとすると
エントリーポイントとしてDllMainを定義している前提(参考)
-
--gcc.path=に32bitコンパイラへのパスを渡す -
--cpuでi386アーキテクチャを指定する -
--nomainを指定する -
--app=libを指定することでdllを生成することを伝える。
nim c --app=lib --nomain --gcc.path=PATH_TO_MINGW32\mingw32\bin --cpu=i386 toDll.nim
オプションを自動指定する方法
これらを毎回指定するのはめんどくさいですよね?
実はプロジェクトディレクトリにnim.cfgファイルを作って指定したいオプションを書いておくと、いちいち指定しなくてもNimが自動で参照してくれるようになります。
# nim.cfg
--app: lib # exeの場合はいらない
--nomain # exeの場合はいらない
--gcc.path: "PATH_TO_MINGW32\mingw32\bin"
--cpu: i386
この状態で以下を実行すると、32bitのtoDll.dllが生成されます。
# exeの場合は -rをつけてもよい
nim c toDll.nim
最後に
言い忘れてましたが、32bitのdllをプロセスにinjectするにはlibgccをstatic linkする必要があるらしいです。
というわけで以下のプラグマを指定してください。
{.passL: "-s -static-libgcc".}
完成品
ボイラープレート作っておいたので参考にどうぞ。
References
Discussion