选择要编译的文件以使用 Oasis 获取模块
Choose which file to compile to get a module with Oasis
我决定将编译环境从 Makefile 和配置文件切换到 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 中这样做,但我不知道是否可行,如果可行,我应该怎么做?
在撰写本文时,OASIS 0.4.8 既不支持可选也不支持条件 linking。尽管您可以选择性地构建目标,但目标的配方应该是静态的。有传闻,OASIS 作者计划在 0.4.9 中添加此功能,但目前,他被 ocamlbuild.an issue 阻止。
但是,解决方法很少。
预处理
您可以只添加一个额外的间接层,并从一些 _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
文件,而不是使用 autoconf 替换。例如,在 BAP 中,我们正在构建一个最终的 _oasis
文件,方法是将它从我们的自定义 configure 脚本中的片段粘合起来。
使用对象部分并扩展 OCamlBuild
Drup 提出了替代解决方案(参见 following PR 作为示例)。这个想法是将每个变体描述为一个有条件的构建对象,然后用一个特殊的构建规则扩展 OCamlbuild,根据一个标志,找到这个对象并直接 link 它。
两种解决方案各有优缺点,因此我们都期待将此功能添加到 OASIS 中。
一种可能性是使用带有您的库名称的标志,并在库存在时要求 opam 启用它们(oasis2opam does that for you). See for example the definition of a lwt flag and its use to conditionally build a library. You can also have setup.ml
enable the flag if the library is present. Finally, you can add cppo rules in myocamlbuild
以启用条件代码编译。
我决定将编译环境从 Makefile 和配置文件切换到 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 中这样做,但我不知道是否可行,如果可行,我应该怎么做?
在撰写本文时,OASIS 0.4.8 既不支持可选也不支持条件 linking。尽管您可以选择性地构建目标,但目标的配方应该是静态的。有传闻,OASIS 作者计划在 0.4.9 中添加此功能,但目前,他被 ocamlbuild.an issue 阻止。
但是,解决方法很少。
预处理
您可以只添加一个额外的间接层,并从一些 _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
文件,而不是使用 autoconf 替换。例如,在 BAP 中,我们正在构建一个最终的 _oasis
文件,方法是将它从我们的自定义 configure 脚本中的片段粘合起来。
使用对象部分并扩展 OCamlBuild
Drup 提出了替代解决方案(参见 following PR 作为示例)。这个想法是将每个变体描述为一个有条件的构建对象,然后用一个特殊的构建规则扩展 OCamlbuild,根据一个标志,找到这个对象并直接 link 它。
两种解决方案各有优缺点,因此我们都期待将此功能添加到 OASIS 中。
一种可能性是使用带有您的库名称的标志,并在库存在时要求 opam 启用它们(oasis2opam does that for you). See for example the definition of a lwt flag and its use to conditionally build a library. You can also have setup.ml
enable the flag if the library is present. Finally, you can add cppo rules in myocamlbuild
以启用条件代码编译。