Search code examples
ocamloasis

Choose which file to compile to get a module with Oasis


I decided to switch my compilation environment from a Makefile and a configure file to Oasis.

In my configure file I had this command :

EXTERNALLIB=""
if test "$USEOCAMLFIND" = yes; then
  EXTERNALLIB=$(ocamlfind query -i-format External)
fi

and in my 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

which allowed me to compile an actual Externalwrapper module if the library existed in my computer and a fake one if it didn't.

Now, I try to do it in Oasis but I don't know if it's possible and, if yes, how should I do it ?


Solution

  • At the time of writing OASIS 0.4.8 supports neither optional nor conditional linking. Although you can build targets optionally, a recipe for the target should be static. There are rumors, that OASIS author is planning to add this feature in 0.4.9, but currently, he is blocked by an issue in ocamlbuild.

    There are few workarounds, however.

    Preprocessing

    You can just add an extra layer of indirection, and build your _oasis file froms some _oasis.in file. You can even use autoconf for this, e.g.,

    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)
    

    And in the _oasis.in you can use @WRAPPER_MODULE@ variable that will be actualized to externalwrapper_actual.ml or externalwrapper_fake.ml.

    Instead of using autoconf substitutions you can actually build your own configure script that will construct _oasis file. For example, in BAP we are constructing a final _oasis file by gluing it from pieces in our custom configure script.

    Use Object section and extend OCamlBuild

    An alternative solution was proposed by Drup (see the following PR as an example). The idea is to describe each variant as a conditionally built object, and then extend OCamlbuild with a special build rule, that will, depending on a flag, find this object and link it directly.

    Both solutions have their cons and pros, so we are all looking forward for the feature to be added into OASIS.