Conditional library dependencies

In this question I asked how to have a conditional dependency in a package in dune-package. The answer is

(package
  (name foo)
  (depends
    (linenoise (and (>= 1.1.0) (<> :os "windows")))))

That works, but now I need to

a) conditionally link to that library in an executable, and
b) conditionally compile code to use that library (or fallback code if it isn’t used)

Here is the executable:

(executable
 (name sail)
 (package sail)
 (link_flags -linkall)
 (libraries other_stuff linenoise))

And here is some code that uses it:

let mode_clear istate =
  match istate.mode with
  | Normal -> ()
  | Evaluation _ -> if istate.display_options.clear then LNoise.clear_screen () else ()

And if linenoise isn’t being used I want it instead to compile

let mode_clear _istate = ()

How do I achieve both of those?

I think you can do this with Alternative Dependencies.

You have to create two separate ml files, one for when installed and one for when not, and then use select to have dune “copy” whichever of the two is appropriate to something that’ll actually be used.

Something like (but I probably have it wrong in some way, please tweak to your use case):

(select mode_clear.ml from
  (linenoise -> mode_clear.ml.with)
  (-> mode_clear.ml.without))

There is an example of this here : sherlodoc/store/dune at master · art-w/sherlodoc · GitHub

This depends on whether some other opam package is installed, you can probably have some other condition

(it actually depends on whether a library exists, but this library only exists if some opam package is available)