是否实现了 ocamlfind 包谓词?
Are ocamlfind package predicates implemented?
我有一个名为 sundialsml 的包,我想在其中加载一个略有不同的 .cm(x)a 文件,具体取决于是否加载了名为 no_sens 的子包。令人鼓舞的是,findlib 1.6.2 reference manual 描述了一个 "package predicate" 特征:
[...] there are package predicates for every package that is finally
selected. [They] have the form "pkg_" plus the name of the package
(fully qualified).
所以我写了这个 META 文件,其中 archive
分支在子包的包谓词上:
version = "2.6.2"
description = "OCaml interface to Sundials"
requires = "bigarray"
archive(byte) = "sundials.cma"
archive(byte,pkg_sundialsml.no_sens) = "sundials_no_sens.cma"
archive(native) = "sundials.cmxa"
archive(native,pkg_sundialsml.no_sens) = "sundials_no_sens.cmxa"
package "no_sens" (
version = "2.6.2"
description = "Sundials/ML without sensitivity analysis (CVODE, IDA, KINSOL)"
requires = "sundialsml"
)
但是 findlib 会加载 sundials.cma 而不管子包 no_sens 是否加载,例如:
# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
#require "package";; to load a package
#list;; to list the available packages
#camlp4o;; to load camlp4 (standard syntax)
#camlp4r;; to load camlp4 (revised syntax)
#predicates "p,q,...";; to set these predicates
Topfind.reset();; to force that packages will be reloaded
#thread;; to enable threads
- : unit = ()
# #require "sundialsml.no_sens";;
/home/jun/.opam/4.01.0/lib/ocaml/unix.cma: loaded
/home/jun/.opam/4.01.0/lib/ocaml/bigarray.cma: loaded
/home/jun/.opam/4.01.0/lib/sundialsml: added to search path
/home/jun/.opam/4.01.0/lib/sundialsml/sundials.cma: loaded
如果我尝试在顶级包上分支,也会发生同样的情况,比如 ao
。事实上,据我所知,从未定义 pkg_foo
形式的谓词(当然,除非我们说 #predicates "pkg_foo";;
)。
我是否错误地使用了包谓词?或者他们没有真正实施?如果是这样,有没有其他方法可以根据 presence/absence 子包 select 不同的档案?
请注意这里的重点是计算 用户select编辑的子包集的存档。所以 "why don't you use #predicates" 不是我正在寻找的解决方案。
看起来 pkg_
谓词根本没有为 #require
指令实现。当然,我可能是错的,因为我只是通过 greping 代码和实验来推断这一点。事实上,它只是在前端实现,所以如果有人使用库接口,它也是不可用的(所以它不会开箱即用 ocamlbuild
)。此外,pkg_
谓词仅为选定的软件包设置,而不是为已安装的软件包设置。选中的位置意味着该包位于依赖项集中。
这是一个例子。我们使用以下 META
:
定义包 ttt
archive(byte,pkg_ttt.foo) = "foo.cma"
archive(byte,pkg_ttt.bar) = "bar.cma"
package "foo" (
requires = "ttt"
)
package "bar" (
requires = "ttt"
)
现在我们可以验证它是否有效:
$ ocamlfind c -only-show -linkpkg -package "ttt.bar" main.ml
ocamlc.opt -I opam/lib/ttt opam/lib/ttt/bar.cma main.ml
注意:我使用 opam
而不是我的 ocaml 安装的真实路径来缩短输出以提高可读性。
$ ocamlfind c -only-show -linkpkg -package "ttt.foo" main.ml
ocamlc.opt -I opam/lib/ttt opam/lib/ttt/foo.cma main.ml
因此,当我们使用前端时,一切正常。但是如果我们从顶层尝试:
# #require "ttt.foo";;
opam/lib/ttt: added to search path
然后什么都没有加载。
我们也可以尝试使用ocamlbuild
:
$ ocamlbuild -classic-display -package ttt.foo main.byte
opam/bin/ocamldep.opt -modules main.ml > main.ml.depends
opam/bin/ocamlc.opt -c -I opam/lib/ttt -o main.cmo main.ml
opam/bin/ocamlc.opt -I opam/lib/ttt main.cmo -o main.byte
所以没有任何链接,它不起作用。但是,如果您将使用 -use-ocamlfind
选项,它将起作用,因为此选项规定 ocamlbuild
使用 ocamlfind
前置。
$ ocamlbuild -use-ocamlfind -classic-display -package ttt.foo main.byte
ocamlfind ocamldep -package ttt.foo -modules main.ml > main.ml.depends
ocamlfind ocamlc -c -package ttt.foo -o main.cmo main.ml
ocamlfind ocamlc -linkpkg -package ttt.foo main.cmo -o main.byte
所以,总而言之,这个想法很好,理论上可行,但最好不要使用它,因为实现还不完整。
我有一个名为 sundialsml 的包,我想在其中加载一个略有不同的 .cm(x)a 文件,具体取决于是否加载了名为 no_sens 的子包。令人鼓舞的是,findlib 1.6.2 reference manual 描述了一个 "package predicate" 特征:
[...] there are package predicates for every package that is finally selected. [They] have the form "pkg_" plus the name of the package (fully qualified).
所以我写了这个 META 文件,其中 archive
分支在子包的包谓词上:
version = "2.6.2"
description = "OCaml interface to Sundials"
requires = "bigarray"
archive(byte) = "sundials.cma"
archive(byte,pkg_sundialsml.no_sens) = "sundials_no_sens.cma"
archive(native) = "sundials.cmxa"
archive(native,pkg_sundialsml.no_sens) = "sundials_no_sens.cmxa"
package "no_sens" (
version = "2.6.2"
description = "Sundials/ML without sensitivity analysis (CVODE, IDA, KINSOL)"
requires = "sundialsml"
)
但是 findlib 会加载 sundials.cma 而不管子包 no_sens 是否加载,例如:
# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
#require "package";; to load a package
#list;; to list the available packages
#camlp4o;; to load camlp4 (standard syntax)
#camlp4r;; to load camlp4 (revised syntax)
#predicates "p,q,...";; to set these predicates
Topfind.reset();; to force that packages will be reloaded
#thread;; to enable threads
- : unit = ()
# #require "sundialsml.no_sens";;
/home/jun/.opam/4.01.0/lib/ocaml/unix.cma: loaded
/home/jun/.opam/4.01.0/lib/ocaml/bigarray.cma: loaded
/home/jun/.opam/4.01.0/lib/sundialsml: added to search path
/home/jun/.opam/4.01.0/lib/sundialsml/sundials.cma: loaded
如果我尝试在顶级包上分支,也会发生同样的情况,比如 ao
。事实上,据我所知,从未定义 pkg_foo
形式的谓词(当然,除非我们说 #predicates "pkg_foo";;
)。
我是否错误地使用了包谓词?或者他们没有真正实施?如果是这样,有没有其他方法可以根据 presence/absence 子包 select 不同的档案?
请注意这里的重点是计算 用户select编辑的子包集的存档。所以 "why don't you use #predicates" 不是我正在寻找的解决方案。
看起来 pkg_
谓词根本没有为 #require
指令实现。当然,我可能是错的,因为我只是通过 greping 代码和实验来推断这一点。事实上,它只是在前端实现,所以如果有人使用库接口,它也是不可用的(所以它不会开箱即用 ocamlbuild
)。此外,pkg_
谓词仅为选定的软件包设置,而不是为已安装的软件包设置。选中的位置意味着该包位于依赖项集中。
这是一个例子。我们使用以下 META
:
ttt
archive(byte,pkg_ttt.foo) = "foo.cma"
archive(byte,pkg_ttt.bar) = "bar.cma"
package "foo" (
requires = "ttt"
)
package "bar" (
requires = "ttt"
)
现在我们可以验证它是否有效:
$ ocamlfind c -only-show -linkpkg -package "ttt.bar" main.ml
ocamlc.opt -I opam/lib/ttt opam/lib/ttt/bar.cma main.ml
注意:我使用 opam
而不是我的 ocaml 安装的真实路径来缩短输出以提高可读性。
$ ocamlfind c -only-show -linkpkg -package "ttt.foo" main.ml
ocamlc.opt -I opam/lib/ttt opam/lib/ttt/foo.cma main.ml
因此,当我们使用前端时,一切正常。但是如果我们从顶层尝试:
# #require "ttt.foo";;
opam/lib/ttt: added to search path
然后什么都没有加载。
我们也可以尝试使用ocamlbuild
:
$ ocamlbuild -classic-display -package ttt.foo main.byte
opam/bin/ocamldep.opt -modules main.ml > main.ml.depends
opam/bin/ocamlc.opt -c -I opam/lib/ttt -o main.cmo main.ml
opam/bin/ocamlc.opt -I opam/lib/ttt main.cmo -o main.byte
所以没有任何链接,它不起作用。但是,如果您将使用 -use-ocamlfind
选项,它将起作用,因为此选项规定 ocamlbuild
使用 ocamlfind
前置。
$ ocamlbuild -use-ocamlfind -classic-display -package ttt.foo main.byte
ocamlfind ocamldep -package ttt.foo -modules main.ml > main.ml.depends
ocamlfind ocamlc -c -package ttt.foo -o main.cmo main.ml
ocamlfind ocamlc -linkpkg -package ttt.foo main.cmo -o main.byte
所以,总而言之,这个想法很好,理论上可行,但最好不要使用它,因为实现还不完整。