10

OCaml Batteries Includedのコンセプトと、私が見つけたほとんどのチュートリアルの進め方に少し不満を感じ、混乱しています。GODIのような「生産性」ツールを使用したり、ocamlcの呼び出しをocamlfindバッテリー/ ocamlcに置き換える前これは、現時点では私にはあまりにも魔法のようです)、OCamlバッテリーに含まれるライブラリのコアセットを簡単に使用できることを望んでいました。他のライブラリと同じように。そのために、私はgit(ヘッドハッシュ:9f94ecb)から最新のソースをダウンロードし、 makeallを実行ました。./_build/src/に3つの.cmaライブラリと102の.cmiがあることに気づきました。同じディレクトリ内のファイル。そのため、そのディレクトリを指す-Iスイッチを使用してコンパイルし、そこにある3つの.cmaライブラリのいずれかとリンクすることで、バッテリを「インストール」したり、プラットフォームツールを使用したりしなくても十分であると想定しました。それをテストするために、私はどこかで見つけた次の簡単なプログラムの実行可能ファイルを作成することに着手しました。

(* file euler001.ml *)
open BatEnum      
open BatPervasives
let main () = 
 (1--999)
|> BatEnum.filter (fun i -> i mod 3 = 0 || i mod 5 == 0)
|> BatEnum.reduce (+) 
|> BatInt.print stdout

let _ = main ()

私はそれをコンパイルすることができました:

ocamlc -c -I ../batteries-included/_build/src/ euler001.ml

しかし、私がリンクしようとしたとき:

ocamlc -o euler001 unix.cma nums.cma ../batteries-included/_build/src/batteries.cma euler001.cmo

私が得た:

ファイル"_none_"、1行目、文字0-1:
エラー:../batteries-included/_build/src/batteries.cma(BatBigarray)のリンク中にエラーが発生しました:
外部関数`caml_ba_reshape'は使用できません

コマンドラインで追加したnums.cmaunix.cmaは、リンカーが未定義のグローバルBig_intおよび(追加されたときの)Unixへの参照が欠落していることについて不平を言ったためです。しかし、これら2つのモジュールがリンカーの呼び出しで追加された後、最後のメッセージ(欠落している外部関数'caml_ba_reshape')を受け取りました。これは、ブロックされていることを証明しました。だから私は尋ねたいと思います:

  1. この特定のケースではどのように進めますか?
  2. 一般的な場合(つまり、リンカーが外部関数の欠落について不平を言う場合)はどのように進めますか?
  3. この方法で含まれているバッテリーを使用することは実行可能ですか?プラットフォームツールに頼る前に、問題が発生した場合に、標準のOCamlコンパイラとリンカーで基盤となるアーティファクト(cmaおよびcmi / mliファイル)を使用できることを保証したいと思います。
4

1 に答える 1

14

caml_ba_reshape名前から推測できるように、それは明らかではないことに同意しますが、Bigarrayモジュールのプリミティブです。bigarray.cmaコンパイルコマンドを追加する必要があります。その前に、それbatteries.cmaに依存します。

ocamlfindこれらの依存関係を抽象化するために正確に使用される、を使用することをお勧めするのには理由があります。私はあなたが使うことになっているとは思いませんがocamlfind batteries/ocamlc、むしろocamlfind ocamlc -package batteries。そのようなサポートなしでコンパイラを使用することを主張する場合は、実際に手動でコンパイルする必要があります-私はあなたの欲求不満を理解していますが、それは十分に洗練されたOCamlライブラリに興味をそそるものであり、それはあなた自身からのみ来ることも理解してください-課せられた制約。

一般的な場合(つまり、リンカーが外部関数の欠落について不平を言う場合)はどのように進めますか

プリミティブがどこから来たのかを知るか推測する必要があります。ocamlfind依存関係を通知するために使用される、ライ​​ブラリによって提供されるMETAファイルを確認すると役立つ場合があります。仮定を確認したい場合は、ツールを使用して、ocamlobjinfoaが提供するプリミティブを知ることができます。.cma(または、ocamlfindを使用して、正しいコンパイルコマンドを吐き出します。以下を参照してください。)

この方法で含まれているバッテリーを使用することは実行可能ですか?

あなたが主張するならば、「手で」コンパイルすることは合理的です。ライブラリをインストールせずにソースリポジトリでのみ作業することはできません。インストール後に行うことを続けるのは簡単です-I ...。選択したインストールパスに置き換えるだけです。

プラットフォームツールに頼る前に、問題が発生した場合に、標準のOCamlコンパイラとリンカーで基盤となるアーティファクト(cmaおよびcmi / mliファイル)を使用できることを保証したいと思います。

ocamlfindプラットフォームツールではありません(唯一の)。これは、サードパーティのocamlライブラリを使用する方法です。これは、ocamlを使用するプラットフォームの標準である必要があります。それがINRIAの配布に付属していないことは歴史的な詳細です。

ocamlfindベアコンパイラの呼び出しを表示するように依頼できます。

% ocamlfind ocamlc -linkpkg -package batteries t.ml -o test -verbose
Effective set of compiler predicates:
pkg_unix,pkg_num.core,pkg_num,pkg_bigarray,pkg_str,pkg_batteries,autolink,byte
+ ocamlc.opt -o test -verbose -I /usr/local/lib/ocaml/3.12.1/batteries /usr/lib/ocaml/unix.cma /usr/lib/ocaml/nums.cma /usr/lib/ocaml/bigarray.cma /usr/lib/ocaml/str.cma /usr/local/lib/ocaml/3.12.1/batteries/batteries.cma t.ml

私はあなたに石を投げたくない。OCamlツールの風景は、ソースディストリビューションによって提供されるものの最小限の要約に加えて、非常にまばらであり、一貫したエントリポイントを欠いています。時間が経つにつれて、私はそれらのツールに慣れてきて、それらを使用するのは非常に自然ですが、私たちが下げようとしなければならないエントリのコストがあることを理解しています。

PS:バッテリーのドキュメントを改善する方法についてのアドバイスは大歓迎です。ドキュメントに物事を追加したり修正したりするためのパッチはさらに優れています。バッテリー-devel@lists.forge.ocamlcore.orgは行く場所です。

于 2012-05-19T19:37:50.307 に答える