LoginSignup
1
0

More than 3 years have passed since last update.

msys2でocamlのビルドをしようとしてautotoolsの前に完全敗北した話

Last updated at Posted at 2020-05-06

はじめに

WindowsにArch Linuxにも採用されているpacmanを用いてパッケージ管理を行っているmingw環境としてmsys2というのがある。

このパッケージはやはりArch Linuxと同じくmakepkgでビルドするわけだが、そのためのPKGBUILDなどのファイル群が
https://github.com/msys2/MINGW-packages
で管理されている。

過去の私は何を思ったのかこのなかのocamlのパッケージを更新しようと試みていたようだ。しかし中途半端に終わり投げ出している。

今OCamlは4.10.0がリリースされているらしい。一方で依然としてmsys2のocamlパッケージはメンテ放棄されていて、4.04.0のままで時が止まっている。

しまいにはもうOCaml関係のパッケージ取り除こうぜっていう提案が投げつけられている
https://github.com/msys2/MINGW-packages/issues/6040

なんとかアップデートできないん?

OCamlのビルド方法

そもそもOCamlをWindows環境でビルドするにはCygwinかCygwin環境のMingw、あるいはmsvcが必要らしい。msys2のことは考えられていない。

OCamlはautotoolsを使ってビルドすることになっている。autotoolsはLinuxで使うぶんには優れたツールだろうが、Windows環境で動かすにはあまりにも辛い。Cygwinとも大きく違うmsys2で動かすには何かしらのパッチを当てなければ動かないことは確実である。

そこで
https://github.com/msys2/MINGW-packages/tree/2cfdf054df2c826d7c61237ee5ac2453b0f3964d/mingw-w64-ocaml
にあるパッチをみつつ、手動でパッチを当てていくことにした。

/config/Makefile.mingw32がないんですが?

環境ごとにMakefileを用意することそのものをやめたらしく、autotoolsを使うように切り替わっている。そのため機械的にパッチを当てることはできず、configure.acの中で該当箇所を探して置き換えていくことになる

Unicode対応のためにパッチに変更が必要なもの

どうもWindows環境でもUnicodeをまともに扱うために、wchar_t系APIを叩いてそれをUTF-8に変換するような扱い方をするようになったらしい。

パッチを当てたもの

まあとにかくパッチを当ててみた。

が、だめ

$make VERBOSE=1
make coldstart
make[1]: ディレクトリ '/c/Users/yumetodo/Downloads/ocaml-4.10.0.tar/ocaml-4.10.0' に入ります
make -C runtime  all
make[2]: ディレクトリ '/c/Users/yumetodo/Downloads/ocaml-4.10.0.tar/ocaml-4.10.0/runtime' に入ります
echo "-O -mms-bitfields -Wno-unused -Wall -fno-tree-vrp -g -DCAML_NAME_SPACE -DUNICODE -D_UNICODE -DWINDOWS_UNICODE=1 -I"/lib/flexdll""
-O -mms-bitfields -Wno-unused -Wall -fno-tree-vrp -g -DCAML_NAME_SPACE -DUNICODE -D_UNICODE -DWINDOWS_UNICODE=1 -I/lib/flexdll
gcc -c -O -mms-bitfields -Wno-unused -Wall -fno-tree-vrp -g -DCAML_NAME_SPACE -DUNICODE -D_UNICODE -DWINDOWS_UNICODE=1 -I"/lib/flexdll" -o win32_b.o win32.c
win32.c:52:10: fatal error: flexdll.h: No such file or directory
   52 | #include <flexdll.h>
      |          ^~~~~~~~~~~
compilation terminated.
make[2]: *** [Makefile:343: win32_b.o] エラー 1
make[2]: ディレクトリ '/c/Users/yumetodo/Downloads/ocaml-4.10.0.tar/ocaml-4.10.0/runtime' から出ます
make[1]: *** [Makefile:347: coldstart] エラー 2
make[1]: ディレクトリ '/c/Users/yumetodo/Downloads/ocaml-4.10.0.tar/ocaml-4.10.0' から出ます
make: *** [Makefile:476: world.opt] エラー 2

どういうわけか-I"/lib/flexdll"になってしまうがために、flexdllを見つけられない。

これには心当たりがある。実は次のようなパッチを当てている。

configure.ac
diff --git a/configure.ac b/configure.ac
index e3e28fb..9c6f51d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -627,7 +627,7 @@ AS_CASE([$CC,$host],
     common_cppflags="$common_cppflags -U_WIN32"
     AS_IF([$with_sharedlibs],
       [flexlink="flexlink -chain $flavor -merge-manifest -stack 16777216"
-      flexdir=`$flexlink -where | tr -d '\015'`
+      flexdir="$(prefix)/lib/flexdll"
       AS_IF([test -z "$flexdir"],
         [AC_MSG_WARN(
           [flexlink not found: native shared libraries won't be available.]
@@ -639,7 +639,7 @@ AS_CASE([$CC,$host],
       )]
     )
     AS_IF([! $with_sharedlibs],
-      [mkexe="$mkexe -Wl,--stack,16777216"
+      [mkexe="$mkexe -L$(shell cygpath -m /mingw32/i686-w64-mingw32/lib) -Wl,--stack,16777216"
       oc_ldflags="-Wl,--stack,16777216"]
     )
     ostype="Cygwin"],
@@ -649,7 +649,6 @@ AS_CASE([$CC,$host],
         [i686-*-*], [flexdll_chain="mingw"],
         [x86_64-*-*], [flexdll_chain="mingw64"])
       flexlink="flexlink -chain $flexdll_chain -merge-manifest -stack 16777216"
-      flexdir=`$flexlink -where | tr -d '\015'`
       AS_IF([test -z "$flexdir"], [flexdir='$(ROOTDIR)/flexdll'])
       iflexdir="-I\"$flexdir\""
       mkexedebugflag="-link -g"])

つまり何らかの理由でprefixという変数が展開されていないのではないか、そう考えた。

Debug printを仕込めない・・・だと!?

こうなると誰でも思いつくのがとりあえずprintfデバッグしよう、ということだ。怪しそうなところに片っ端から

AC_MSG_NOTICE(["line: 652, prefix=$(prefix)"])

のようなものを仕込んでいった。しかし結果はいかのような散々なものだった。

︙
./configure: line 12566: prefix: command not found
./configure: line 12567: prefix: command not found
configure: "line: 652, prefix="
︙
./configure: line 16762: prefix: command not found
./configure: line 16764: prefix: command not found
configure: "line: 1763; then :
  prefix="
./configure: line 16832: prefix: command not found
./configure: line 16833: prefix: command not found
configure: "line: 1806, prefix="
︙

; then :ってどっから来たし。command not foundってどういうこと?

まあまて、落ち着くんだ。そもそもこれは./configureを吐き出しているんだからそっちを直接書き換えて・・・

diff --git a/configure b/configure
index 28ac47d..4f8603f 100644
--- a/configure
+++ b/configure
@@ -16758,13 +16758,10 @@ if test x"$libdir" = x'${exec_prefix}/lib'; then :
 fi

 if test x"$mandir" = x'${datarootdir}/man'; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: \"line: 1763
-elif prefix=$(prefix)\"" >&5
-$as_echo "$as_me: \"line: 1763; then :
-  prefix=$(prefix)\"" >&6;}
 else
   mandir='${prefix}/man'
 fi
+echo 'line: 1763 prefix=$(prefix)'

 case $host in #(
   *-*-mingw32|*-pc-windows) :

結果は

line: 1763 prefix=$(prefix)

あっ

https://mastodon.cardina1.red/@lo48576/104116608117787838

@yumetodo そういえば configure (という名のシェルスクリプト) が吐く Makefile 内で効果を発揮すべき変数であれば、 configure 内ではエスケープされた状態になってたりするわけですね……つらそう

もうautotoolsなんか投げ捨ててCMake書いたほうが速いまであるきがしてきたけど、どう考えてもそんなモチベはないので、この記事を書いて終わることにします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0