我决定将编译环境从Makefile和configure文件切换到Oasis。
在我的configure
文件中,我有这样的命令:
EXTERNALLIB=""
if test "$USEOCAMLFIND" = yes; then
EXTERNALLIB=$(ocamlfind query -i-format External)
fi
在我的Makefile
:中
externalwrapper.ml: externalwrapper_actual.ml externalwrapper_fake.ml config.status
@rm -f externalwrapper.ml
@if [ -z "$(EXTERNALLIB)" ]; then
cat externalwrapper_fake.ml >> externalwrapper.ml;
else
cat externalwrapper_actual.ml >> externalwrapper.ml;
fi;
chmod -w externalwrapper.ml
如果库存在于我的计算机中,它允许我编译一个实际的Externalwrapper
模块,如果没有,它允许编译一个假的模块。
现在,我试着在绿洲做这件事,但我不知道这是否可能,如果可能,我该怎么做?
在编写OASIS时,0.4.8既不支持可选链接,也不支持条件链接。尽管您可以选择性地构建目标,但目标的配方应该是静态的。有传言称,OASIS作者计划在0.4.9中添加此功能,但目前,他被ocamlbuild中的一个问题阻止了。
然而,几乎没有什么解决办法。
预处理
您可以添加一个额外的间接层,并从某个_oasis.in
文件构建_oasis
文件。你甚至可以使用autoconf
,例如
AC_INIT([Name], [0.1-beta], [your@email])
AC_CONFIG_FILES([_oasis])
EXTERNALLIB=$(ocamlfind query -i-format External)
WRAPPER_MODULE=externalwrapper_fake.ml
if test -z "$(EXTERNALLIB)"; then
WRAPPER_MODULE=externalwrapper_actual.ml
fi
AC_OUTPUT
AC_SUBST(WRAPPER_MODULE)
在_oasis.in
中,您可以使用@WRAPPER_MODULE@
变量,该变量将被实现为externalwrapper_actual.ml
或externalwrapper_fake.ml
。
您实际上可以构建自己的配置脚本来构建_oasis
文件,而不是使用自动配置替换。例如,在BAP中,我们通过将其从自定义配置脚本中的片段粘合来构建最终的_oasis
文件。
使用Object部分并扩展OCamlBuild
Drup提出了另一种解决方案(见以下PR作为示例)。其想法是将每个变体描述为有条件构建的对象,然后用一个特殊的构建规则扩展OCamlbuild,该规则将根据标志找到该对象并直接链接它。
这两种解决方案各有利弊,所以我们都期待着将该功能添加到OASIS中。
一种可能性是使用带有库名称的标志,并要求opam在存在库的情况下启用它们(oasis2opam为您做到这一点)。例如,请参阅lwt标志的定义及其在有条件地构建库中的使用。如果存在库,也可以让setup.ml
启用标志。最后,您可以在myocamlbuild
中添加cppo规则以启用条件代码编译。