Windows上で ocamlopt + OMake + LablGL

ただのリンク集+実際の設定みたいな感じのエントリ。先人方に感謝。

一通り設定を終えた後で特に見直しもせず記憶に頼って書き綴っているのでどこか抜けがある可能性が高いです。了解の上ご覧ください。


Windows用のOCamlはインストール済みであるものとします。

パス通し

今回はVC++ 2008をインストールしたときに入る「Visual Studio 2008 コマンドプロンプト」のようなもののOCaml版を作ってみた。ここは自分がそうしたかっただけだしパスも環境依存なので適宜読み飛ばすなり読みかえるなり。普通にシステムのプロパティから環境変数を編集しても同じことのはず。

  • env.bat
@call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
@set PATH=E:\Online-Softs\Development\FlexDLL;C:\Program Files\Objective Caml\bin;E:\Documents\Development\Libraries\GLUT-3.7.6;%PATH%
@set LIB=E:\Documents\Development\Libraries\GLUT-3.7.6;%LIB%

1行目でVisual Studio 2008 コマンドプロンプトそのものを呼び出しVC++環境変数を設定、2,3行目で追加の環境変数を設定。

このenv.batのショートカットを作成し、「リンク先」を

%comspec% /k (env.batの場所)

に変更。

これでショートカットからコマンドプロンプトを開くと環境変数の設定された環境になります。

ocamloptを動かす

前回のエントリでもリンクさせていただいたこちらを参考に。

説明終了。ひどい

OMakeをインストール

インストーラをこちらからDLして普通にインストールすれば大丈夫です。パスも通されるようです。

次にいわゆるMakefileを作らなければなりません。

を参考にさせていただきました。

現時点の自分のOMakefileはこちら。普通のGNU Makeもロクに使えないので綺麗な書きかたなのかどうかは分かりませんが、とりあえず動きます。"omake --install"で作られるOMakefileからの変更はなるべく小さくする方針です。

########################################################################
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this file, to deal in the File without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the File, and to permit persons to whom the
# File is furnished to do so, subject to the following condition:
#
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR
# THE USE OR OTHER DEALINGS IN THE FILE.

########################################################################
# The standard OMakefile.
# You will usually need to modify this file for your project.

########################################################################
# Phony targets are scoped, so you probably want to declare them first.
#

# .PHONY: all install clean
.PHONY: clean run

########################################################################
# Subdirectories.
# You may want to include some subdirectories in this project.
# If so, define the subdirectory targets and uncomment this section.
#

# .SUBDIRS:

########################################################################
# OCaml configuration.
# Delete this section if you are not building OCaml files.
#

################################################
# Configuration.  You may want to modify any of these configuration
# variables.
#

#
# This project requires ocamlfind (default - false).
#
# USE_OCAMLFIND = true
#
# OCAMLPACKS[] =
#    pack1
#    pack2
#
# if $(not $(OCAMLFIND_EXISTS))
#    eprintln(This project requires ocamlfind, but is was not found.)
#    eprintln(You need to install ocamlfind and run "omake --configure".)
#    exit 1

#
# Include path
#
OCAMLINCLUDES += +lablgl

#
# Compile native or byte code? 
#
# The default values are defined as follows:
#
NATIVE_ENABLED = $(OCAMLOPT_EXISTS)
BYTE_ENABLED = $(not $(OCAMLOPT_EXISTS))

#
# Various options
#
# OCAMLFLAGS    +=
# OCAMLCFLAGS   +=
# OCAMLOPTFLAGS +=
# OCAML_LINK_FLAGS +=
# OCAML_BYTE_LINK_FLAGS +=
# OCAML_NATIVE_LINK_FLAGS +=

################################################
# Generated files
#
# Workaround for the fact that ocamldep does not pay attention to .mll
# and .mly files.
#
# OCamlGeneratedFiles(parser.ml lexer.ml)

################################################
# Build an OCaml library
#

# FILES[] =
#    file1
#    file2
#
# LIB = main
#
# .DEFAULT: $(OCamlLibrary $(LIB), $(FILES))

################################################
# Build an OCaml program
#

# FILES[] =
#    core
FILES[] = $(removesuffix $(glob *.ml))
#
PROGRAM = mshiki
# OCAML_LIBS +=
# OCAML_CLIBS +=
OCAML_OTHER_LIBS += lablgl lablglut
# OCAML_LIB_FLAGS +=
#
.DEFAULT: $(OCamlProgram $(PROGRAM), $(FILES))

clean:
	rm -f \
	    $(filter-proper-targets $(glob $(addsuffix .*, $(FILES)))) \
	    $(PROGRAM).run $(PROGRAM).opt $(PROGRAM).exe

run:
	cp $(PROGRAM).exe ..
	../$(PROGRAM).exe

ファイル一覧をいちいち更新するのが面倒なので FILES[] = $(removesuffix $(glob *.ml)) にしました。


適当なhelloworldプログラムでも作ってビルドが動作するか確認してみてください。

LablGLをインストール


先にGLUTをDL。

どこかに解凍しておきます。自分の場合は E:\Documents\Development\Libraries\GLUT-3.7.6 に置きました。上のバッチファイルでも登場している場所です。

ネイティブの実行ファイルのみから利用する場合は実行ファイルと同じフォルダにglut32.dllを置いておけば問題ないと思いますが、対話環境から使う場合はocaml.exeと同じフォルダ(デフォルトならC:\Program Files\Objective Caml\bin)またはどこかパスの通った場所においておく必要があります。バイトコードを実行する場合は試していないので分かりません。

次にここからWindows版LablGLをDL。

解凍して、OCamlをインストールしたフォルダ(デフォルトならC:\Program Files\Objective Caml)へ上書き。
上書きといってもフォルダ名が被っているだけでファイルは追加になるはずです。

そのあとビルドが必要です。OCamlをインストールしたフォルダ内の lib\lablgl (デフォルトならC:\Program Files\Objective Caml\lib\lablgl)へ移動し、

ocaml build.ml

を実行…と書いてあるページが多く見つかりますが、VistaでProgram Files以下に置いているとアクセス権の問題でこれは失敗します。

Error: Assembler error, input left in file (テンポラリフォルダ内のファイル名)

どこかアクセス権の問題のない場所へ lib\lablgl を丸ごとコピーしそこで ocaml build.ml してください。インクルードやライブラリのパスの設定は特に必要なかった…はず…。

そのあとで Program Files 以下へ上書きコピー。

おそらくこのエントリの説明には間違いがあるので、ご覧の方がそこをなんとかしてうまくインストールを終えていたとすると、OCamlをインストールしたフォルダ内の examples\LablGlut 以下のプログラムを対話環境で起動できるはずです。

C:\Program Files\Objective Caml\examples\LablGlut>lablglut simple.ml

3つの力を合わせてネイティブビルド

やっと準備が終わったので、LablGLを利用するプログラムをOMakeとocamloptでネイティブの実行ファイルにしてやります。

OMakeなしの場合

ocamlopt -I +lablgl lablgl.cmxa lablglut.cmxa (プログラムのファイル名 ...)

でビルドが通る、かも知れませんが、glut32.libが無いぞと言われるかもしれません。

ここで最初に掲載したenv.batを見てみると

@set LIB=E:\Documents\Development\Libraries\GLUT-3.7.6;%LIB%

という風に環境変数LIBへGLUTを解凍した場所を追加しています。これがないと glut32.lib を見つけることが出来ません。

OMakeを使いたい場合は "-I +lablgl" "lablgl.cmxa lablglut.cmxa" をどう書くのかが問題になりますが、上のほうにあるOMakefileを見てみると

#
# Include path
#
OCAMLINCLUDES += +lablgl
OCAML_OTHER_LIBS += lablgl lablglut

ということですね。

このOMakefileを使う場合は、同じフォルダに先ほどのexamplesフォルダ以下にあるmorph3d.mlなんかを持ってきて

>ls
OMakefile      OMakeroot      morph3d.ml
>omake
*** omake: reading OMakefiles
*** omake: finished reading OMakefiles (0.02 sec)
*** omake: done (1.51 sec, 0/1 scans, 3/5 rules, 5/84 digests)
>ls
OMakefile      OMakeroot      morph3d.cmi    morph3d.ml     mshiki.exe
OMakefile.omc  OMakeroot.omc  morph3d.cmx    morph3d.obj    mshiki.opt

という風に出来るかと思います。

 

重ね重ねになりますがかなりてきとーに書いているので、説明を飛ばしてしまったところや分かりにくいところなどあると思いますが、その場合はコメントなんかで指摘していただければ加筆します。