2012-08-11

OMakeをビルドするときの問題

OMake 0.9.8.6をCygwinでビルドするとき、

  • 依存しているライブラリが正常に検出されない
  • OCaml 4.00.0でビルドすると警告が原因でビルドに失敗する

という問題があったので、解決方法を記録しておく。

依存するライブラリが検出されない問題について。OMakeでは、自身をビルドするとき、ncursesなどのライブラリの検出にCheckLibという関数を利用している。このCheckLibの実体は、lib/configure/Configure.omで定義されている、CheckCLibという関数なんだけど、ここでライブラリの指定をLDFLAGSではなく、CFLAGSでしている。

public.CheckCLib(libs, funs) =
    CFLAGS += $(addprefix -l, $(libs))

    return $(TryLinkC $"""
#ifdef __cplusplus
extern "C"
#endif
#pragma warning( disable : 4100 )
/* Override any gcc2 internal prototype to avoid an error.  */
$(add-wrapper $(nl)extern char , $'();', $(funs))
int main(int argc, char **argv) {
    /* Usage */
$(add-wrapper $(nl)    , $'();', $(funs))
    return 0;
}
""")

これによって、gccに渡される-lオプションがCFLAGSの位置にきてしまい、ライブラリを検出するときのリンクに失敗する。

なので、

--- ../omake-0.9.8.6-/lib/configure/Configure.om        2012-08-11 15:05:41.265625000 +0900
+++ lib/configure/Configure.om  2012-08-11 16:12:42.359375000 +0900
@@ -266,7 +266,8 @@
 # \end{doc}
 #
 public.CheckCLib(libs, funs) =
-    CFLAGS += $(addprefix -l, $(libs))
+    # CFLAGS += $(addprefix -l, $(libs))
+    LDFLAGS += $(addprefix -l, $(libs))

     return $(TryLinkC $"""
 #ifdef __cplusplus

のように修正すれば、正常にライブラリが検出されるようになる。

ちなみに、FAM(OMakeの-Pオプションを利用するために必要)のためにCygwinのパッケージに収録されているGaminをインストールした場合、ビルドに失敗してしまう。

- build src/main omake.opt
+ ocamlopt.opt -warn-error A -w Aekr-29z -I . -I ../libmojave -I ../util -I ../magic -I ../ast -I ../ir -I ../env -I ../exec -I ../eval -I ../shell -I ../build -I ../builtin -o omake.opt unix.cmxa ../libmojave/lm.cmxa ../util/util.cmxa ../magic/magic.cmxa ../ast/ast.cmxa ../ir/ir.cmxa ../env/env.cmxa ../exec/exec.cmxa ../eval/eval.cmxa ../shell/shell.cmxa ../build/build.cmxa ../builtin/builtin.cmxa omake_shell.cmx omake_main.cmx ../clib/clib.a -cclib -lfam
** Cannot resolve symbols for ../clib/clib.a(lm_notify.o):
 _FAMErrno
 _FamErrlist
File "caml_startup", line 1:===============================    ] 01189 / 01242
Error: Error during linking
*** omake: 1189/1242 targets are up to date
*** omake: failed (4 min 47.47 sec, 234/234 scans, 357/519 rules, 801/2398 digests)
*** omake: targets were not rebuilt because of errors:
   src/main/omake.opt

DLL特有の名前修飾が原因と思われるものの、関数のシンボルは正常に解決できているようで、詳しい原因は分からなかった。GaminのDLLをGNU ldのruntime pseudo relocations機能を使ってビルドすれば良いのかもしれないが、そちらのビルドにも行き詰まったので、今回は手を引くことにした。

次に、警告が原因でビルドに失敗する問題について。参考資料によると、OCaml 3.12で厳し目に警告を出すようになったことが原因らしい。

コンパイラに渡すフラグをOMakefileで指定しているので、

--- ../omake-0.9.8.6-/OMakefile 2012-08-11 15:05:41.484375000 +0900
+++ OMakefile   2012-08-11 17:41:35.703125000 +0900
@@ -57,7 +57,7 @@
 #
 # OCaml options
 #
-OCAMLFLAGS[] += -w Ae$(if $(OCAML_ACCEPTS_Z_WARNING), z)
+OCAMLFLAGS[] += -w Aekr-29$(if $(OCAML_ACCEPTS_Z_WARNING), z)
 if $(THREADS_ENABLED)
     OCAMLFLAGS += -thread
     export

といった感じで、特定の警告は無視することにすれば良い。

以上。以下は参考資料。

0 件のコメント: